diff options
author | Alan Modra <amodra@gmail.com> | 2023-05-09 17:11:46 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-05-09 17:11:46 +0930 |
commit | 55a75aae9d971d3d0f49884e3954ac4794559542 (patch) | |
tree | 437fd2113eddbf90b85a864f89e4b10962d3e76a | |
parent | 06ba6be629959ebbb4d0dbeedc4c0413cf60e249 (diff) | |
download | binutils-55a75aae9d971d3d0f49884e3954ac4794559542.zip binutils-55a75aae9d971d3d0f49884e3954ac4794559542.tar.gz binutils-55a75aae9d971d3d0f49884e3954ac4794559542.tar.bz2 |
stack overflow in debug_write_type
Another fuzzer attack. This one was a "set" with elements using an
indirect type pointing back at the set. The existing recursion check
only prevented simple recursion.
* debug.c (struct debug_type_s): Add mark.
(debug_write_type): Set mark and check before recursing into
indirect types.
-rw-r--r-- | binutils/debug.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/binutils/debug.c b/binutils/debug.c index 53b4587..5cc77f7 100644 --- a/binutils/debug.c +++ b/binutils/debug.c @@ -105,6 +105,8 @@ struct debug_type_s enum debug_type_kind kind; /* Size of type (0 if not known). */ unsigned int size; + /* Used by debug_write to stop DEBUG_KIND_INDIRECT infinite recursion. */ + unsigned int mark; /* Type which is a pointer to this type. */ debug_type pointer; /* Tagged union with additional information about the type. */ @@ -2422,6 +2424,9 @@ debug_write_type (struct debug_handle *info, if (type == DEBUG_TYPE_NULL) return (*fns->empty_type) (fhandle); + /* Mark the type so that we don't define a type in terms of itself. */ + type->mark = info->mark; + /* If we have a name for this type, just output it. We only output typedef names after they have been defined. We output type tags whenever we are not actually defining them. */ @@ -2485,7 +2490,7 @@ debug_write_type (struct debug_handle *info, return false; case DEBUG_KIND_INDIRECT: /* Prevent infinite recursion. */ - if (*type->u.kindirect->slot == type) + if ((*type->u.kindirect->slot)->mark == info->mark) return (*fns->empty_type) (fhandle); return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot, name); |