Skip to content

Commit 5ea3a54

Browse files
committed
libbootimg: Properly handle the ELF v2 cmdline with section header
* Store the initial 8 bytes of metadata that used to be ignored with an offset in order to rebuild the ELF original structure * Store the additional signature stored after the cmdline inside the section data on Sony ELF v2 bootimages Change-Id: I4324c88431c4d265d7e5c61f1491b6b1bfffb242 Signed-off-by: Adrian DC <radian.dc@gmail.com>
1 parent 7beeaee commit 5ea3a54

2 files changed

Lines changed: 79 additions & 13 deletions

File tree

include/boot_img_hdr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ struct boot_img_elf_info
123123
uint8_t elf_version;
124124
uint8_t elf_out_format;
125125
uint32_t cmdline_size;
126+
uint8_t cmdline_metadata[8];
127+
uint32_t cmdline_metadata_cnt;
128+
uint8_t* cmdline_signature;
129+
uint32_t cmdline_signature_cnt;
126130
};
127131

128132
struct boot_img_elf_prog_hdr

src/libbootimg.c

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ void libbootimg_init_new(struct bootimg *img)
100100
img->hdr.page_size = DEFAULT_PAGE_SIZE;
101101
img->hdr_info = malloc(sizeof(struct boot_img_elf_info));
102102
memset(img->hdr_info, 0, sizeof(struct boot_img_elf_info));
103+
img->hdr_info->cmdline_signature = 0;
103104
img->is_elf = 0;
104105

