diff options
author | Alan Modra <amodra@gmail.com> | 2021-12-15 11:48:42 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-12-15 11:51:26 +1030 |
commit | 161e87d12167b1e36193385485c1f6ce92f74f02 (patch) | |
tree | 361204d128f1a80bb5a8ab7d7849b568e97d0807 /binutils | |
parent | d5c94731766bf4f276146fd29c1df8eebc2aaf69 (diff) | |
download | fsf-binutils-gdb-161e87d12167b1e36193385485c1f6ce92f74f02.zip fsf-binutils-gdb-161e87d12167b1e36193385485c1f6ce92f74f02.tar.gz fsf-binutils-gdb-161e87d12167b1e36193385485c1f6ce92f74f02.tar.bz2 |
PR28694, Out-of-bounds write in stab_xcoff_builtin_type
PR 28694
* stabs.c (stab_xcoff_builtin_type): Make typenum unsigned.
Negate typenum earlier, simplifying bounds checking. Correct
off-by-one indexing. Adjust switch cases.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/stabs.c | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/binutils/stabs.c b/binutils/stabs.c index 274bfb0..83ee3ea 100644 --- a/binutils/stabs.c +++ b/binutils/stabs.c @@ -202,7 +202,7 @@ static debug_type stab_find_type (void *, struct stab_handle *, const int *); static bool stab_record_type (void *, struct stab_handle *, const int *, debug_type); static debug_type stab_xcoff_builtin_type - (void *, struct stab_handle *, int); + (void *, struct stab_handle *, unsigned int); static debug_type stab_find_tagged_type (void *, struct stab_handle *, const char *, int, enum debug_type_kind); static debug_type *stab_demangle_argtypes @@ -3496,166 +3496,167 @@ stab_record_type (void *dhandle ATTRIBUTE_UNUSED, struct stab_handle *info, static debug_type stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info, - int typenum) + unsigned int typenum) { debug_type rettype; const char *name; - if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT) + typenum = -typenum - 1; + if (typenum >= XCOFF_TYPE_COUNT) { - fprintf (stderr, _("Unrecognized XCOFF type %d\n"), typenum); + fprintf (stderr, _("Unrecognized XCOFF type %d\n"), -typenum - 1); return DEBUG_TYPE_NULL; } - if (info->xcoff_types[-typenum] != NULL) - return info->xcoff_types[-typenum]; + if (info->xcoff_types[typenum] != NULL) + return info->xcoff_types[typenum]; - switch (-typenum) + switch (typenum) { - case 1: + case 0: /* The size of this and all the other types are fixed, defined by the debugging format. */ name = "int"; rettype = debug_make_int_type (dhandle, 4, false); break; - case 2: + case 1: name = "char"; rettype = debug_make_int_type (dhandle, 1, false); break; - case 3: + case 2: name = "short"; rettype = debug_make_int_type (dhandle, 2, false); break; - case 4: + case 3: name = "long"; rettype = debug_make_int_type (dhandle, 4, false); break; - case 5: + case 4: name = "unsigned char"; rettype = debug_make_int_type (dhandle, 1, true); break; - case 6: + case 5: name = "signed char"; rettype = debug_make_int_type (dhandle, 1, false); break; - case 7: + case 6: name = "unsigned short"; rettype = debug_make_int_type (dhandle, 2, true); break; - case 8: + case 7: name = "unsigned int"; rettype = debug_make_int_type (dhandle, 4, true); break; - case 9: + case 8: name = "unsigned"; rettype = debug_make_int_type (dhandle, 4, true); break; - case 10: + case 9: name = "unsigned long"; rettype = debug_make_int_type (dhandle, 4, true); break; - case 11: + case 10: name = "void"; rettype = debug_make_void_type (dhandle); break; - case 12: + case 11: /* IEEE single precision (32 bit). */ name = "float"; rettype = debug_make_float_type (dhandle, 4); break; - case 13: + case 12: /* IEEE double precision (64 bit). */ name = "double"; rettype = debug_make_float_type (dhandle, 8); break; - case 14: + case 13: /* This is an IEEE double on the RS/6000, and different machines with different sizes for "long double" should use different negative type numbers. See stabs.texinfo. */ name = "long double"; rettype = debug_make_float_type (dhandle, 8); break; - case 15: + case 14: name = "integer"; rettype = debug_make_int_type (dhandle, 4, false); break; - case 16: + case 15: name = "boolean"; rettype = debug_make_bool_type (dhandle, 4); break; - case 17: + case 16: name = "short real"; rettype = debug_make_float_type (dhandle, 4); break; - case 18: + case 17: name = "real"; rettype = debug_make_float_type (dhandle, 8); break; - case 19: + case 18: /* FIXME */ name = "stringptr"; rettype = NULL; break; - case 20: + case 19: /* FIXME */ name = "character"; rettype = debug_make_int_type (dhandle, 1, true); break; - case 21: + case 20: name = "logical*1"; rettype = debug_make_bool_type (dhandle, 1); break; - case 22: + case 21: name = "logical*2"; rettype = debug_make_bool_type (dhandle, 2); break; - case 23: + case 22: name = "logical*4"; rettype = debug_make_bool_type (dhandle, 4); break; - case 24: + case 23: name = "logical"; rettype = debug_make_bool_type (dhandle, 4); break; - case 25: + case 24: /* Complex type consisting of two IEEE single precision values. */ name = "complex"; rettype = debug_make_complex_type (dhandle, 8); break; - case 26: + case 25: /* Complex type consisting of two IEEE double precision values. */ name = "double complex"; rettype = debug_make_complex_type (dhandle, 16); break; - case 27: + case 26: name = "integer*1"; rettype = debug_make_int_type (dhandle, 1, false); break; - case 28: + case 27: name = "integer*2"; rettype = debug_make_int_type (dhandle, 2, false); break; - case 29: + case 28: name = "integer*4"; rettype = debug_make_int_type (dhandle, 4, false); break; - case 30: + case 29: /* FIXME */ name = "wchar"; rettype = debug_make_int_type (dhandle, 2, false); break; - case 31: + case 30: name = "long long"; rettype = debug_make_int_type (dhandle, 8, false); break; - case 32: + case 31: name = "unsigned long long"; rettype = debug_make_int_type (dhandle, 8, true); break; - case 33: + case 32: name = "logical*8"; rettype = debug_make_bool_type (dhandle, 8); break; - case 34: + case 33: name = "integer*8"; rettype = debug_make_int_type (dhandle, 8, false); break; @@ -3664,9 +3665,7 @@ stab_xcoff_builtin_type (void *dhandle, struct stab_handle *info, } rettype = debug_name_type (dhandle, name, rettype); - - info->xcoff_types[-typenum] = rettype; - + info->xcoff_types[typenum] = rettype; return rettype; } |