gdb: fix nullptr dereference in block::ranges()
authorAndrew Burgess <aburgess@redhat.com>
Thu, 28 Apr 2022 10:37:51 +0000 (11:37 +0100)
committerAndrew Burgess <aburgess@redhat.com>
Thu, 28 Apr 2022 14:09:50 +0000 (15:09 +0100)
commitc42dd30d73ec441ed9cab207597c7f5ce88ee231
tree226451dbeee4300742b09e95452a4158d3f3d84f
parentd942d8db12adf4c9e5c7d9ed6496a779ece7149e
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<blockrange> 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.
gdb/block.h