From f4f373d65de6d665a3d96222ae1c3ad7b84ca4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sat, 17 Dec 2022 19:33:13 +0100 Subject: [PATCH 1/4] Readout elf endianess and print error on mismatch --- include/patchelfcrc/elfpatch.h | 2 +- src/elfpatch.c | 28 +++++++++++++++++++++++++--- src/main.c | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/patchelfcrc/elfpatch.h b/include/patchelfcrc/elfpatch.h index c8646db..c16faac 100644 --- a/include/patchelfcrc/elfpatch.h +++ b/include/patchelfcrc/elfpatch.h @@ -41,7 +41,7 @@ enum crc_format { FORMAT_STRUCT, }; -elfpatch_handle_t *elf_patch_open(const char *path, bool readonly); +elfpatch_handle_t *elf_patch_open(const char *path, bool readonly, bool expect_little_endian); /** * @brief Check if a section is present in file diff --git a/src/elfpatch.c b/src/elfpatch.c index b2cb876..e1f7ef1 100644 --- a/src/elfpatch.c +++ b/src/elfpatch.c @@ -293,9 +293,10 @@ static int elf_patch_update_info(elfpatch_handle_t *ep) return 0; } -elfpatch_handle_t *elf_patch_open(const char *path, bool readonly) +elfpatch_handle_t *elf_patch_open(const char *path, bool readonly, bool expect_little_endian) { struct elfpatch *ep; + const char *ident; /* This is important to guarantee structure packing behavior */ CRC_OUT_CHECK_STRUCT_SIZES; @@ -320,7 +321,7 @@ elfpatch_handle_t *elf_patch_open(const char *path, bool readonly) goto close_fd; } - /* Prewvent Libelf from relayouting the sections, which would brick the load segments */ + /* Prevent Libelf from relayouting the sections, which would brick the load segments */ elf_flagelf(ep->elf, ELF_C_SET, ELF_F_LAYOUT); if (elf_patch_update_info(ep)) { @@ -328,6 +329,27 @@ elfpatch_handle_t *elf_patch_open(const char *path, bool readonly) goto close_elf; } + ident = elf_getident(ep->elf, NULL); + if (ident) { + switch (ident[5]) { + case 1: + print_debug("ELF Endianess: little\n"); + if (!expect_little_endian) { + print_err("Big endian format expected. File is little endian. Double check settings!\n"); + } + break; + case 2: + print_debug("ELF Endianess: big\n"); + if (expect_little_endian) { + print_err("Little endian format expected. File is big endian. Double check settings!\n"); + } + break; + default: + print_err("Cannot determine endianess of ELF file. EI_DATA is: %d\n", ident[5]); + break; + } + } + return (elfpatch_handle_t *)ep; close_elf: if (ep->elf) { @@ -634,7 +656,7 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section, } /* Flag section data as invalid to trigger rewrite. - * This is needed to to the forced memory layout + * This is needed due to the forced memory layout */ elf_flagdata(output_sec_data, ELF_C_SET, ELF_F_DIRTY); ret = 0; diff --git a/src/main.c b/src/main.c index a81fb34..97c2047 100644 --- a/src/main.c +++ b/src/main.c @@ -398,7 +398,7 @@ int main(int argc, char **argv) elf_version(EV_CURRENT); /* Open the ELF file */ - ep = elf_patch_open(cmd_opts.elf_path, cmd_opts.dry_run); + ep = elf_patch_open(cmd_opts.elf_path, cmd_opts.dry_run, cmd_opts.little_endian); if (!ep) { ret = -2; goto free_cmds; From 5b86194734d4021158312898e9e6e403cbbb7480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Wed, 4 Jan 2023 14:53:25 +0100 Subject: [PATCH 2/4] Remove reading of program headers. It is not necessary. --- src/elfpatch.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/elfpatch.c b/src/elfpatch.c index e1f7ef1..390284f 100644 --- a/src/elfpatch.c +++ b/src/elfpatch.c @@ -232,9 +232,6 @@ static int elf_patch_update_info(elfpatch_handle_t *ep) { Elf_Kind ek; const char *type_string = "unrecognized"; - size_t header_count = 0ull; - GElf_Phdr phdr; - size_t i; ret_val_if_ep_err(ep, -1001); @@ -276,20 +273,6 @@ static int elf_patch_update_info(elfpatch_handle_t *ep) return -1; } - /* Get program headers */ - if ( elf_getphdrnum(ep->elf, &header_count) != 0) { - print_err("Error reading count of program headers: %s\n", elf_errmsg(-1)); - return -1; - } - - for (i = 0ull; i < header_count; i++) { - if (gelf_getphdr(ep->elf, (int)i, &phdr) != &phdr) { - print_err("Error reading program header (%zu): %s\n", i, elf_errmsg(-1)); - return -1; - } - print_debug("Read program header %zu\n", i); - } - return 0; } From e09a07b3d32d171849d8c3a16b8d61ff3d63a01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Wed, 4 Jan 2023 15:04:06 +0100 Subject: [PATCH 3/4] Fix segmentation fault if a NOBITS section is specified as a source section --- src/elfpatch.c | 10 +++++++++- src/main.c | 7 +++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/elfpatch.c b/src/elfpatch.c index 390284f..7e9c3a0 100644 --- a/src/elfpatch.c +++ b/src/elfpatch.c @@ -423,8 +423,16 @@ int elf_patch_compute_crc_over_section(elfpatch_handle_t *ep, const char *sectio } print_debug("Section data length: %lu\n", data->d_size); - if (!data->d_size) + if (!data->d_size) { print_err("Section %s contains no data.\n", section); + return -2; + } + + /* NOBIT sections have a length but no data in the file. Abort in this case */ + if (!data->d_buf) { + print_err("Section %s does not contain loadable data.\n", section); + return -2; + } /* If big endian or granularity is byte, simply compute CRC. No reordering is necessary */ if (!little_endian || granularity == GRANULARITY_BYTE) { diff --git a/src/main.c b/src/main.c index 97c2047..bc14947 100644 --- a/src/main.c +++ b/src/main.c @@ -407,12 +407,14 @@ int main(int argc, char **argv) /* Check if all sections are present */ if (check_all_sections_present(ep, cmd_opts.section_list)) { ret = -2; - goto free_cmds; + goto ret_close_elf; } /* Compute CRCs over sections */ crcs = (uint32_t *)malloc(sl_list_length(cmd_opts.section_list) * sizeof(uint32_t)); - compute_crcs(ep, cmd_opts.section_list, &cmd_opts, crcs); + if (compute_crcs(ep, cmd_opts.section_list, &cmd_opts, crcs)) { + goto ret_close_elf; + } if (reporting_get_verbosity()) { print_crcs(cmd_opts.section_list, crcs); @@ -427,6 +429,7 @@ int main(int argc, char **argv) } } +ret_close_elf: elf_patch_close_and_free(ep); free_cmds: From 2fca25d4c0e4d7e8f7d26621757f991d1163f342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Wed, 4 Jan 2023 15:07:01 +0100 Subject: [PATCH 4/4] Fix segmentation fault if a NOBITS section is specified for output --- src/elfpatch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/elfpatch.c b/src/elfpatch.c index 7e9c3a0..978f8e6 100644 --- a/src/elfpatch.c +++ b/src/elfpatch.c @@ -534,6 +534,11 @@ int elf_patch_write_crcs_to_section(elfpatch_handle_t *ep, const char *section, /* Get data object of section */ output_sec_data = elf_getdata(output_section->scn, NULL); sec_bytes = (uint8_t *)output_sec_data->d_buf; + if (!sec_bytes) { + print_err("Output section '%s' does not contain loadable data. It has to be allocated in the ELF file\n", + section); + goto ret_err; + } /* Check the start and end magics */ if (check_start_magic) {