From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by sourceware.org (Postfix) with ESMTPS id C3AF03856DDE for ; Wed, 15 Jun 2022 04:06:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C3AF03856DDE Received: by mail-pl1-x632.google.com with SMTP id g8so4171733plt.8 for ; Tue, 14 Jun 2022 21:06:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=GYiQbtbbw63aSVn0kVvL4HlUPXmUUb+K20AGLouUyz4=; b=VO1vBUU4Gc0+vCndBoEuA5h4+eHJTbfhaxU9QpT2FCNRe76tK+IIAD2OjfK/eg9VJJ 3PmKbd0E1U7DWpYj66gbX/bI7F9zU3fe+UeGByzZS03KAfWmz7XiqODP/nr4e17O6dqO NAOy9Dyzu0HJvqsso8X4f59x7yEUBum9YcDCvuHR6xKlwy0v1YX0/nynGyKk1r4r8Aee WTJ39GFTt9svj41n6bRkRKi7mdcoUkKLiYhZ0j7qLFSV92RH9Glw9rzfIcMJw8hnFaMq fQNJ5F4YbRI5dV+cCIYuFpr7YApALkdoU6ZVAGXBRGGebjAKU9wGs1FDh02K8ayyfFK7 Lg1g== X-Gm-Message-State: AJIora+pdxMY7+A/H9w4xyoADJ2xB/lqQDF5N4Fzk0zm0BZnkgG6/V99 V4ObgxnIi8x/bKlqVsl1IuoZl+xiX2A= X-Google-Smtp-Source: AGRyM1uMRi3lZT9ZqpRsuoyIrqoJuWwIk+Yv0xI8vqC01sVJn+4DrikL7cb8GCIkI/f8UCP1WFQbOQ== X-Received: by 2002:a17:902:e742:b0:166:4d34:3be8 with SMTP id p2-20020a170902e74200b001664d343be8mr7300492plf.140.1655265986298; Tue, 14 Jun 2022 21:06:26 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:41ae:b30b:70a9:de8f]) by smtp.gmail.com with ESMTPSA id n89-20020a17090a5ae200b001e880972840sm467726pji.29.2022.06.14.21.06.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jun 2022 21:06:25 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 554311140197; Wed, 15 Jun 2022 13:36:22 +0930 (ACST) Date: Wed, 15 Jun 2022 13:36:22 +0930 From: Alan Modra To: binutils@sourceware.org Subject: PR29230, segv in lookup_symbol_in_variable_table Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3036.3 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, 15 Jun 2022 04:06:31 -0000 The PR23230 testcase uses indexed strings without specifying SW_AT_str_offsets_base. In this case we left u.str with garbage (from u.val) which then led to a segfault when attempting to access the string. Fix that by clearing u.str. The patch also adds missing sanity checks in the recently committed read_indexed_address and read_indexed_string functions. PR 29230 * dwarf2.c (read_indexed_address): Return uint64_t. Sanity check idx. (read_indexed_string): Use uint64_t for str_offset. Sanity check idx. (read_attribute_value): Clear u.str for indexed string forms when DW_AT_str_offsets_base is not yet read or missing. diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 51018e1ab45..aaa2d84887f 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -1353,13 +1353,13 @@ is_addrx_form (enum dwarf_form form) /* Returns the address in .debug_addr section using DW_AT_addr_base. Used to implement DW_FORM_addrx*. */ -static bfd_vma +static uint64_t read_indexed_address (uint64_t idx, struct comp_unit *unit) { struct dwarf2_debug *stash = unit->stash; struct dwarf2_debug_file *file = unit->file; - size_t addr_base = unit->dwarf_addr_offset; bfd_byte *info_ptr; + size_t offset; if (stash == NULL) return 0; @@ -1369,12 +1369,23 @@ read_indexed_address (uint64_t idx, struct comp_unit *unit) &file->dwarf_addr_buffer, &file->dwarf_addr_size)) return 0; - info_ptr = file->dwarf_addr_buffer + addr_base + idx * unit->offset_size; + if (_bfd_mul_overflow (idx, unit->offset_size, &offset)) + return 0; + + offset += unit->dwarf_addr_offset; + if (offset < unit->dwarf_addr_offset + || offset > file->dwarf_addr_size + || file->dwarf_addr_size - offset < unit->offset_size) + return 0; + + info_ptr = file->dwarf_addr_buffer + offset; if (unit->offset_size == 4) return bfd_get_32 (unit->abfd, info_ptr); - else + else if (unit->offset_size == 8) return bfd_get_64 (unit->abfd, info_ptr); + else + return 0; } /* Returns the string using DW_AT_str_offsets_base. @@ -1385,7 +1396,8 @@ read_indexed_string (uint64_t idx, struct comp_unit *unit) struct dwarf2_debug *stash = unit->stash; struct dwarf2_debug_file *file = unit->file; bfd_byte *info_ptr; - unsigned long str_offset; + uint64_t str_offset; + size_t offset; if (stash == NULL) return NULL; @@ -1401,15 +1413,26 @@ read_indexed_string (uint64_t idx, struct comp_unit *unit) &file->dwarf_str_offsets_size)) return NULL; - info_ptr = (file->dwarf_str_offsets_buffer - + unit->dwarf_str_offset - + idx * unit->offset_size); + if (_bfd_mul_overflow (idx, unit->offset_size, &offset)) + return NULL; + + offset += unit->dwarf_str_offset; + if (offset < unit->dwarf_str_offset + || offset > file->dwarf_str_offsets_size + || file->dwarf_str_offsets_size - offset < unit->offset_size) + return NULL; + + info_ptr = file->dwarf_str_offsets_buffer + offset; if (unit->offset_size == 4) str_offset = bfd_get_32 (unit->abfd, info_ptr); - else + else if (unit->offset_size == 8) str_offset = bfd_get_64 (unit->abfd, info_ptr); + else + return NULL; + if (str_offset >= file->dwarf_str_size) + return NULL; return (const char *) file->dwarf_str_buffer + str_offset; } @@ -1534,27 +1557,37 @@ read_attribute_value (struct attribute * attr, is not yet read. */ if (unit->dwarf_str_offset != 0) attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + else + attr->u.str = NULL; break; case DW_FORM_strx2: attr->u.val = read_2_bytes (abfd, &info_ptr, info_ptr_end); if (unit->dwarf_str_offset != 0) attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + else + attr->u.str = NULL; break; case DW_FORM_strx3: attr->u.val = read_3_bytes (abfd, &info_ptr, info_ptr_end); if (unit->dwarf_str_offset != 0) attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + else + attr->u.str = NULL; break; case DW_FORM_strx4: attr->u.val = read_4_bytes (abfd, &info_ptr, info_ptr_end); if (unit->dwarf_str_offset != 0) attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + else + attr->u.str = NULL; break; case DW_FORM_strx: attr->u.val = _bfd_safe_read_leb128 (abfd, &info_ptr, false, info_ptr_end); if (unit->dwarf_str_offset != 0) attr->u.str = (char *) read_indexed_string (attr->u.val, unit); + else + attr->u.str = NULL; break; case DW_FORM_exprloc: case DW_FORM_block: -- Alan Modra Australia Development Lab, IBM