diff options
author | Alan Modra <amodra@gmail.com> | 2023-07-26 09:54:03 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-07-26 10:23:27 +0930 |
commit | 477c9f2ba26ccd77016f2c97941fc8b35e332e35 (patch) | |
tree | 7101fd32ce2079ad0dc7006ddf9d54251af2b320 /gprof/vax.c | |
parent | eb14a8b4bfb767beebfb54d7911da4132b5c0f94 (diff) | |
download | gdb-477c9f2ba26ccd77016f2c97941fc8b35e332e35.zip gdb-477c9f2ba26ccd77016f2c97941fc8b35e332e35.tar.gz gdb-477c9f2ba26ccd77016f2c97941fc8b35e332e35.tar.bz2 |
PR30657, gprof heap buffer overflow
PR 30657
* cg_arcs.c (cg_assemble): Sanity check find_call addresses.
* i386.c (i386_find_call): Don't access past end of core_text_space.
* aarch64.c (aarch64_find_call): Round up lowpc, round down highpc.
* alpha.c (alpha_find_call): Likewise.
* mips.c (mips_find_call): Likewise.
* sparc.c (sparc_find_call): Likewise.
* vax.c (vax_find_call): Sanity check core_text_space accesses.
Diffstat (limited to 'gprof/vax.c')
-rw-r--r-- | gprof/vax.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/gprof/vax.c b/gprof/vax.c index 9294235..fafe2b1 100644 --- a/gprof/vax.c +++ b/gprof/vax.c @@ -252,6 +252,8 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) (unsigned long) p_highpc)); for (pc = p_lowpc; pc < p_highpc; pc += length) { + unsigned char *operand; + length = 1; instructp = ((unsigned char *) core_text_space + pc - core_text_sect->vma); @@ -263,7 +265,10 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) */ DBG (CALLDEBUG, printf ("[findcall]\t0x%lx:calls", (unsigned long) pc)); - firstmode = vax_operandmode (instructp + length); + if (pc - core_text_sect->vma + length >= core_text_sect->size) + goto botched; + operand = instructp + length; + firstmode = vax_operandmode (operand); switch (firstmode) { case literal: @@ -272,8 +277,11 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) default: goto botched; } - length += vax_operandlength (instructp + length); - mode = vax_operandmode (instructp + length); + length += vax_operandlength (operand); + if (pc - core_text_sect->vma + length >= core_text_sect->size) + goto botched; + operand = instructp + length; + mode = vax_operandmode (operand); DBG (CALLDEBUG, printf ("\tfirst operand is %s", vax_operandname (firstmode)); printf ("\tsecond operand is %s\n", vax_operandname (mode))); @@ -294,8 +302,10 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) * [are there others that we miss?, * e.g. arrays of pointers to functions???] */ + length += vax_operandlength (operand); + if (pc - core_text_sect->vma + length > core_text_sect->size) + goto botched; arc_add (parent, &indirectchild, (unsigned long) 0); - length += vax_operandlength (instructp + length); continue; case byterel: case wordrel: @@ -305,7 +315,10 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) * check that this is the address of * a function. */ - destpc = pc + vax_offset (instructp + length); + length += vax_operandlength (operand); + if (pc - core_text_sect->vma + length > core_text_sect->size) + goto botched; + destpc = pc + vax_offset (operand); if (hist_check_address (destpc)) { child = sym_lookup (&symtab, destpc); @@ -324,7 +337,6 @@ vax_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) * a hit */ arc_add (parent, child, (unsigned long) 0); - length += vax_operandlength (instructp + length); continue; } } |