diff --git a/bundled/libdwarf/dwarf_elf_load_headers.c b/bundled/libdwarf/dwarf_elf_load_headers.c index a193305..6c1cdfe 100644 --- a/bundled/libdwarf/dwarf_elf_load_headers.c +++ b/bundled/libdwarf/dwarf_elf_load_headers.c @@ -178,116 +178,6 @@ is_empty_section(Dwarf_Unsigned type) return FALSE; } -#if 0 -int -dwarf_construct_elf_access_path(const char *path, - dwarf_elf_object_access_internals_t **mp,int *errcode) -{ - int fd = -1; - int res = 0; - dwarf_elf_object_access_internals_t *mymp = 0; - - fd = open(path, O_RDONLY|O_BINARY|O_CLOEXEC); - if (fd < 0) { - *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; - return DW_DLV_ERROR; - } - res = dwarf_construct_elf_access(fd, - path,&mymp,errcode); - if (res != DW_DLV_OK) { - close(fd); - return res; - } - mymp->f_destruct_close_fd = TRUE; - *mp = mymp; - return res; -} - -/* Here path is not essential. Pass in with "" if unknown. */ -int -dwarf_construct_elf_access(int fd, - const char *path, - dwarf_elf_object_access_internals_t **mp,int *errcode) -{ - unsigned ftype = 0; - unsigned endian = 0; - unsigned offsetsize = 0; - Dwarf_Unsigned filesize = 0; - dwarf_elf_object_access_internals_t *mfp = 0; - int res = 0; - - res = dwarf_object_detector_fd(fd, - &ftype,&endian,&offsetsize, &filesize, errcode); - if (res != DW_DLV_OK) { - return res; - } - - mfp = calloc(1,sizeof(dwarf_elf_object_access_internals_t)); - if (!mfp) { - *errcode = DW_DLE_ALLOC_FAIL; - return DW_DLV_ERROR; - } - /* For non-libelf Elf, call it 'F'. Libelf Elf uses 'E' */ - mfp->f_ident[0] = 'F'; - mfp->f_ident[1] = 1; - mfp->f_fd = fd; - mfp->f_destruct_close_fd = FALSE; - mfp->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); - mfp->f_filesize = filesize; - mfp->f_offsetsize = offsetsize; - mfp->f_pointersize = offsetsize; - mfp->f_endian = endian; - mfp->f_ftype = ftype; - mfp->f_path = strdup(path); - - *mp = mfp; - return DW_DLV_OK; -} - -/* Caller must zero the passed in pointer - after this returns to remind - the caller to avoid use of the pointer. */ -int -dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t* ep, - int *errcode) -{ - struct generic_shdr *shp = 0; - Dwarf_Unsigned shcount = 0; - Dwarf_Unsigned i = 0; - - (void)errcode; - free(ep->f_ehdr); - shp = ep->f_shdr; - shcount = ep->f_loc_shdr.g_count; - for (i = 0; i < shcount; ++i,++shp) { - free(shp->gh_rels); - shp->gh_rels = 0; - free(shp->gh_content); - shp->gh_content = 0; - free(shp->gh_sht_group_array); - shp->gh_sht_group_array = 0; - shp->gh_sht_group_array_count = 0; - } - free(ep->f_shdr); - free(ep->f_phdr); - free(ep->f_elf_shstrings_data); - free(ep->f_dynamic); - free(ep->f_symtab_sect_strings); - free(ep->f_dynsym_sect_strings); - free(ep->f_symtab); - free(ep->f_dynsym); - - /* if TRUE close f_fd on destruct.*/ - if (ep->f_destruct_close_fd) { - close(ep->f_fd); - } - ep->f_ident[0] = 'X'; - free(ep->f_path); - free(ep); - return DW_DLV_OK; -} -#endif /*0*/ - static int generic_ehdr_from_32(dwarf_elf_object_access_internals_t *ep, struct generic_ehdr *ehdr, dw_elf32_ehdr *e, @@ -954,7 +844,7 @@ _dwarf_generic_elf_load_symbols( } return res; } -#if 0 +#if 0 /* not needed */ int dwarf_load_elf_dynsym_symbols( dwarf_elf_object_access_internals_t *ep, int*errcode) @@ -1189,7 +1079,7 @@ generic_rel_from_rel64( return DW_DLV_OK; } -#if 0 +#if 0 /* not needed */ int dwarf_load_elf_dynstr( dwarf_elf_object_access_internals_t *ep, int *errcode) @@ -1801,6 +1691,7 @@ _dwarf_load_elf_relx( gshdr->gh_relcount = count_read; return DW_DLV_OK; } + static int validate_section_name_string(Dwarf_Unsigned section_length, Dwarf_Unsigned string_loc_index, @@ -1925,51 +1816,6 @@ elf_load_elf_header64( return res; } -static int -validate_struct_sizes(int*errcode) -{ - - (void)errcode; -#if 0 - /* This is a sanity check when we have an elf.h - to check against. - As of 0.7.1 we skip this entirely (here). */ - if (sizeof(Elf32_Ehdr) != sizeof(dw_elf32_ehdr)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf64_Ehdr) != sizeof(dw_elf64_ehdr)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf32_Shdr) != sizeof(dw_elf32_shdr)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf64_Shdr) != sizeof(dw_elf64_shdr)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf32_Rel) != sizeof(dw_elf32_rel)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf64_Rel) != sizeof(dw_elf64_rel)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf32_Rela) != sizeof(dw_elf32_rela)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } - if (sizeof(Elf64_Rela) != sizeof(dw_elf64_rela)) { - *errcode = DW_DLE_BAD_TYPE_SIZE; - return DW_DLV_ERROR; - } -#endif /* 0 */ - return DW_DLV_OK; -} - int _dwarf_load_elf_header( dwarf_elf_object_access_internals_t *ep,int*errcode) @@ -1977,11 +1823,6 @@ _dwarf_load_elf_header( unsigned offsetsize = ep->f_offsetsize; int res = 0; - res = validate_struct_sizes(errcode); - if (res != DW_DLV_OK) { - return res; - } - if (offsetsize == 32) { res = elf_load_elf_header32(ep,errcode); } else if (offsetsize == 64) { @@ -2342,14 +2183,6 @@ _dwarf_elf_find_sym_sections( ep->f_loc_dynamic.g_offset = psh->gh_offset; } } - -#if 0 - res = validate_links(ep,ep->f_dynsym_sect_index, - ep->f_dynsym_sect_strings_sect_index,errcode); - if (res!= DW_DLV_OK) { - return res; - } -#endif /*0*/ res = validate_links(ep,ep->f_symtab_sect_index, ep->f_symtab_sect_strings_sect_index,errcode); if (res!= DW_DLV_OK) { diff --git a/bundled/libdwarf/dwarf_errmsg_list.h b/bundled/libdwarf/dwarf_errmsg_list.h index 41155ce..4a7a8a6 100644 --- a/bundled/libdwarf/dwarf_errmsg_list.h +++ b/bundled/libdwarf/dwarf_errmsg_list.h @@ -683,7 +683,9 @@ static const char _dwarf_errmsgs[DW_DLE_LAST+1][DW_MAX_MSG_LEN] = { "not valid. Corrupt data."}, {"DW_DLE_ARITHMETIC_OVERFLOW(501) Arithmetic overflow. " " Corrupt Dwarf." }, -{" DW_DLE_UNIVERSAL_BINARY_ERROR(502) Error reading Mach-O " - "uninversal binary head. Corrupt Mach-O object." } +{"DW_DLE_UNIVERSAL_BINARY_ERROR(502) Error reading Mach-O " + "uninversal binary head. Corrupt Mach-O object." }, +{"DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR(503) Offset/size from " + "a Mach-O universal binary has an impossible value"} }; #endif /* DWARF_ERRMSG_LIST_H */ diff --git a/bundled/libdwarf/dwarf_generic_init.c b/bundled/libdwarf/dwarf_generic_init.c index 6b905c1..1a24aef 100644 --- a/bundled/libdwarf/dwarf_generic_init.c +++ b/bundled/libdwarf/dwarf_generic_init.c @@ -124,7 +124,7 @@ set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error) return res; } -/* New in December 2018. */ +/* New in September 2023. */ int dwarf_init_path_a(const char *path, char * true_path_out_buffer, unsigned true_path_bufferlen, diff --git a/bundled/libdwarf/dwarf_machoread.c b/bundled/libdwarf/dwarf_machoread.c index ded021e..4633500 100644 --- a/bundled/libdwarf/dwarf_machoread.c +++ b/bundled/libdwarf/dwarf_machoread.c @@ -1005,7 +1005,6 @@ _dwarf_macho_object_access_internals_init( &offsetsizei,&fileoffseti,&filesizei,errcode); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { - *errcode = DW_DLE_UNIVERSAL_BINARY_ERROR; } return res; } @@ -1141,7 +1140,8 @@ static int fill_in_uni_arch_32( struct fat_arch * fa, struct Dwarf_Universal_Head_s *duhd, - void (*word_swap) (void *, const void *, unsigned long)) + void (*word_swap) (void *, const void *, unsigned long), + int *errcode) { Dwarf_Unsigned i = 0; struct Dwarf_Universal_Arch_s * dua = 0; @@ -1151,8 +1151,25 @@ fill_in_uni_arch_32( ASNAR(word_swap,dua->au_cputype,fa->cputype); ASNAR(word_swap,dua->au_cpusubtype,fa->cpusubtype); ASNAR(word_swap,dua->au_offset,fa->offset); + if (dua->au_offset >= duhd->au_filesize) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } ASNAR(word_swap,dua->au_size,fa->size); + if (dua->au_size >= duhd->au_filesize) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } + if ((dua->au_size+dua->au_offset) > duhd->au_filesize) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } + ASNAR(word_swap,dua->au_align,fa->align); + if (dua->au_align >= 32) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } dua->au_reserved = 0; } return DW_DLV_OK; @@ -1162,7 +1179,8 @@ static int fill_in_uni_arch_64( struct fat_arch_64 * fa, struct Dwarf_Universal_Head_s *duhd, - void (*word_swap) (void *, const void *, unsigned long)) + void (*word_swap) (void *, const void *, unsigned long), + int *errcode) { Dwarf_Unsigned i = 0; struct Dwarf_Universal_Arch_s * dua = 0; @@ -1172,9 +1190,24 @@ fill_in_uni_arch_64( ASNAR(word_swap,dua->au_cputype,fa->cputype); ASNAR(word_swap,dua->au_cpusubtype,fa->cpusubtype); ASNAR(word_swap,dua->au_offset,fa->offset); + if (dua->au_offset >= duhd->au_filesize) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } ASNAR(word_swap,dua->au_size,fa->size); + if (dua->au_size >= duhd->au_filesize) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } + if ((dua->au_size+dua->au_offset) > duhd->au_filesize) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } ASNAR(word_swap,dua->au_align,fa->align); - ASNAR(word_swap,dua->au_align,fa->align); + if (dua->au_align >= 32) { + *errcode = DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR; + return DW_DLV_ERROR; + } ASNAR(word_swap,dua->au_reserved,fa->reserved); } return DW_DLV_OK; @@ -1201,6 +1234,11 @@ _dwarf_object_detector_universal_head_fd( duhd = duhzero; fh = fhzero; /* A universal head is always at offset zero. */ + duhd.au_filesize = dw_filesize; + if (sizeof(fh) >= dw_filesize) { + *errcode = DW_DLE_UNIVERSAL_BINARY_ERROR; + return DW_DLV_ERROR; + } res = RRMOA(fd,&fh,0,sizeof(fh), dw_filesize,errcode); if (res != DW_DLV_OK) { return res; @@ -1235,7 +1273,6 @@ _dwarf_object_detector_universal_head_fd( word_swap = _dwarf_memcpy_swap_bytes; } #endif /* LITTLE- BIG-ENDIAN */ - ASNAR(word_swap,duhd.au_count,fh.nfat_arch); /* The limit is a first-cut safe heuristic. */ if (duhd.au_count >= (dw_filesize/2) ) { @@ -1257,9 +1294,9 @@ _dwarf_object_detector_universal_head_fd( free(duhd.au_arches); duhd.au_arches = 0; free(fa); - return res; + return DW_DLV_ERROR; } - if (duhd.au_count*sizeof(*fa) >= dw_filesize) { + if (sizeof(fh)+duhd.au_count*sizeof(*fa) >= dw_filesize) { free(duhd.au_arches); duhd.au_arches = 0; free(fa); @@ -1275,26 +1312,26 @@ _dwarf_object_detector_universal_head_fd( free(fa); return res; } - res = fill_in_uni_arch_32(fa,&duhd,word_swap); + res = fill_in_uni_arch_32(fa,&duhd,word_swap, + errcode); + free(fa); + fa = 0; if (res != DW_DLV_OK) { free(duhd.au_arches); duhd.au_arches = 0; - free(fa); return res; } - free(fa); - fa = 0; } else { /* 64 */ struct fat_arch_64 * fa = 0; fa = (struct fat_arch_64 *)calloc(duhd.au_count, - sizeof(struct fat_arch)); + sizeof(struct fat_arch_64)); if (!fa) { *errcode = DW_DLE_ALLOC_FAIL; free(duhd.au_arches); duhd.au_arches = 0; - return res; + return DW_DLV_ERROR; } - if (duhd.au_count*sizeof(*fa) >= dw_filesize) { + if (sizeof(fh)+duhd.au_count*sizeof(*fa) >= dw_filesize) { free(duhd.au_arches); duhd.au_arches = 0; free(fa); @@ -1310,14 +1347,15 @@ _dwarf_object_detector_universal_head_fd( free(fa); return res; } - res = fill_in_uni_arch_64(fa,&duhd,word_swap); + res = fill_in_uni_arch_64(fa,&duhd,word_swap, + errcode); + free(fa); + fa = 0; if (res != DW_DLV_OK) { free(duhd.au_arches); duhd.au_arches = 0; return res; } - free(fa); - fa = 0; } duhdp = malloc(sizeof(*duhdp)); @@ -1331,7 +1369,7 @@ _dwarf_object_detector_universal_head_fd( *dw_contentcount = duhd.au_count; duhdp->au_arches = duhd.au_arches; *dw_head = duhdp; - return res; + return DW_DLV_OK; } #if 0 diff --git a/bundled/libdwarf/dwarf_machoread.h b/bundled/libdwarf/dwarf_machoread.h index d556cbb..6d9627f 100644 --- a/bundled/libdwarf/dwarf_machoread.h +++ b/bundled/libdwarf/dwarf_machoread.h @@ -37,6 +37,7 @@ struct Dwarf_Universal_Arch_s; struct Dwarf_Universal_Head_s { Dwarf_Unsigned au_magic; Dwarf_Unsigned au_count; + Dwarf_Unsigned au_filesize; /* physical file size */ struct Dwarf_Universal_Arch_s * au_arches; }; diff --git a/bundled/libdwarf/dwarf_names.c b/bundled/libdwarf/dwarf_names.c index 59400fe..0761867 100644 --- a/bundled/libdwarf/dwarf_names.c +++ b/bundled/libdwarf/dwarf_names.c @@ -1,5 +1,5 @@ /* Generated routines, do not edit. */ -/* Generated for source version 0.8.1 */ +/* Generated for source version 0.9.0 */ /* BEGIN FILE */ diff --git a/bundled/libdwarf/libdwarf.h b/bundled/libdwarf/libdwarf.h index bc0ef7f..9a0783e 100644 --- a/bundled/libdwarf/libdwarf.h +++ b/bundled/libdwarf/libdwarf.h @@ -99,10 +99,10 @@ extern "C" { */ /* Semantic Version identity for this libdwarf.h */ -#define DW_LIBDWARF_VERSION "0.8.1" +#define DW_LIBDWARF_VERSION "0.9.0" #define DW_LIBDWARF_VERSION_MAJOR 0 -#define DW_LIBDWARF_VERSION_MINOR 8 -#define DW_LIBDWARF_VERSION_MICRO 1 +#define DW_LIBDWARF_VERSION_MINOR 9 +#define DW_LIBDWARF_VERSION_MICRO 0 #define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_basic 1 @@ -1387,9 +1387,10 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; #define DW_DLE_LINE_COUNT_WRONG 500 #define DW_DLE_ARITHMETIC_OVERFLOW 501 #define DW_DLE_UNIVERSAL_BINARY_ERROR 502 +#define DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR 503 /*! @note DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ -#define DW_DLE_LAST 502 +#define DW_DLE_LAST 503 #define DW_DLE_LO_USER 0x10000 /*! @} */ @@ -1407,7 +1408,7 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; On a Mach-O universal binary this function can only return information about the first (zero index) - object in the universal binary. + object in the universal binary. @param dw_path Pass in the path to the object file to open. @@ -1455,7 +1456,6 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; @see exampleinit */ - DW_API int dwarf_init_path(const char * dw_path, char * dw_true_path_out_buffer, unsigned int dw_true_path_bufferlen, @@ -1470,7 +1470,7 @@ DW_API int dwarf_init_path(const char * dw_path, This identical to dwarf_init_path() except that it adds a new argument, dw_universalnumber, with which you can specify which object in - a Mach-O universal binary you wish to open. + a Mach-O universal binary you wish to open. It is always safe and appropriate to pass zero as the dw_universalnumber. @@ -8909,7 +8909,7 @@ DW_API Dwarf_Small dwarf_set_default_address_size( /*! @brief Retrieve universal binary index For Mach-O universal binaries this returns - relevant information. + relevant information. For non-universal binaries (Mach-O, Elf, or PE) the values are not meaningful, so @@ -8936,7 +8936,6 @@ DW_API int dwarf_get_universalbinary_count( Dwarf_Unsigned *dw_current_index, Dwarf_Unsigned *dw_available_count); - /*! @} */ diff --git a/bundled/pull-libdwarf.sh b/bundled/pull-libdwarf.sh index 559183b..b71098f 100644 --- a/bundled/pull-libdwarf.sh +++ b/bundled/pull-libdwarf.sh @@ -3,7 +3,7 @@ echo "Removing .c and .h files" rm -rfv libdwarf/*.c libdwarf/*.h libdwarf/cmake/config.h.cmake echo "Fetching current state" -git clone https://github.com/davea42/libdwarf-code.git +git clone https://github.com/davea42/libdwarf-code.git --depth=1 echo "Copying files" mv -v libdwarf-code/src/lib/libdwarf/*.c libdwarf mv -v libdwarf-code/src/lib/libdwarf/*.h libdwarf