Return TARGET_XFER_EOF if reading at the end of TARGET_OBJECT_SIGNAL_INFO.

Message ID 20190509232425.2243-1-jhb@FreeBSD.org
State New, archived
Headers

Commit Message

John Baldwin May 9, 2019, 11:24 p.m. UTC
  This fixes an assertion failure if a request is made to read just past
the end of a native thread's signal information structure.

gdb/ChangeLog:

	* fbsd-nat.c (fbsd_nat_target::xfer_partial) [USE_SIGINFO]: Return
	TARGET_XFER_EOF if len is zero.
---
 gdb/ChangeLog  | 5 +++++
 gdb/fbsd-nat.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)
  

Comments

Tom Tromey May 10, 2019, 5:40 p.m. UTC | #1
>>>>> "John" == John Baldwin <jhb@FreeBSD.org> writes:

John> This fixes an assertion failure if a request is made to read just past
John> the end of a native thread's signal information structure.

I am curious to know where the assertion happens.

linux-nat.c doesn't seem to return TARGET_XFER_EOF here (see
linux_xfer_siginfo), so I wonder if either linux-nat.c needs a fix, or
if the bug is somewhere else.

Tom
  
John Baldwin May 10, 2019, 7:39 p.m. UTC | #2
On 5/10/19 10:40 AM, Tom Tromey wrote:
>>>>>> "John" == John Baldwin <jhb@FreeBSD.org> writes:
> 
> John> This fixes an assertion failure if a request is made to read just past
> John> the end of a native thread's signal information structure.
> 
> I am curious to know where the assertion happens.
> 
> linux-nat.c doesn't seem to return TARGET_XFER_EOF here (see
> linux_xfer_siginfo), so I wonder if either linux-nat.c needs a fix, or
> if the bug is somewhere else.

I had to try hard to provoke it.  I had a bug in out-of-tree patches to
fbsd-nat.c that resulted in getting the siginfo_size wrong (too small)
compared to the generated type for $_siginfo for the target architecture.
The size mismatch just so happened to result in a field that started on
the byte location of the end of the too-small size and so 'p $_siginfo'
tried to read a field at that exact offset and tripped the assertion at
the bottom of target_xfer_partial:

  /* Check implementations of to_xfer_partial update *XFERED_LEN
     properly.  Do assertion after printing debug messages, so that we
     can find more clues on assertion failure from debugging messages.  */
  if (retval == TARGET_XFER_OK || retval == TARGET_XFER_UNAVAILABLE)
    gdb_assert (*xfered_len > 0);
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5b0a9fde61..de24a26a59 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2019-05-09  John Baldwin  <jhb@FreeBSD.org>
+
+	* fbsd-nat.c (fbsd_nat_target::xfer_partial) [USE_SIGINFO]: Return
+	TARGET_XFER_EOF if len is zero.
+
 2019-05-08  Tom Tromey  <tom@tromey.com>
 
 	* gdbtypes.c (objfile_type_data): Change type.
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index d4f4c8cf35..35188b44fa 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -720,7 +720,7 @@  fbsd_nat_target::xfer_partial (enum target_object object,
 
 	memcpy (readbuf, ((gdb_byte *) &pl.pl_siginfo) + offset, len);
 	*xfered_len = len;
-	return TARGET_XFER_OK;
+	return len == 0 ? TARGET_XFER_EOF : TARGET_XFER_OK;
       }
 #endif
 #ifdef KERN_PROC_AUXV