From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id 5DC923858415 for ; Wed, 17 Aug 2022 07:07:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5DC923858415 Received: by mail-pj1-x102c.google.com with SMTP id t2-20020a17090a4e4200b001f21572f3a4so1070173pjl.0 for ; Wed, 17 Aug 2022 00:07:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc; bh=XhU3fsOkD565fVobSkduAU6B4v81iYs5BHubkoEKoR8=; b=HwA7+pD4m/ss7QI6sYKvWhON7tgREKeL4+OLLadfw+vtHu+/5b+4QvdkSaViwiSbgT qQxEhYvzZVN/k61pwanL/7XufENpMBPePdu92ECsXn2KBOmlLzlQKVazILV/pHqNTNut dXeSh9Zovtcl2tkvei3wMqs1VFfeA3YaH9L9eW8BAzgBFA9ETkxEqU9CY2mr2tysmyv0 uiiTx3mfdB1nBmiqoLfVbeiRW7hblRXW4Ih4k2dKlvgGPTuZPyeHr85BuoMsjbTPd9Mr 5Jo8OlWodM/XzYd3hAaIuObA/Jh0lvjaN0WVo+1vvEF1I7j4ADo7Y8+uvMD+nh8CDP+T eNhQ== X-Gm-Message-State: ACgBeo3CpMg8ghjIfsSW/5/KtxJcPnDmRjBgN+Ce8lu3LHzJwp4b3l/T Qq3DrEcOvLqOMq/tAe+A7wofXQqeMt0= X-Google-Smtp-Source: AA6agR6JVr7WnL+T7fOWqVcAKf7r1yJOyvgsI/pCRmE0c07lsy7yCcBJQC6eACozKNEB+45WR7sknw== X-Received: by 2002:a17:902:d890:b0:16c:abb4:94d0 with SMTP id b16-20020a170902d89000b0016cabb494d0mr25742568plz.50.1660720039172; Wed, 17 Aug 2022 00:07:19 -0700 (PDT) Received: from squeak.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id z7-20020aa79587000000b00528c22fbb45sm9968275pfj.141.2022.08.17.00.07.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Aug 2022 00:07:18 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 2F2321142EA6; Wed, 17 Aug 2022 16:37:16 +0930 (ACST) Date: Wed, 17 Aug 2022 16:37:16 +0930 From: Alan Modra To: binutils@sourceware.org Subject: asan: heap buffer overflow in mmo_scan Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3036.6 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 X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Aug 2022 07:07:21 -0000 mmo_get_loc needs to handle arbitrary vma and size chunks. Fuzzers found that it wasn't working so well when the end of chunks were getting close to address wrap-around. * mmo.c (mmo_get_loc): Make "size" unsigned. Avoid arithmetic overflow when calculating whether range hits an existing chunk. diff --git a/bfd/mmo.c b/bfd/mmo.c index 9c177d8d0b0..1c901ae5c20 100644 --- a/bfd/mmo.c +++ b/bfd/mmo.c @@ -382,7 +382,7 @@ static bool mmo_scan (bfd *); static asection *mmo_decide_section (bfd *, bfd_vma); static asection *mmo_get_generic_spec_data_section (bfd *, int); static asection *mmo_get_spec_section (bfd *, int); -static bfd_byte *mmo_get_loc (asection *, bfd_vma, int); +static bfd_byte *mmo_get_loc (asection *, bfd_vma, unsigned int); static bfd_cleanup mmo_object_p (bfd *); static void mmo_map_set_sizes (bfd *, asection *, void *); static bool mmo_get_symbols (bfd *); @@ -1492,7 +1492,7 @@ SUBSECTION MMO_SEC_CONTENTS_CHUNK_SIZE. */ static bfd_byte * -mmo_get_loc (asection *sec, bfd_vma vma, int size) +mmo_get_loc (asection *sec, bfd_vma vma, unsigned int size) { bfd_size_type allocated_size; struct mmo_section_data_struct *sdatap = mmo_section_data (sec); @@ -1504,27 +1504,29 @@ mmo_get_loc (asection *sec, bfd_vma vma, int size) for (; datap != NULL; datap = datap->next) { if (datap->where <= vma - && datap->where + datap->size >= vma + size) - return datap->data + vma - datap->where; + && datap->size >= size + && datap->size - size >= vma - datap->where) + return datap->data + (vma - datap->where); else if (datap->where <= vma - && datap->where + datap->allocated_size >= vma + size + && datap->allocated_size >= size + && datap->allocated_size - size >= vma - datap->where /* Only munch on the "allocated size" if it does not overlap the next chunk. */ && (datap->next == NULL || datap->next->where >= vma + size)) { /* There was room allocated, but the size wasn't set to include it. Do that now. */ - datap->size += (vma + size) - (datap->where + datap->size); + datap->size = vma - datap->where + size; /* Update the section size. This happens only if we update the 32-bit-aligned chunk size. Callers that have non-32-bit-aligned sections should do all allocation and size-setting by themselves or at least set the section size after the last allocating call to this function. */ - if (vma + size > sec->vma + sec->size) - sec->size += (vma + size) - (sec->vma + sec->size); + if (vma - sec->vma + size > sec->size) + sec->size = vma - sec->vma + size; - return datap->data + vma - datap->where; + return datap->data + (vma - datap->where); } } @@ -1535,7 +1537,7 @@ mmo_get_loc (asection *sec, bfd_vma vma, int size) for no more than MMO_SEC_CONTENTS_CHUNK_SIZE will always get resolved. */ for (datap = sdatap->head; datap != NULL; datap = datap->next) - if ((datap->where <= vma && datap->where + datap->size > vma) + if ((datap->where <= vma && datap->size > vma - datap->where) || (datap->where < vma + size && datap->where + datap->size >= vma + size)) return NULL; @@ -1583,8 +1585,8 @@ mmo_get_loc (asection *sec, bfd_vma vma, int size) /* Update the section size. This happens only when we add contents and re-size as we go. The section size will then be aligned to 32 bits. */ - if (vma + size > sec->vma + sec->size) - sec->size += (vma + size) - (sec->vma + sec->size); + if (vma - sec->vma + size > sec->size) + sec->size = vma - sec->vma + size; return entry->data; } -- Alan Modra Australia Development Lab, IBM