From patchwork Thu Jul 2 03:03:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 138283 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 795D64BA2E0E for ; Thu, 2 Jul 2026 03:04:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 795D64BA2E0E Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=hoFdPuHY X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by sourceware.org (Postfix) with ESMTPS id 227904BA2E0E for ; Thu, 2 Jul 2026 03:03:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 227904BA2E0E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 227904BA2E0E Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1035 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782961433; cv=none; b=f3m8spzND/xMajbusZYOuYZRyCspH+shaFkSPVLwdUQw+qA0lycl3xzMhCdH0yJO+S8LNhKYTclS8BmcbziIJAECn6VYAe+bTa6mLT/ONK60byM6ug430AYD1l3YJVQotYcJi0z9LIEd3jO4RQZF3zz23CM3mXcyojXwViufFPs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1782961433; c=relaxed/simple; bh=jup+R5dahIpjfzRwesvZhFG9+aW3VzdlmwzP42RwitY=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=SwH/mkDcqHZWmWzlBhhDLJyA5dNrU7lYKI+QXfj+AKstexeOSs5iAmZle/EstjvK+nTE91GX4yaAjtPR510vfN+iVyCCsAYXrl/ylen5dOFmn+SYJ7k5Wu/z79BKqqoBNtf2+hZLakw16CZZahTKB3Nkpv4W66X0zZ7cjquxWTs= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=hoFdPuHY DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 227904BA2E0E Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-37f72212544so1407217a91.0 for ; Wed, 01 Jul 2026 20:03:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782961432; x=1783566232; darn=sourceware.org; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=sqN8vnYnY72WAKPyGuQ1KtAmX56rKXMr8PAiC5cE5PM=; b=hoFdPuHYdSRdhombahnM7Cbe/aFoIbcn/gFno+EBbq5D+ZBM0SO8MIKGp3Xo6judDL uF8qjYxMe4Z+86DV/s3nvn7riRLZKr4/BCeaYpkUk82D2zut7goQGa10Ui1datET+of7 /Zdo4Qf+X4GGchA1H4E3YmbqDzoD+/rdtJ8oq8J7nxJ2IGW4TuNeCV855LEbuobNlzf2 FeYcfvKqCCu5gyuTyT+pBMRRxxq41h7XvhU9vV/AQRd23RSY/gEygAnAIjsS/7p1eV2F pQefq9LyTwCxRJh+CYSG020RPXvsMTOrt8TW4r5zt8MYyUImGdZBjbWQLq2TBr2tQg2e cfAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782961432; x=1783566232; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=sqN8vnYnY72WAKPyGuQ1KtAmX56rKXMr8PAiC5cE5PM=; b=cnZJtKWYJQMCkSw0fsUY3tecEjlf2l2k2TBRzkBHOxf5cdn9l8Zh+ad3IuUIvGdMqL v35ko8M5048ML5/+S/95Gi1UhFZyRBix9iST5Qs/IBdHT1LidNyCoroxGclETiAVm3gM tpO13bXCwCfm/5S08qpPQ173SCeUznhVvheRhqx9fKq2lgvMUl7Np3hZaTSActgCn6DR B0ABmMxVWGZQheD9XkwIkqfEbRJ8co8MU+5fsTws3BGpcKiwuueX1e0WLtzN3DAQyN5U 7pUQRTO49jRLB6+OSNFELh/9kp5Q1oAMMcVSm7OWnOXEjQYPVKxTG657IgwfVV2OQSUa LcJQ== X-Gm-Message-State: AOJu0YxQywxbvNLcHpOyeGCsGSzRH98fW3l/z0xUeij48GZ7lStZM+g+ mmIbsOwNvy3kWh+cpOafw1Rrnbx2kdI0ew9ij01Lnqci2f83elGGSCjLtbwaAA== X-Gm-Gg: AfdE7cl6toH9UE0SSnnINYd+0UGiOdzMcyldf7BR1EINhaK8OrSjo7ZHyuyx/BUwdpl aCGB2+RJhg65/H2WABameY110wqU8oTNSBOTNywuPd2VAbY4TsxVnglFmoRJtDrHM3a73hsrFNP yjAgK2eWUZBMvMXOzgoMYKr8G1OMD9P7IZE5M8Zpjz4L6RhQX+dp5wrs9+ve0RqXPWOGanuYziR fgpm/hReQ7hvNwgZLb81HSIsV2wy0rNwTBnEzOSkXIxHSmLfMFKnEMe7WmBBbdXZYR9z3dQ+CaD ESKLZV+GUB8bcQOBhqRugEz36J9nFnq4EfRz5hgQDjD8G4JE8GdbQ6x0XbREy/ya03gqhpzTWdT 1MO4zM6Bngp10suuLageYDY2n3tDdCzJaMeI4VfkRtTDzIorvEwVYOQznSyROv7Nh2Vh7D4ltOY NY062HpMUP4jW+rM1FEKYT63/8rtMiNVwCe158IFpSPP2LmE7u2Qu8vA== X-Received: by 2002:a17:90b:4e8c:b0:37c:ad9b:680b with SMTP id 98e67ed59e1d1-380aa18c40emr3909110a91.20.1782961431760; Wed, 01 Jul 2026 20:03:51 -0700 (PDT) Received: from squeak.grove.modra.org (58-96-106-158.ip4.superloop.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30f0b7b8e3dsm3751093eec.6.2026.07.01.20.03.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Jul 2026 20:03:51 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id AD5F11140BEA; Thu, 02 Jul 2026 12:33:47 +0930 (ACST) Date: Thu, 2 Jul 2026 12:33:47 +0930 From: Alan Modra To: binutils@sourceware.org Cc: Hans-Peter Nilsson Subject: PR 34327 Out of bounds accesses in reloc special functions. Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3029.9 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 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org As per the PR, s12z lacked any reloc offset sanity checking, the others all just checked that the offset started within the section rather than checking the field was contained in the section. Using the proper check for mmix exposed a problem in the howto table, present since the initial mmix commit. The R_MMIX_BASE_PLUS_OFFSET field is actually two bytes, located at the reloc address. Making it an eight byte field is just wrong, as doing that indicates the field is at the reloc address plus six bytes for a big-endian target. Presumably this was done for overlow reporting, which is properly done by appropriately setting complain_on_overflow. * elf32-d30v.c (bfd_elf_d30v_reloc, bfd_elf_d30v_reloc_21): Use bfd_reloc_offset_in_range * elf32-s12z.c (opru18_reloc): Likewise. * elf32-spu.c (spu_elf_rel9): Likewise. * elf32-xstormy16.c (xstormy16_elf_24_reloc): Likewise. * elf32-visium.c (visium_elf_howto_parity_reloc): Likewise. Remove unnecessary casts too. * elf64-s390.c (s390_elf_ldisp_reloc): Likewise. * elfxx-sparc.c (init_insn_reloc): Likewise. * elf64-mmix.c (mmix_elf_reloc): Likewise. Remove unnecessary variable too. (elf_mmix_howto_table[R_MMIX_BASE_PLUS_OFFSET]): Correct size, bitsize and complain_on_overflow. diff --git a/bfd/elf32-d30v.c b/bfd/elf32-d30v.c index 95277412346..a74107cff21 100644 --- a/bfd/elf32-d30v.c +++ b/bfd/elf32-d30v.c @@ -66,8 +66,8 @@ bfd_elf_d30v_reloc (bfd *abfd, && output_bfd == NULL) flag = bfd_reloc_undefined; - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address)) return bfd_reloc_outofrange; /* Work out which section the relocation is targeted at and the @@ -174,8 +174,8 @@ bfd_elf_d30v_reloc_21 (bfd *abfd, && output_bfd == NULL) flag = bfd_reloc_undefined; - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address)) return bfd_reloc_outofrange; /* Work out which section the relocation is targeted at and the diff --git a/bfd/elf32-s12z.c b/bfd/elf32-s12z.c index 1630895136e..52eaf4f4e6c 100644 --- a/bfd/elf32-s12z.c +++ b/bfd/elf32-s12z.c @@ -48,6 +48,9 @@ opru18_reloc (bfd *abfd, arelent *reloc_entry, struct bfd_symbol *symbol, bfd_size_type octets = (reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section)); + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, octets)) + return bfd_reloc_outofrange; bfd_vma result = bfd_get_24 (abfd, (unsigned char *) data + octets); bfd_vma val = bfd_asymbol_value (symbol); diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index e0e74b781ff..5f1183ce7d1 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -213,9 +213,10 @@ spu_elf_rel9 (bfd *abfd, arelent *reloc_entry, asymbol *symbol, return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; octets = reloc_entry->address * OCTETS_PER_BYTE (abfd, input_section); + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, octets)) + return bfd_reloc_outofrange; /* Get symbol value. */ val = 0; diff --git a/bfd/elf32-visium.c b/bfd/elf32-visium.c index fe5f4d5eafb..b862b13614e 100644 --- a/bfd/elf32-visium.c +++ b/bfd/elf32-visium.c @@ -303,7 +303,7 @@ visium_parity_bit (bfd_vma insn) It sets instruction parity to even. This cannot be done by a howto. */ static bfd_reloc_status_type -visium_elf_howto_parity_reloc (bfd * input_bfd, arelent *reloc_entry, +visium_elf_howto_parity_reloc (bfd *input_bfd, arelent *reloc_entry, asymbol *symbol, void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) @@ -316,7 +316,7 @@ visium_elf_howto_parity_reloc (bfd * input_bfd, arelent *reloc_entry, /* This part is from bfd_elf_generic_reloc. If we're relocating, and this an external symbol, we don't want to change anything. */ - if (output_bfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0) + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0) { reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; @@ -324,21 +324,21 @@ visium_elf_howto_parity_reloc (bfd * input_bfd, arelent *reloc_entry, /* Now do the reloc in the usual way. */ - /* Sanity check the address (offset in section). */ - if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, input_bfd, + input_section, reloc_entry->address)) return bfd_reloc_outofrange; ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL) + if (bfd_is_und_section (symbol->section) && output_bfd == NULL) ret = bfd_reloc_undefined; - if (bfd_is_com_section (symbol->section) || output_bfd != (bfd *) NULL) + if (bfd_is_com_section (symbol->section) || output_bfd != NULL) relocation = 0; else relocation = symbol->value; /* Only do this for a final link. */ - if (output_bfd == (bfd *) NULL) + if (output_bfd == NULL) { relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; @@ -383,7 +383,7 @@ visium_elf_howto_parity_reloc (bfd * input_bfd, arelent *reloc_entry, insn |= visium_parity_bit (insn); bfd_put_32 (input_bfd, insn, inplace_address); - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) reloc_entry->address += input_section->output_offset; return ret; diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index 60ab5e6875a..04782449b8a 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -44,7 +44,8 @@ xstormy16_elf_24_reloc (bfd *abfd, return bfd_reloc_ok; } - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address)) return bfd_reloc_outofrange; if (bfd_is_com_section (symbol->section)) diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 4036dcb7c3d..ca611b75012 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -703,16 +703,14 @@ static reloc_howto_type elf_mmix_howto_table[] = 0xff, /* dst_mask */ false), /* pcrel_offset */ - /* A register plus an index, corresponding to the relocation expression. - The sizes must correspond to the valid range of the expression, while - the bitmasks correspond to what we store in the image. */ + /* A register plus an index, corresponding to the relocation expression. */ HOWTO (R_MMIX_BASE_PLUS_OFFSET, /* type */ 0, /* rightshift */ - 8, /* size */ - 64, /* bitsize */ + 2, /* size */ + 16, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ + complain_overflow_dont, /* complain_on_overflow */ mmix_elf_reloc, /* special_function */ "R_MMIX_BASE_PLUS_OFFSET", /* name */ false, /* partial_inplace */ @@ -1282,8 +1280,7 @@ mmix_elf_reloc (bfd *abfd, bfd_vma relocation; bfd_reloc_status_type r; asection *reloc_target_output_section; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_vma output_base = 0; + bfd_vma output_base; r = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message); @@ -1295,13 +1292,9 @@ mmix_elf_reloc (bfd *abfd, if (bfd_is_und_section (symbol->section) && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) + && output_bfd == NULL) return bfd_reloc_undefined; - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - /* Work out which section the relocation is targeted at and the initial relocation command value. */ @@ -1322,7 +1315,7 @@ mmix_elf_reloc (bfd *abfd, relocation += output_base + symbol->section->output_offset; - if (output_bfd != (bfd *) NULL) + if (output_bfd != NULL) { /* Add in supplied addend. */ relocation += reloc_entry->addend; @@ -1332,9 +1325,13 @@ mmix_elf_reloc (bfd *abfd, Modify the reloc inplace to reflect what we now know. */ reloc_entry->addend = relocation; reloc_entry->address += input_section->output_offset; - return flag; + return bfd_reloc_ok; } + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address)) + return bfd_reloc_outofrange; + return mmix_final_link_relocate (reloc_entry->howto, input_section, data, reloc_entry->address, reloc_entry->addend, relocation, diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index cbffbc99a78..9150670f0ce 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -417,7 +417,7 @@ s390_elf_ldisp_reloc (bfd *abfd, bfd_vma relocation; bfd_vma insn; - if (output_bfd != (bfd *) NULL + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (! howto->partial_inplace || reloc_entry->addend == 0)) @@ -428,7 +428,8 @@ s390_elf_ldisp_reloc (bfd *abfd, if (output_bfd != NULL) return bfd_reloc_continue; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address)) return bfd_reloc_outofrange; relocation = (symbol->value diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 14d8fb9986f..641b806f686 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -55,7 +55,7 @@ init_insn_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_vma relocation; reloc_howto_type *howto = reloc_entry->howto; - if (output_bfd != (bfd *) NULL + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (! howto->partial_inplace || reloc_entry->addend == 0)) @@ -68,7 +68,8 @@ init_insn_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (output_bfd != NULL) return bfd_reloc_continue; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address)) return bfd_reloc_outofrange; relocation = (symbol->value