Skip to content
58 changes: 53 additions & 5 deletions tools/rimage/src/manifest.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <sys/time.h>

Expand All @@ -26,6 +27,33 @@
#include <rimage/misc_utils.h>
#include <rimage/hash.h>

static bool cse_header_is_valid(const struct image *image, const void *buffer, size_t size)
{
if (image->adsp->man_v2_5 || image->adsp->man_ace_v1_5) {
const struct CsePartitionDirHeader_v2_5 *cse_hdr = buffer;

if (size < sizeof(*cse_hdr))
return false;

return cse_hdr->header_marker == CSE_HEADER_MAKER &&
cse_hdr->nb_entries == MAN_CSE_PARTS &&
cse_hdr->header_length >= sizeof(*cse_hdr);
}

if (image->adsp->man_v1_5 || image->adsp->man_v1_5_sue || image->adsp->man_v1_8) {
const struct CsePartitionDirHeader *cse_hdr = buffer;

if (size < sizeof(*cse_hdr))
return false;

return cse_hdr->header_marker == CSE_HEADER_MAKER &&
cse_hdr->nb_entries == MAN_CSE_PARTS &&
cse_hdr->header_length >= sizeof(*cse_hdr);
}

return false;
}

static int man_open_rom_file(struct image *image)
{
uint32_t size;
Expand Down Expand Up @@ -1644,8 +1672,8 @@ int man_write_fw_ace_v1_5(struct image *image)
int verify_image(struct image *image)
{
FILE *in_file;
int ret;
void *buffer;
int ret = -EINVAL;
void *buffer = NULL;
size_t size, read, i;

/* is verify supported for target ? */
Expand Down Expand Up @@ -1680,7 +1708,7 @@ int verify_image(struct image *image)
}
for (i = 0; i + sizeof(uint32_t) <= size; i += sizeof(uint32_t)) {
/* find CSE header marker "$CPD" */
if (*(uint32_t *)(buffer + i) == CSE_HEADER_MAKER) {
if (cse_header_is_valid(image, buffer + i, size - i)) {
image->fw_image = buffer + i;
/* size of the image from the CSE header to the end of the
* file, used by v1.5 verification and the signed-payload
Expand All @@ -1706,6 +1734,7 @@ int verify_image(struct image *image)
image->verify_file);
ret = -EINVAL;
out:
free(buffer);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5fa4400. buffer is initialised to NULL, so an early get_file_size() failure that jumps to the cleanup no longer calls free() on an uninitialised pointer.

fclose(in_file);
/* propagate verification result so callers (and the exit code) can
* detect a failed/missing verification instead of always seeing success
Expand Down Expand Up @@ -1751,7 +1780,7 @@ int resign_image(struct image *image)

for (i = 0; i + sizeof(uint32_t) <= size; i += sizeof(uint32_t)) {
/* find CSE header marker "$CPD" */
if (*(uint32_t *)(buffer + i) == CSE_HEADER_MAKER) {
if (cse_header_is_valid(image, buffer + i, size - i)) {
image->fw_image = buffer + i;
break;
}
Expand Down Expand Up @@ -1813,7 +1842,26 @@ int resign_image(struct image *image)
goto out;
}

man_write_fw_mod(image);
ret = man_write_fw_mod(image);
if (ret < 0)
goto out;

/* fclose() closes the stream even when it reports an error, so clear the
* handle first to stop the caller's cleanup from closing it a second time.
*/
ret = fclose(image->out_fd);
image->out_fd = NULL;
if (ret) {
ret = file_error("unable to close file after signing", image->out_file);
goto out;
}

/* validate the re-signed output with the same private key */
image->verify_file = image->out_file;
ret = verify_image(image);
image->verify_file = NULL;
if (ret < 0)
unlink(image->out_file);

out:
free(buffer);
Expand Down
7 changes: 6 additions & 1 deletion tools/rimage/src/rimage.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void usage(char *name)
fprintf(stdout, "\t -e build extended manifest\n");
fprintf(stdout, "\t -l build loadable modules image (don't treat the first module as a bootloader)\n");
fprintf(stdout, "\t -y verify signed file\n");
fprintf(stdout, "\t -q resign binary\n");
fprintf(stdout, "\t -q resign binary from infile and validate the output signature\n");
fprintf(stdout, "\t -p set PV bit\n");
fprintf(stdout, "\t -d ignore detached sections\n");
fprintf(stdout, "\t -Q, --quiet suppress informational stdout logs\n");
Expand Down Expand Up @@ -144,6 +144,11 @@ int main(int argc, char *argv[])
return -EINVAL;
}

if (image.in_file && image.verify_file) {
fprintf(stderr, "error: resign and verify modes are mutually exclusive\n");
return -EINVAL;
}

/* firmware version: major.minor.micro */
if (image.fw_ver_string) {
ret = sscanf(image.fw_ver_string, "%hu.%hu.%hu",
Expand Down
Loading
Loading