From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oo1-xc33.google.com (mail-oo1-xc33.google.com [IPv6:2607:f8b0:4864:20::c33]) by sourceware.org (Postfix) with ESMTPS id 9E932385C6F1 for ; Wed, 26 Jul 2023 00:56:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9E932385C6F1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo1-xc33.google.com with SMTP id 006d021491bc7-56661fe27cbso4138136eaf.3 for ; Tue, 25 Jul 2023 17:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1690332960; x=1690937760; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=SkOjLJAEoSbQZmEBqFi5P8QCk0AXxGbjbP7+LKvXDVU=; b=srfFNSbu8a02+Xv1tTk9DSDc2Fz6Alq6IKuR+djbzPYYH5jODfJxBM3/k+MISSEfiB JLhVcuyRfg5XJDOfuzl0q7reA6V+FpJ/BWc7hPJdZ8oz2mRUZwWrNwJnKjJZ0sm2PBno /2ombxEtwZw0deoivuuJWaqNKstW7i1fesL4xuaaAxX6Fr4lsq9y6N/29blM80I69O1G 0+bSjPxmeOdiQD85Gj9//J7xDZtaNx/k7eFFA+19UfYRaA4bSqFWnf8dY/mNCgIjlXUc ypSEe10rxvTt5j0wX4LttzxqYmUmC4DXDQ5+a5PrvXw/LCUk9sFYbtd5G0ZaYO0RDmaM 63sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690332960; x=1690937760; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=SkOjLJAEoSbQZmEBqFi5P8QCk0AXxGbjbP7+LKvXDVU=; b=laAVYeiQ0mWSEyFjWM1f+UhNVNhYfneeCB4SXAlZ9fV638F6NyfBVdW5915z1eVIiK l/0ZdOd6GxznFP9yBGJgnTjHO+77SpAJa8GwpdEHGnx+caDBJiXaury91CC5pgjZQvY0 7f58gckHOeDieQtpCDxkGbPhYF0d8eMhFXV/cyB/bPUSsfpU7p6tBrYdngvLoGWLIr3Q TQ6QvrNld/JYXx2jT8vNnJaa73afkGd6uUcjedS4M5OqKoWq5WzYa/ggjxXUGOh9cQg4 p3ATtJ7dmYe3Xpc3PwZzCtv5kZJEesv9XEnOv5SanbfxTpL14OsqiRY6iN2JFZbGgBAx 9gIg== X-Gm-Message-State: ABy/qLYhmEVnO5j2+3bA6PSkv/uvNOyd2pdEw5pHYa16zTI0q/r19dQn JyXW6Dtl7h5fJNLbOcxFHLrwDXmpgmo= X-Google-Smtp-Source: APBJJlGapE57e//kgxfjdiP2/RcojRJNvrsobP7bKIVO7i2kMI/yQED4iYnnyJ+4nIGVs1VGUACiPQ== X-Received: by 2002:a05:6808:2088:b0:3a3:f7b8:576f with SMTP id s8-20020a056808208800b003a3f7b8576fmr618485oiw.19.1690332959799; Tue, 25 Jul 2023 17:55:59 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:269e:e27:8964:c006]) by smtp.gmail.com with ESMTPSA id 4-20020a17090a198400b002682392506bsm162483pji.50.2023.07.25.17.55.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Jul 2023 17:55:59 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 0E22F1142902; Wed, 26 Jul 2023 10:25:57 +0930 (ACST) Date: Wed, 26 Jul 2023 10:25:57 +0930 From: Alan Modra To: binutils@sourceware.org Subject: PR30657, gprof heap buffer overflow Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3034.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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. diff --git a/gprof/aarch64.c b/gprof/aarch64.c index 68febf93723..3ab6067dbac 100644 --- a/gprof/aarch64.c +++ b/gprof/aarch64.c @@ -54,7 +54,8 @@ aarch64_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n", parent->name, (unsigned long) p_lowpc, (unsigned long) p_highpc)); - + p_lowpc = (p_lowpc + 3) & ~3; + p_highpc &= ~3; for (pc = p_lowpc; pc < p_highpc; pc += 4) { diff --git a/gprof/alpha.c b/gprof/alpha.c index d84cdf0a916..df714be6c81 100644 --- a/gprof/alpha.c +++ b/gprof/alpha.c @@ -107,7 +107,9 @@ alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"), parent->name, (unsigned long) p_lowpc, (unsigned long) p_highpc)); - for (pc = (p_lowpc + 3) & ~(bfd_vma) 3; pc < p_highpc; pc += 4) + p_lowpc = (p_lowpc + 3) & ~3; + p_highpc &= ~3; + for (pc = p_lowpc; pc < p_highpc; pc += 4) { insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space + pc - core_text_sect->vma)); diff --git a/gprof/cg_arcs.c b/gprof/cg_arcs.c index e76c2cb78cf..cfffb09ff87 100644 --- a/gprof/cg_arcs.c +++ b/gprof/cg_arcs.c @@ -37,6 +37,7 @@ #include "cg_print.h" #include "utils.h" #include "sym_ids.h" +#include "corefile.h" static int cmp_topo (const void *, const void *); static void propagate_time (Sym *); @@ -622,7 +623,11 @@ cg_assemble (void) parent->cg.cyc.num = 0; parent->cg.cyc.head = parent; parent->cg.cyc.next = 0; - if (ignore_direct_calls) + if (ignore_direct_calls + && parent->addr >= core_text_sect->vma + && parent->addr < core_text_sect->vma + core_text_sect->size + && (parent + 1)->addr >= core_text_sect->vma + && (parent + 1)->addr <= core_text_sect->vma + core_text_sect->size) find_call (parent, parent->addr, (parent + 1)->addr); } diff --git a/gprof/i386.c b/gprof/i386.c index bdf8bd1b832..62f6f96b20a 100644 --- a/gprof/i386.c +++ b/gprof/i386.c @@ -57,6 +57,9 @@ i386_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) parent->name, (unsigned long) p_lowpc, (unsigned long) p_highpc)); + if (p_highpc < 5) + return; + p_highpc -= 5; for (pc = p_lowpc; pc < p_highpc; ++pc) { instructp = (unsigned char *) core_text_space + pc - core_text_sect->vma; diff --git a/gprof/mips.c b/gprof/mips.c index e198a6f411a..0ccd17db525 100644 --- a/gprof/mips.c +++ b/gprof/mips.c @@ -59,6 +59,8 @@ mips_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"), parent->name, (unsigned long) p_lowpc, (unsigned long) p_highpc)); + p_lowpc = (p_lowpc + 3) & ~3; + p_highpc &= ~3; for (pc = p_lowpc; pc < p_highpc; pc += 4) { op = bfd_get_32 (core_bfd, ((unsigned char *)core_text_space diff --git a/gprof/sparc.c b/gprof/sparc.c index 44724c47d3f..019e58b185f 100644 --- a/gprof/sparc.c +++ b/gprof/sparc.c @@ -51,7 +51,9 @@ sparc_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc) DBG (CALLDEBUG, printf ("[find_call] %s: 0x%lx to 0x%lx\n", parent->name, (unsigned long) p_lowpc, (unsigned long) p_highpc)); - for (pc = (p_lowpc + 3) & ~(bfd_vma) 3; pc < p_highpc; pc += 4) + p_lowpc = (p_lowpc + 3) & ~3; + p_highpc &= ~3; + for (pc = p_lowpc; pc < p_highpc; pc += 4) { insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space + pc - core_text_sect->vma)); diff --git a/gprof/vax.c b/gprof/vax.c index 92942353b48..fafe2b17b53 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; } } -- Alan Modra Australia Development Lab, IBM