From: Andrew Burgess Date: Thu, 28 Apr 2022 10:37:51 +0000 (+0100) Subject: gdb: fix nullptr dereference in block::ranges() X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c42dd30d73ec441ed9cab207597c7f5ce88ee231;p=binutils-gdb.git gdb: fix nullptr dereference in block::ranges() This commit: commit f5cb8afdd297dd68273d98a10fbfd350dff918d8 Date: Sun Feb 6 22:27:53 2022 -0500 gdb: remove BLOCK_RANGES macro introduces a potential nullptr dereference in block::ranges, this is breaking most tests, e.g. gdb.base/break.exp is failing for me. In the above patch BLOCK_CONTIGUOUS_P is changed from this: #define BLOCK_CONTIGUOUS_P(bl) (BLOCK_RANGES (bl) == nullptr \ || BLOCK_NRANGES (bl) <= 1) to this: #define BLOCK_CONTIGUOUS_P(bl) ((bl)->ranges ().size () == 0 \ || (bl)->ranges ().size () == 1) So, before the commit we checked for the block ranges being nullptr, but afterwards we just call block::ranges() in all cases. The problem is that block::ranges() looks like this: /* Return a view on this block's ranges. */ gdb::array_view ranges () { return gdb::make_array_view (m_ranges->range, m_ranges->nranges); } where m_ranges is: struct blockranges *m_ranges; And so, we see that the nullptr check has been lost, and we might end up dereferencing a nullptr. My proposed fix is to move the nullptr check into block::ranges, and return an explicit empty array_view if m_ranges is nullptr. After this, everything seems fine again. --- 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 /* 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 == nullptr) + return {}; + else + return gdb::make_array_view (m_ranges->range, m_ranges->nranges); + } /* Const version of the above. */ gdb::array_view ranges () const - { return gdb::make_array_view (m_ranges->range, m_ranges->nranges); } + { + if (m_ranges == nullptr) + return {}; + else + return gdb::make_array_view (m_ranges->range, m_ranges->nranges); + } /* Set this block's ranges array. */ void set_ranges (blockranges *ranges)