summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/elflint.c3
-rw-r--r--src/readelf.c14
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"