From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by sourceware.org (Postfix) with ESMTPS id 964503858D38 for ; Mon, 6 Feb 2023 12:33:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 964503858D38 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-pg1-x52e.google.com with SMTP id 7so8067938pgh.7 for ; Mon, 06 Feb 2023 04:33:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=rnIHqugv9DTZZuzIUMRfKtM72GItAvWzGdDJOJiQ7vM=; b=Rdt2gpsZAous8u2mgyIsRBRWWYPDZ9zkJ9TlCcTkY6BhLdj2FGY37JEpMLK02+O6y+ iJ0ovuT4rdaVKiodcdYrlAAIWfv7t5iTCBeQsdWkjtrN1FsBxwhrgEQ7JvepLG+s0qzC XTMKtz+elFeoOZdJoT7Birjg59n8JUN9ohiYvlIyPlbXQuIDy4/RXhj7ApDgyL9Bz/RD fFl0b180IxRxh17hkC0nVkouWZayIfm2SPaSExt4MKFY+o6zONLvDb896GNtZbL0zK1Z me6djdyq+w/u/eI7FeaNW6U0pZDM8NC5DEBUwuZOgeNOvG1kH4TL3gXZK4PLb47S4BId 2T5w== 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:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rnIHqugv9DTZZuzIUMRfKtM72GItAvWzGdDJOJiQ7vM=; b=EYXSBVAMwGnKVy/XxV78R42GNaZrR7doYBG452F2KVXOPKX1vVOeNR/Jxf3y8saghY U57DJkFfOgxWNZKtLFfpUMSi7WLf7efmgMGNCInwjrAtMcyHOtIJc3UCRCaST36GfzNZ WgxRu1VNvBFslz9Kcrm7fAHPpNyiaYUgdM4Mka25FrXJCJDWJSQKJJVPRwvk/VGuzAX0 r03mfQ/Se26C3IkUJWNLi6gbb0nrd5NahfhIl/KpBJYnEDyYv/rfUIhHx/+a2wqOL5TD IOX76dYdtUxtspBqsJIdkEkjuAgYM4YQNfFdsSd4T/9lxHXxhvNeVT2ABoidHXwodpD7 YCLQ== X-Gm-Message-State: AO0yUKW2FkRRxfGxh9PZaNf22FT9pU3E/YYHADyZH+VLiy1T85JgzfWs koTNFodAch9UvBL3zqy32ZpkPMdJwHU= X-Google-Smtp-Source: AK7set9o1aYIPiYzG2a5bR+vh9knNRevJYv7T2pOT9i4BS8O86NXtsYrDzaBgCmYiVo9UGm07En+mw== X-Received: by 2002:a05:6a00:22d6:b0:593:bc80:2d2d with SMTP id f22-20020a056a0022d600b00593bc802d2dmr23684987pfj.17.1675686792529; Mon, 06 Feb 2023 04:33:12 -0800 (PST) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:8595:7eb:ede9:c45]) by smtp.gmail.com with ESMTPSA id x18-20020a056a00189200b0058e12bbb560sm7278116pfh.15.2023.02.06.04.33.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Feb 2023 04:33:12 -0800 (PST) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id A564C11401F9; Mon, 6 Feb 2023 23:03:09 +1030 (ACDT) Date: Mon, 6 Feb 2023 23:03:09 +1030 From: Alan Modra To: binutils@sourceware.org Cc: Chenghua Xu , "Maciej W. Rozycki" Subject: Protect mips_hi16_list from fuzzed debug info Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3035.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 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: This is another fix for the testcase mentioned in https://sourceware.org/pipermail/binutils/2023-February/125915.html either of which will stop the addr2line segfault. This one also fixes a potential problem when linking corrupted debug info. OK to apply? * elfxx-mips.c (struct mips_elf_obj_tdata): Add freeze_mips_hi16_list. (_bfd_mips_elf_hi16_reloc): Heed freeze_mips_hi16_list. (_bfd_mips_elf_lo16_reloc): Likewise. (find_nearest_line): Rename from _bfd_mips_elf_find_nearest_line and make static. (_bfd_mips_elf_find_nearest_line): New wrapper function setting freeze_mips_hi16_list around find_nearest_line. diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index e9fb61ff9e7..20934c477e2 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -599,6 +599,7 @@ struct mips_elf_obj_tdata asection *elf_text_section; struct mips_hi16 *mips_hi16_list; + bool freeze_mips_hi16_list; }; /* Get MIPS ELF private object data from BFD's tdata. */ @@ -2534,11 +2535,14 @@ _bfd_mips_elf_hi16_reloc (bfd *abfd, arelent *reloc_entry, if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) return bfd_reloc_outofrange; + tdata = mips_elf_tdata (abfd); + if (tdata->freeze_mips_hi16_list) + return bfd_reloc_outofrange; + n = bfd_malloc (sizeof *n); if (n == NULL) return bfd_reloc_outofrange; - tdata = mips_elf_tdata (abfd); n->next = tdata->mips_hi16_list; n->data = data; n->input_section = input_section; @@ -2596,38 +2600,41 @@ _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, location); tdata = mips_elf_tdata (abfd); - while (tdata->mips_hi16_list != NULL) - { - bfd_reloc_status_type ret; - struct mips_hi16 *hi; - - hi = tdata->mips_hi16_list; - - /* R_MIPS*_GOT16 relocations are something of a special case. We - want to install the addend in the same way as for a R_MIPS*_HI16 - relocation (with a rightshift of 16). However, since GOT16 - relocations can also be used with global symbols, their howto - has a rightshift of 0. */ - if (hi->rel.howto->type == R_MIPS_GOT16) - hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, false); - else if (hi->rel.howto->type == R_MIPS16_GOT16) - hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS16_HI16, false); - else if (hi->rel.howto->type == R_MICROMIPS_GOT16) - hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MICROMIPS_HI16, false); - - /* VALLO is a signed 16-bit number. Bias it by 0x8000 so that any - carry or borrow will induce a change of +1 or -1 in the high part. */ - hi->rel.addend += (vallo + 0x8000) & 0xffff; - - ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data, - hi->input_section, output_bfd, - error_message); - if (ret != bfd_reloc_ok) - return ret; - - tdata->mips_hi16_list = hi->next; - free (hi); - } + if (!tdata->freeze_mips_hi16_list) + while (tdata->mips_hi16_list != NULL) + { + bfd_reloc_status_type ret; + struct mips_hi16 *hi; + + hi = tdata->mips_hi16_list; + + /* R_MIPS*_GOT16 relocations are something of a special case. + We want to install the addend in the same way as for a + R_MIPS*_HI16 relocation (with a rightshift of 16). + However, since GOT16 relocations can also be used with + global symbols, their howto has a rightshift of 0. */ + if (hi->rel.howto->type == R_MIPS_GOT16) + hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, false); + else if (hi->rel.howto->type == R_MIPS16_GOT16) + hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS16_HI16, false); + else if (hi->rel.howto->type == R_MICROMIPS_GOT16) + hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MICROMIPS_HI16, + false); + + /* VALLO is a signed 16-bit number. Bias it by 0x8000 so that + any carry or borrow will induce a change of +1 or -1 in the + high part. */ + hi->rel.addend += (vallo + 0x8000) & 0xffff; + + ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data, + hi->input_section, output_bfd, + error_message); + if (ret != bfd_reloc_ok) + return ret; + + tdata->mips_hi16_list = hi->next; + free (hi); + } return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, @@ -13118,13 +13125,11 @@ struct mips_elf_find_line struct ecoff_find_line i; }; -bool -_bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols, - asection *section, bfd_vma offset, - const char **filename_ptr, - const char **functionname_ptr, - unsigned int *line_ptr, - unsigned int *discriminator_ptr) +static bool +find_nearest_line (bfd *abfd, asymbol **symbols, + asection *section, bfd_vma offset, + const char **filename_ptr, const char **functionname_ptr, + unsigned int *line_ptr, unsigned int *discriminator_ptr) { asection *msec; @@ -13228,6 +13233,25 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols, line_ptr, discriminator_ptr); } +bool +_bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols, + asection *section, bfd_vma offset, + const char **filename_ptr, + const char **functionname_ptr, + unsigned int *line_ptr, + unsigned int *discriminator_ptr) +{ + /* Debug info should not contain hi16 or lo16 relocs. If it does + then someone is playing fuzzing games. Altering the hi16 list + during linking when printing an error message is bad. */ + mips_elf_tdata (abfd)->freeze_mips_hi16_list = true; + bool ret = find_nearest_line (abfd, symbols, section, offset, + filename_ptr, functionname_ptr, + line_ptr, discriminator_ptr); + mips_elf_tdata (abfd)->freeze_mips_hi16_list = false; + return ret; +} + bool _bfd_mips_elf_find_inliner_info (bfd *abfd, const char **filename_ptr, @@ -13321,16 +13345,19 @@ _bfd_elf_mips_get_relocated_section_contents mips_hi16_list that point into this section's data. Data will typically be freed on return from this function. */ tdata = mips_elf_tdata (abfd); - hip = &tdata->mips_hi16_list; - while ((hi = *hip) != NULL) + if (!tdata->freeze_mips_hi16_list) { - if (hi->input_section == input_section) + hip = &tdata->mips_hi16_list; + while ((hi = *hip) != NULL) { - *hip = hi->next; - free (hi); + if (hi->input_section == input_section) + { + *hip = hi->next; + free (hi); + } + else + hip = &hi->next; } - else - hip = &hi->next; } if (orig_data == NULL) free (data); -- Alan Modra Australia Development Lab, IBM