105106
img->blobs[LIBBOOTIMG_BLOB_KERNEL].size = &img->hdr.kernel_size;
@@ -193,6 +194,10 @@ void libbootimg_destroy(struct bootimg *b)
193194
{
194195
struct bootimg_blob *blob = b->blobs;
195196
struct bootimg_blob * const blobs_end = blob + LIBBOOTIMG_BLOB_CNT;
197+
if (b->hdr_info->cmdline_signature != 0)
198+
{
199+
free(b->hdr_info->cmdline_signature);
200+
}
196201
free(b->hdr_info);
197202
for(; blob != blobs_end; ++blob)
198203
{
@@ -465,42 +470,62 @@ void libbootimg_read_cmdline(struct boot_img_hdr *hdr, struct boot_img_elf_info
465470
{
466471
unsigned char buf[BOOT_ARGS_SIZE];
467472
int cmdline_start_pos = 0;
468-
int cmd_len_max = 0;
473+
uint32_t cmdline_full_size = 0;
469474

470475
if (elf_info->elf_version == VER_ELF_1)
471476
{
472477
cmdline_start_pos = elf_info->prog[ELF_PROG_CMD].offset;
473478
elf_info->cmdline_size = elf_info->prog[ELF_PROG_CMD].size;
474-
cmd_len_max = elf_info->cmdline_size;
475479
}
476480
else if (elf_info->elf_version == VER_ELF_2)
477481
{
478482
cmdline_start_pos = elf_info->sect[ELF_SECT_CMD].offset;
479483
elf_info->cmdline_size = elf_info->sect[ELF_SECT_CMD].size;
480-
cmd_len_max = elf_info->cmdline_size;
481484
}
482-
cmd_len_max = cmd_len_max < BOOT_ARGS_SIZE ? cmd_len_max : BOOT_ARGS_SIZE;
485+
486+
cmdline_full_size = elf_info->cmdline_size;
487+
elf_info->cmdline_signature = 0;
488+
elf_info->cmdline_signature_cnt = 0;
489+
elf_info->cmdline_size = cmdline_full_size < BOOT_ARGS_SIZE ?
490+
cmdline_full_size : BOOT_ARGS_SIZE;
483491

484492
memset(&hdr->cmdline, '\0', BOOT_ARGS_SIZE);
485-
memset(&buf, '\0', BOOT_ARGS_SIZE);
486493
fseek(f, cmdline_start_pos, SEEK_SET);
487-
fread(buf, cmd_len_max, 1, f);
488494

489-
int buf_offset = 0;
495+
int buf_idx;
490496
if (elf_info->elf_version == VER_ELF_2)
491497
{
492-
buf_offset = 8;
498+
elf_info->cmdline_metadata_cnt = 8;
499+
if (fread(elf_info->cmdline_metadata, 8, 1, f) != 1)
500+
{
501+
LOG_DBG("Cmd line metadata read failed.\n");
502+
}
503+
}
504+
else
505+
{
506+
elf_info->cmdline_metadata_cnt = 0;
507+
memset(elf_info->cmdline_metadata,
508+
sizeof(elf_info->cmdline_metadata), 0);
493509
}
494510

495-
int buf_idx = 0;
496-
for (; buf_idx < cmd_len_max; ++buf_idx)
511+
fread(hdr->cmdline, elf_info->cmdline_size, 1, f);
512+
513+
if (cmdline_full_size > elf_info->cmdline_size)
497514
{
498-
hdr->cmdline[buf_idx] = buf[buf_idx + buf_offset];
499-
if (buf[buf_idx + buf_offset] == '\0')
515+
elf_info->cmdline_signature_cnt =
516+
cmdline_full_size - elf_info->cmdline_size;
517+
elf_info->cmdline_signature = malloc(
518+
elf_info->cmdline_signature_cnt * sizeof(uint8_t));
519+
520+
LOG_DBG("Cmd line signature size: %u\n",
521+
elf_info->cmdline_signature_cnt);
522+
if (fread(elf_info->cmdline_signature, elf_info->cmdline_signature_cnt,
523+
1, f) != 1)
500524
{
501-
break;
525+
LOG_DBG("Cmd line signature read failed.\n");
502526
}
503527
}
528+
504529
LOG_DBG("Cmd line: %s\n", hdr->cmdline);
505530
}
506531

@@ -888,6 +913,43 @@ int libbootimg_write_img_fileptr(struct bootimg *b, FILE *f)
888913
// Write the section header if needed by the ELF
889914
if (b->hdr_info->hdr.shnum > 0)
890915
{
916+
// Prepare the cmdline data
917+
LOG_DBG("Writing cmdline data.\n");
918+
LOG_DBG("cmdline: %s\n", b->hdr.cmdline);
919+
LOG_DBG("cmdline size: %u\n", b->hdr_info->cmdline_size);
920+
fseek(f, b->hdr_info->sect[ELF_SECT_CMD].offset, SEEK_SET);
921+
922+
// Write the cmdline metadata
923+
if (b->hdr_info->cmdline_metadata_cnt > 0 &&
924+
fwrite(&b->hdr_info->cmdline_metadata,
925+
b->hdr_info->cmdline_metadata_cnt, 1, f) != 1)
926+
{
927+
LOG_DBG("Failed to write the cmdline metadata.\n");
928+
goto fail_fwrite;
929+
}
930+
931+
// Write the cmdline based on section header
932+
if (fwrite(&b->hdr.cmdline, b->hdr_info->cmdline_size, 1, f) != 1)
933+
{
934+
LOG_DBG("Failed to write the cmdline.\n");
935+
goto fail_fwrite;
936+
}
937+
938+
// Write the cmdline signature based on section header
939+
if (b->hdr_info->cmdline_signature_cnt > 0)
940+
{
941+
LOG_DBG("Writing cmdline signature.\n");
942+
fseek(f, b->hdr_info->sect[ELF_SECT_CMD].offset +
943+
b->hdr_info->cmdline_metadata_cnt + BOOT_ARGS_SIZE, SEEK_SET);
944+
if (fwrite(b->hdr_info->cmdline_signature,
945+
b->hdr_info->cmdline_signature_cnt, 1, f) != 1)
946+
{
947+
LOG_DBG("Failed to write the cmdline signature.\n");
948+
goto fail_fwrite;
949+
}
950+
}
951+
952+
// Write the section header
891953
LOG_DBG("Writing section header.\n");
892954
fseek(f, b->hdr_info->hdr.shoff, SEEK_SET);
893955
if (fwrite(b->hdr_info->sect, b->hdr_info->hdr.shentsize, 1, f) == 1)

0 commit comments

Comments
 (0)