From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1062) id 05D813858D33; Fri, 17 Feb 2023 03:07:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 05D813858D33 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Alan Modra To: bfd-cvs@sourceware.org Subject: [binutils-gdb] Wild pointer reads in _bfd_ecoff_locate_line X-Act-Checkin: binutils-gdb X-Git-Author: Alan Modra X-Git-Refname: refs/heads/master X-Git-Oldrev: 999835294779e92ffb1511c20ac37cea4f3a1b4e X-Git-Newrev: 75092c693dc1325d222d25e0eb3ac7e24b2f16ad Message-Id: <20230217030719.05D813858D33@sourceware.org> Date: Fri, 17 Feb 2023 03:07:19 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Feb 2023 03:07:19 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D75092c693dc1= 325d222d25e0eb3ac7e24b2f16ad commit 75092c693dc1325d222d25e0eb3ac7e24b2f16ad Author: Alan Modra Date: Fri Feb 17 12:26:13 2023 +1030 Wild pointer reads in _bfd_ecoff_locate_line =20 * ecofflink.c (mk_fdrtab): Sanity check fdr procedure descriptor pointer and isymBase. Set fdrtab_len after possible discards. Use size_t vars and catch possible size overflows. Diff: --- bfd/ecofflink.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c index 3521dc8c4d6..e902bd51d53 100644 --- a/bfd/ecofflink.c +++ b/bfd/ecofflink.c @@ -1730,8 +1730,8 @@ mk_fdrtab (bfd *abfd, FDR *fdr_start; FDR *fdr_end; bool stabs; - long len; - bfd_size_type amt; + size_t len; + size_t amt; =20 fdr_start =3D debug_info->fdr; fdr_end =3D fdr_start + debug_info->symbolic_header.ifdMax; @@ -1739,17 +1739,26 @@ mk_fdrtab (bfd *abfd, /* First, let's see how long the table needs to be. */ for (len =3D 0, fdr_ptr =3D fdr_start; fdr_ptr < fdr_end; fdr_ptr++) { - if (fdr_ptr->cpd =3D=3D 0) /* Skip FDRs that have no PDRs. */ + /* Sanity check fdr procedure descriptor pointer. */ + long ipdMax =3D debug_info->symbolic_header.ipdMax; + if (fdr_ptr->ipdFirst >=3D ipdMax + || fdr_ptr->cpd > ipdMax - fdr_ptr->ipdFirst) + fdr_ptr->cpd =3D 0; + /* Skip FDRs that have no PDRs. */ + if (fdr_ptr->cpd =3D=3D 0) continue; ++len; } =20 /* Now, create and fill in the table. */ - amt =3D (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry); + if (_bfd_mul_overflow (len, sizeof (struct ecoff_fdrtab_entry), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return false; + } line_info->fdrtab =3D (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt= ); if (line_info->fdrtab =3D=3D NULL) return false; - line_info->fdrtab_len =3D len; =20 tab =3D line_info->fdrtab; for (fdr_ptr =3D fdr_start; fdr_ptr < fdr_end; fdr_ptr++) @@ -1766,6 +1775,10 @@ mk_fdrtab (bfd *abfd, char *sym_ptr; SYMR sym; =20 + if ((long) ((unsigned long) fdr_ptr->isymBase + 1) <=3D 0 + || fdr_ptr->isymBase + 1 >=3D debug_info->symbolic_header.isymMax) + continue; + sym_ptr =3D ((char *) debug_info->external_sym + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size); (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym); @@ -1797,12 +1810,14 @@ mk_fdrtab (bfd *abfd, tab->fdr =3D fdr_ptr; ++tab; } + len =3D tab - line_info->fdrtab; + line_info->fdrtab_len =3D len; =20 /* Finally, the table is sorted in increasing memory-address order. The table is mostly sorted already, but there are cases (e.g., static functions in include files), where this does not hold. Use "odump -PFv" to verify... */ - qsort (line_info->fdrtab, (size_t) len, + qsort (line_info->fdrtab, len, sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry); =20 return true;