From patchwork Sun Mar 15 23:19:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 131766 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 6229F4BCA42E for ; Sun, 15 Mar 2026 23:20:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6229F4BCA42E Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=hv+7DsOb X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by sourceware.org (Postfix) with ESMTPS id A73C24BC8990 for ; Sun, 15 Mar 2026 23:19:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A73C24BC8990 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 A73C24BC8990 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::633 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773616769; cv=none; b=aO8wL0cw9/RyQe98Fiougu/cpaodR5WpF3YvNJvFY845gQ+2rNs+vx9PRzVJznn/m+D2tPm4YvLdifccT/hUbNqZmlk8tRIl+hq2kEOETiXD9O7aNA5jF6gAO3FqCGkbqiTrSmFjxnfZ4/Z6eLLTnMZk72SnIKH24kGwLmY1okA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773616769; c=relaxed/simple; bh=9TTeCg81ymIf7j9OI3oGEy/0hRUHSFVc8KyYuvgKWFs=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=CjBm1PgGvfOZS6h/ENp3M8/2KfhY9aHg7UyWeFKgeI5vs0qqglBNJ678nyoO4bseR5prwsQlSxQ/gcSEnv36MdltBkNWvUqOgAy1dYVa51+W7tQuPvOmOL3qNQ+hGJ33BE+GRz25O+XJZ2tMZwbcIULt2HsTymGOGiAywZA1y+Y= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A73C24BC8990 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-2aaf59c4f7cso18716435ad.1 for ; Sun, 15 Mar 2026 16:19:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773616768; x=1774221568; darn=sourceware.org; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=MRv9GN+it7BlalM22uju7NzKYwXQm2rP55S/YwEZqFo=; b=hv+7DsObdQCJc3E9J9Y/rt3cSiZIM4NO63n6EixI6VWEcA9zGA+uMP4g77L6dabHBY hXIK+TMEI9p4vF2boemPWCpRUxVxT35Q8U4QEGTgyth2yCnZdgl3pO4WFwPtpBOz9JUG 0fjbj05G+ZZBnpu/t/o9pj92XXoAnOdTEgh87w2sXZDvvgbzoeppCUszlLDE9Hrlk0z/ I9usaAt4PRVAHpp0g9yd3LWDgRsA2skcF2bhTDxydfvtBPCOBDi4ClbBc2+srqQrCBQr q1I0KrbGSc4fOw1pUNn484rSP8op0kAF0hMBaKsBICOyhXwniy4khIz3/LXOFiHkD31y kD8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773616768; x=1774221568; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=MRv9GN+it7BlalM22uju7NzKYwXQm2rP55S/YwEZqFo=; b=gd/nRTZ9Z1q1Nz7xKCjJsStCGg/mI9YtYFZk/HxOgZYXpiHtX0lRkJy728mg7NkjW8 G00d+9wRYO0RSs/J24RIz0/Sq8q0gZrji6IsRJe7dToV9SrUEroVbq/LF1KJ0iAiC+0u n5thrcg/rlXYBzYw/s2lCKHtwnEZlRxqLj+dv4h7UF3KR46AqC9UG4lCguFo7seHE81P xLV387fsY/cEQAJP47nQ+LDOHBaFKxhEHgeT+0VVFJkj0Uth5cZq8Ip+FcjtYeNe25J3 ADWxmzC08M2+svjV6Ru00FnmJ82YNDZqsJp6/oq0pG/1i5n+46DfKlnIpbJYGyNvi4nj eKDg== X-Gm-Message-State: AOJu0YwdG9jkU2p6D4/xPZw7G8kbw4I/ibvpLllww1NYtAkrllsxiUtU dTLK+bKqsOzuJCjCnaQgjSZKL3bz7qJMsxgWHHkw1Cu5AQdLggRCmG3ljeNl2g== X-Gm-Gg: ATEYQzyF9Yq1iJaNfOOJ9ZtGWtiCOi7NfpFVLfOiXijKyCQjmn4qWenb64ep4XeP0nP 1KmTj5SYB0O+MAaihgqAbZjf5WPI1PXVBu4+5aPSGaFi+473zQ3wvCnNY7gA4FGn9XBu771/vCy b+oc72ROVM2Y2CNQSGCUTZHJHEPEETdnA2hjptmR2s8tOdnEN45hSFR++B7oqY9k6ThSW89JQiz 33FswEkuDPMYiPkpElc12s4R6LQxYaEidHLmhlwzI7lE90o/Qa5emgyXDqreEEc7SmjiwTEs+Vk YNnku7g2oDapkzNE1kZsWLsBItYnvXe6XHqyIz52mwaZXm0QVG0E25KumcMffqx0dfmbx7ijc6p brxn9BhRSUIE7bvCm2TQvx2K7MsNChJwnucVCbiAlhcZyf67STAgtwdenJhNezurHxJEaUR7TFh 2unVm3jFkDSqbaAJBylTeHzhgVBv2gLZnT/T7U X-Received: by 2002:a17:903:240b:b0:2ae:4fc8:3f59 with SMTP id d9443c01a7336-2aecac9d416mr113505135ad.49.1773616768182; Sun, 15 Mar 2026 16:19:28 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:f59c:99bb:274f:70f3]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2aece7ee1d8sm91349035ad.55.2026.03.15.16.19.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Mar 2026 16:19:27 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 3898911406A3; Mon, 16 Mar 2026 09:49:25 +1030 (ACDT) Date: Mon, 16 Mar 2026 09:49:25 +1030 From: Alan Modra To: binutils@sourceware.org Subject: PR33919 Out-of-bounds read in XCOFF relocation processing Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3030.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP 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 PR 33919 * coff-rs6000.c (xcoff_calculate_relocation): Don't use explicit array size. (xcoff_complain_overflow): Likewise. (xcoff_rtype2howto): Return a NULL howto rather than aborting. (_bfd_xcoff_reloc_name_lookup): Use ARRAY_SIZE. (xcoff_ppc_relocate_section): Sanity check reloc r_type before accessing xcoff_howto_table. Print r_type using %#x. Remove now redundant later reloc r_type sanity check. * coff64-rs6000.c: Similarly. * libxcoff.h (XCOFF_MAX_CALCULATE_RELOCATION): Don't define. (XCOFF_MAX_COMPLAIN_OVERFLOW): Don't define. diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 62caae64f4e..00e0f5442f7 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -155,8 +155,7 @@ static xcoff_complain_function xcoff_complain_overflow_bitfield_func; static xcoff_complain_function xcoff_complain_overflow_signed_func; static xcoff_complain_function xcoff_complain_overflow_unsigned_func; -xcoff_reloc_function *const -xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = +xcoff_reloc_function *const xcoff_calculate_relocation[] = { xcoff_reloc_type_pos, /* R_POS (0x00) */ xcoff_reloc_type_neg, /* R_NEG (0x01) */ @@ -210,8 +209,7 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = xcoff_reloc_type_toc, /* R_TOCL (0x31) */ }; -xcoff_complain_function *const -xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW] = +xcoff_complain_function *const xcoff_complain_overflow[] = { xcoff_complain_overflow_dont_func, xcoff_complain_overflow_bitfield_func, @@ -1158,8 +1156,11 @@ reloc_howto_type xcoff_howto_table[] = void xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) { - if (internal->r_type > R_TOCL) - abort (); + if (internal->r_type >= ARRAY_SIZE (xcoff_howto_table)) + { + relent->howto = NULL; + return; + } /* Default howto layout works most of the time */ relent->howto = &xcoff_howto_table[internal->r_type]; @@ -1183,7 +1184,7 @@ xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) if (relent->howto->dst_mask != 0 && (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1)) - abort (); + relent->howto = NULL; } reloc_howto_type * @@ -1236,9 +1237,7 @@ _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int i; - for (i = 0; - i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]); - i++) + for (i = 0; i < ARRAY_SIZE (xcoff_howto_table); i++) if (xcoff_howto_table[i].name != NULL && strcasecmp (xcoff_howto_table[i].name, r_name) == 0) return &xcoff_howto_table[i]; @@ -3768,6 +3767,14 @@ xcoff_ppc_relocate_section (bfd *output_bfd, the csect including the symbol which it references. */ if (rel->r_type == R_REF) continue; + if (rel->r_type >= ARRAY_SIZE (xcoff_howto_table)) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + input_bfd, rel->r_type); + bfd_set_error (bfd_error_bad_value); + return false; + } /* Retrieve default value in HOWTO table and fix up according to r_size field, if it can be different. @@ -3787,7 +3794,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd, default: _bfd_error_handler - (_("%pB: relocation (%d) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"), + (_("%pB: relocation (%#x) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"), input_bfd, rel->r_type, (uint64_t) rel->r_vaddr, rel->r_size); return false; } @@ -3863,10 +3870,9 @@ xcoff_ppc_relocate_section (bfd *output_bfd, } } - if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION - || !((*xcoff_calculate_relocation[rel->r_type]) - (input_bfd, input_section, output_bfd, rel, sym, &howto, val, - addend, &relocation, contents, info))) + if (!((*xcoff_calculate_relocation[rel->r_type]) + (input_bfd, input_section, output_bfd, rel, sym, &howto, val, + addend, &relocation, contents, info))) return false; /* address */ diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index fa1759b5925..f6a60433e62 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -177,8 +177,7 @@ static bool xcoff64_bad_format_hook /* Relocation functions */ static xcoff_reloc_function xcoff64_reloc_type_br; -xcoff_reloc_function *const -xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = +xcoff_reloc_function *const xcoff64_calculate_relocation[] = { xcoff_reloc_type_pos, /* R_POS (0x00) */ xcoff_reloc_type_neg, /* R_NEG (0x01) */ @@ -1439,8 +1438,11 @@ reloc_howto_type xcoff64_howto_table[] = void xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) { - if (internal->r_type > R_TOCL) - abort (); + if (internal->r_type >= ARRAY_SIZE (xcoff64_howto_table)) + { + relent->howto = NULL; + return; + } /* Default howto layout works most of the time */ relent->howto = &xcoff64_howto_table[internal->r_type]; @@ -1473,7 +1475,7 @@ xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) if (relent->howto->dst_mask != 0 && (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x3f) + 1)) - abort (); + relent->howto = NULL; } reloc_howto_type * @@ -1528,9 +1530,7 @@ xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int i; - for (i = 0; - i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]); - i++) + for (i = 0; i < ARRAY_SIZE (xcoff64_howto_table); i++) if (xcoff64_howto_table[i].name != NULL && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0) return &xcoff64_howto_table[i]; @@ -1574,6 +1574,14 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, the csect including the symbol which it references. */ if (rel->r_type == R_REF) continue; + if (rel->r_type >= ARRAY_SIZE (xcoff64_howto_table)) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + input_bfd, rel->r_type); + bfd_set_error (bfd_error_bad_value); + return false; + } /* Retrieve default value in HOWTO table and fix up according to r_size field, if it can be different. @@ -1595,7 +1603,7 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, default: _bfd_error_handler - (_("%pB: relocation (%d) at (0x%" PRIx64 ") has wrong" + (_("%pB: relocation (%#x) at (0x%" PRIx64 ") has wrong" " r_rsize (0x%x)\n"), input_bfd, rel->r_type, rel->r_vaddr, rel->r_size); return false; @@ -1668,10 +1676,9 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, } } - if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION - || !((*xcoff64_calculate_relocation[rel->r_type]) - (input_bfd, input_section, output_bfd, rel, sym, &howto, val, - addend, &relocation, contents, info))) + if (!((*xcoff64_calculate_relocation[rel->r_type]) + (input_bfd, input_section, output_bfd, rel, sym, &howto, val, + addend, &relocation, contents, info))) return false; /* address */ diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h index c116d9b795f..e6b87975ff6 100644 --- a/bfd/libxcoff.h +++ b/bfd/libxcoff.h @@ -217,9 +217,6 @@ struct xcoff_backend_data_rec #define bfd_xcoff_text_align_power(a) ((xcoff_data (a)->text_align_power)) #define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power)) -/* xcoff*_ppc_relocate_section macros */ -#define XCOFF_MAX_CALCULATE_RELOCATION (0x32) -#define XCOFF_MAX_COMPLAIN_OVERFLOW (4) /* N_ONES produces N one bits, without overflowing machine arithmetic. */ #ifdef N_ONES #undef N_ONES