diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 12 | ||||
-rw-r--r-- | src/elflint.c | 3 | ||||
-rw-r--r-- | src/readelf.c | 14 |
3 files changed, 29 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 915494f2..699d98ee 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2023-02-12 Mark Wielaard <mark@klomp.org> + + * readelf.c (print_attributes): Add comment about check. + (read_encoded): Check readp >= endp before reading + DW_EH_PE_uleb128 and DW_EH_PE_sleb128. + * elflint.c (check_attributes): Check r >= q before reading + uleb128. + (print_debug_frame_section): Check augmentation length can be read + as uleb128. + (print_debug_exception_table): Likewise for ttype_base_offset, + call_site_table_len and action. + 2023-01-22 Mark Wielaard <mark@klomp.org> * addr2line.c (options): Separate --demangle and -C. diff --git a/src/elflint.c b/src/elflint.c index b4eac32f..dd42dcb4 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -3569,9 +3569,12 @@ section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"), const unsigned char *r = chunk; if (tag == 32 || (tag & 1) == 0) { + if (r >= q) + goto invalid_uleb; get_uleb128 (value, r, q); if (r > q) { + invalid_uleb: ERROR (_("\ section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"), idx, section_name (ebl, idx), buffer_pos (data, chunk)); diff --git a/src/readelf.c b/src/readelf.c index 5b3319c2..0f13874f 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3802,6 +3802,7 @@ print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr) if (tag == 32 || (tag & 1) == 0 || (! gnu_vendor && (tag > 5 && tag < 32))) { + // Note r >= q check above. get_uleb128 (value, r, q); if (r > q) break; @@ -6368,9 +6369,13 @@ read_encoded (unsigned int encoding, const unsigned char *readp, switch (encoding & 0xf) { case DW_EH_PE_uleb128: + if (readp >= endp) + goto invalid; get_uleb128 (*res, readp, endp); break; case DW_EH_PE_sleb128: + if (readp >= endp) + goto invalid; get_sleb128 (*res, readp, endp); break; case DW_EH_PE_udata2: @@ -6983,6 +6988,9 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, if (augmentation[0] == 'z') { + if (cieend - readp < 1) + goto invalid_data; + unsigned int augmentationlen; get_uleb128 (augmentationlen, readp, cieend); @@ -11010,6 +11018,8 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), if (ttype_encoding != DW_EH_PE_omit) { unsigned int ttype_base_offset; + if (readp >= dataend) + goto invalid_data; get_uleb128 (ttype_base_offset, readp, dataend); printf (" TType base offset: %#x\n", ttype_base_offset); if ((size_t) (dataend - readp) > ttype_base_offset) @@ -11022,6 +11032,8 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), printf (_(" Call site encoding: %#x "), call_site_encoding); print_encoding_base ("", call_site_encoding); unsigned int call_site_table_len; + if (readp >= dataend) + goto invalid_data; get_uleb128 (call_site_table_len, readp, dataend); const unsigned char *const action_table = readp + call_site_table_len; @@ -11044,6 +11056,8 @@ print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)), readp = read_encoded (call_site_encoding, readp, dataend, &landing_pad, dbg); unsigned int action; + if (readp >= dataend) + goto invalid_data; get_uleb128 (action, readp, dataend); max_action = MAX (action, max_action); printf (_(" [%4u] Call site start: %#" PRIx64 "\n" |