From: Alan Modra Date: Tue, 14 Feb 2023 21:21:00 +0000 (+1030) Subject: binutils stabs type list X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=72d225ef9cc7d475db188581da33b056df3191fd;p=binutils-gdb.git binutils stabs type list Fuzzers have found that specifying a large stab type number results in lots of memory being requested, as the list is extended with a 16 element array at a time until we reach the given stab type. It also takes a long time. Of course normal sane stab types use small positive integers, but it's not hard to modify the code to handle type numbers starting anyhere. * stabs.c (struct stab_types): Add base_index. (stab_find_slot): Simplify filenum check. Delete type number check. Don't allocate entire array from 0 to type number, allocate a sparse array. --- diff --git a/binutils/stabs.c b/binutils/stabs.c index 5b0249bdc10..85eebebafdd 100644 --- a/binutils/stabs.c +++ b/binutils/stabs.c @@ -121,6 +121,8 @@ struct stab_types { /* Next set of slots for this file. */ struct stab_types *next; + /* Where the TYPES array starts. */ + unsigned int base_index; /* Types indexed by type number. */ #define STAB_TYPES_SLOTS (16) debug_type types[STAB_TYPES_SLOTS]; @@ -3413,40 +3415,32 @@ stab_emit_pending_vars (void *dhandle, struct stab_handle *info) static debug_type * stab_find_slot (struct stab_handle *info, const int *typenums) { - int filenum; - int tindex; + unsigned int filenum; + unsigned int tindex; + unsigned int base_index; struct stab_types **ps; filenum = typenums[0]; tindex = typenums[1]; - if (filenum < 0 || (unsigned int) filenum >= info->files) + if (filenum >= info->files) { fprintf (stderr, _("Type file number %d out of range\n"), filenum); return NULL; } - if (tindex < 0) - { - fprintf (stderr, _("Type index number %d out of range\n"), tindex); - return NULL; - } ps = info->file_types + filenum; + base_index = tindex / STAB_TYPES_SLOTS * STAB_TYPES_SLOTS; + tindex -= base_index; + while (*ps && (*ps)->base_index < base_index) + ps = &(*ps)->next; - while (tindex >= STAB_TYPES_SLOTS) - { - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - ps = &(*ps)->next; - tindex -= STAB_TYPES_SLOTS; - } - if (*ps == NULL) + if (*ps == NULL || (*ps)->base_index != base_index) { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); + struct stab_types *n = xcalloc (1, sizeof (*n)); + n->next = *ps; + n->base_index = base_index; + *ps = n; } return (*ps)->types + tindex;