From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1726) id 6C3CE3856DE8; Thu, 28 Apr 2022 14:10:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6C3CE3856DE8 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Andrew Burgess To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb: fix nullptr dereference in block::ranges() X-Act-Checkin: binutils-gdb X-Git-Author: Andrew Burgess X-Git-Refname: refs/heads/master X-Git-Oldrev: d942d8db12adf4c9e5c7d9ed6496a779ece7149e X-Git-Newrev: c42dd30d73ec441ed9cab207597c7f5ce88ee231 Message-Id: <20220428141003.6C3CE3856DE8@sourceware.org> Date: Thu, 28 Apr 2022 14:10:03 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Apr 2022 14:10:03 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dc42dd30d73ec= 441ed9cab207597c7f5ce88ee231 commit c42dd30d73ec441ed9cab207597c7f5ce88ee231 Author: Andrew Burgess Date: Thu Apr 28 11:37:51 2022 +0100 gdb: fix nullptr dereference in block::ranges() =20 This commit: =20 commit f5cb8afdd297dd68273d98a10fbfd350dff918d8 Date: Sun Feb 6 22:27:53 2022 -0500 =20 gdb: remove BLOCK_RANGES macro =20 introduces a potential nullptr dereference in block::ranges, this is breaking most tests, e.g. gdb.base/break.exp is failing for me. =20 In the above patch BLOCK_CONTIGUOUS_P is changed from this: =20 #define BLOCK_CONTIGUOUS_P(bl) (BLOCK_RANGES (bl) =3D=3D nullptr \ || BLOCK_NRANGES (bl) <=3D 1) =20 to this: =20 #define BLOCK_CONTIGUOUS_P(bl) ((bl)->ranges ().size () =3D=3D 0 \ || (bl)->ranges ().size () =3D=3D 1) =20 So, before the commit we checked for the block ranges being nullptr, but afterwards we just call block::ranges() in all cases. =20 The problem is that block::ranges() looks like this: =20 /* Return a view on this block's ranges. */ gdb::array_view ranges () { return gdb::make_array_view (m_ranges->range, m_ranges->nranges); } =20 where m_ranges is: =20 struct blockranges *m_ranges; =20 And so, we see that the nullptr check has been lost, and we might end up dereferencing a nullptr. =20 My proposed fix is to move the nullptr check into block::ranges, and return an explicit empty array_view if m_ranges is nullptr. =20 After this, everything seems fine again. Diff: --- gdb/block.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gdb/block.h b/gdb/block.h index b9f4e974c04..038ce7bd2f3 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -157,11 +157,21 @@ struct block =20 /* Return a view on this block's ranges. */ gdb::array_view ranges () - { return gdb::make_array_view (m_ranges->range, m_ranges->nranges); } + { + if (m_ranges =3D=3D nullptr) + return {}; + else + return gdb::make_array_view (m_ranges->range, m_ranges->nranges); + } =20 /* Const version of the above. */ gdb::array_view ranges () const - { return gdb::make_array_view (m_ranges->range, m_ranges->nranges); } + { + if (m_ranges =3D=3D nullptr) + return {}; + else + return gdb::make_array_view (m_ranges->range, m_ranges->nranges); + } =20 /* Set this block's ranges array. */ void set_ranges (blockranges *ranges)