Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Check for truncated registers in process_g_packet
@ 2016-10-18 11:10 Lionel Flandrin
  2016-10-18 15:50 ` Simon Marchi
  0 siblings, 1 reply; 20+ messages in thread
From: Lionel Flandrin @ 2016-10-18 11:10 UTC (permalink / raw)
  To: gdb-patches

Hello,

While investigating an unrelated issue in remote.c I noticed that the
bound checking for 'g' packets was bogus:

The previous code would only check that the first byte of the register
was within bounds before passing the buffer to regcache_raw_supply. If
it turned out that the register in the 'g' packet was incomplete then
regcache_raw_supply would proceed to memcpy out-of-bounds.

Since the buffer is allocated with alloca it's relatively unlikely to
crash (you just end up dumping gdb's stack into the cache) but it's
still a bit messy.

I changed this logic to check for truncated registers and raise an
error if one is encountered. Hopefully it should make debugging remote
stubs a bit easier.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4b642b8..73b9b9e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2016-10-18  Lionel Flandrin <lionel@svkt.org>
+
+	* remote.c (process_g_packet): Detect truncated registers in 'g'
+	packets and raise an error. Fixes a potential out-of-bounds buffer
+	access if the remote sent a truncated 'g' packet.
+
 2016-10-18  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* i386-tdep.c (i386_mpx_info_bounds): Make sure the architecture
diff --git a/gdb/remote.c b/gdb/remote.c
index af7508a..5ec5ea6 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -7163,18 +7163,31 @@ process_g_packet (struct regcache *regcache)
      the 'p' packet must be used.  */
   if (buf_len < 2 * rsa->sizeof_g_packet)
     {
-      rsa->sizeof_g_packet = buf_len / 2;
+      long sizeof_g_packet = buf_len / 2;
 
       for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
 	{
+	  long offset = rsa->regs[i].offset;
+	  long reg_size = register_size(gdbarch, i);
+
 	  if (rsa->regs[i].pnum == -1)
 	    continue;
 
-	  if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
+	  if (offset >= sizeof_g_packet)
 	    rsa->regs[i].in_g_packet = 0;
+	  else if (offset + reg_size > sizeof_g_packet)
+	    error (_("Truncated register %d in remote 'g' packet"), i);
 	  else
 	    rsa->regs[i].in_g_packet = 1;
 	}
+
+      /* Looks valid enough, we can assume this is the correct length
+         for a 'g' packet. It's important not to adjust
+         rsa.sizeof_g_packet if we have truncated registers otherwise
+         this "if" won't be run the next time the method is called
+         with a packet of the same size and one of the internal errors
+         below will trigger instead. */
+      rsa->sizeof_g_packet = sizeof_g_packet;
     }
 
   regs = (char *) alloca (rsa->sizeof_g_packet);
@@ -7204,10 +7217,11 @@ process_g_packet (struct regcache *regcache)
   for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
     {
       struct packet_reg *r = &rsa->regs[i];
+      long reg_size = register_size(gdbarch, i);
 
       if (r->in_g_packet)
 	{
-	  if (r->offset * 2 >= strlen (rs->buf))
+	  if ((r->offset + reg_size) * 2 > strlen (rs->buf))
 	    /* This shouldn't happen - we adjusted in_g_packet above.  */
 	    internal_error (__FILE__, __LINE__,
 			    _("unexpected end of 'g' packet reply"));


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-09-05 15:44 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-18 11:10 Check for truncated registers in process_g_packet Lionel Flandrin
2016-10-18 15:50 ` Simon Marchi
2016-10-18 16:07   ` Lionel Flandrin
2016-10-27 15:23     ` Lionel Flandrin
2016-11-08 10:37     ` Pedro Alves
2017-08-25 10:53       ` Yao Qi
2017-08-25 21:05         ` Simon Marchi
2017-08-25 22:55           ` Simon Marchi
2017-08-27 10:16             ` [PATCH 0/4] Try to fix the gdb.multi/multi-arch-exec.exp failure Simon Marchi
2017-08-27 10:16               ` [PATCH 2/4] Read stop_pc after updating the gdbarch when exec'ing Simon Marchi
2017-09-05 10:12                 ` Yao Qi
2017-08-27 10:16               ` [PATCH 4/4] Test different follow-exec-mode settings in gdb.multi/multi-arch-exec.exp Simon Marchi
2017-09-05 10:40                 ` Yao Qi
2017-09-05 15:40                   ` Simon Marchi
2017-08-27 10:16               ` [PATCH 1/4] Improve "'g' reply is is to long" error message Simon Marchi
2017-09-05  9:49                 ` Yao Qi
2017-08-27 10:16               ` [PATCH 3/4] Add thread after updating gdbarch when exec'ing Simon Marchi
2017-09-05 10:37                 ` Yao Qi
2017-09-05 15:30                   ` Simon Marchi
2017-09-05 15:44                     ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox