Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jeremy Bennett <jeremy.bennett@embecosm.com>
To: gdb-patches@sourceware.org
Subject: [PATCH PR gdb/15236] gdbserver write to linux memory with zero length corrupts stack
Date: Wed, 06 Mar 2013 18:04:00 -0000	[thread overview]
Message-ID: <1362593035.2235.57.camel@laria> (raw)

PROBLEM:

The function linux_write_memory () in linux-low.c allocates a buffer on
the stack to hold a copy of the data to be written.

  register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *)
    alloca (count * sizeof (PTRACE_XFER_TYPE));

"count" is the number of bytes to be written, rounded up to the nearest
multiple of sizeof (PTRACE_XFER_TYPE) and allowing for not being an
aligned address. The function later uses 

  buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
                      (PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);

The problem is that this function can be called to write zero bytes on
an aligned address, for example when receiving an X packet of length 0
(used to test if 8-bit write is supported). Under these circumstances,
count can be zero.

Since in this case, buffer[0] may never have been allocated, the stack
is corrupted and gdbserver may crash.

Demonstrated with the port of GDB 7.5.1 for the Synopsys
arc-linux-uclibc- target, currently under development at:

        https://github.com/foss-for-synopsys-dwc-arc-processors/gdb

(to be submitted to the FSF in due course).

SOLUTION:

Writing zero bytes should always succeed. The patch below returns
successfully early if the length is zero, so avoiding the stack
corruption.

Verified on the ARC GDB 7.5.1 port.

CHANGELOG ENTRY:

2013-03-06  Jeremy Bennett  <jeremy.bennett@embecosm.com> 

	PR gdb/15236
	* linux-low.c (linux_write_memory): Return early success if len is
	zero.

PATCH:

I'm working from a git mirror and have produced this using git diff.
Advice on how to do this properly appreciated!

diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 7b79cd1..450e2db 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,9 @@
+2013-03-06  Jeremy Bennett  <jeremy.bennett@embecosm.com>
+
+	PR gdb/15236
+	* linux-low.c (linux_write_memory): Return early success if len is
+	zero.
+
 2012-04-29  Yao Qi  <yao@codesourcery.com>
 
 	* server.h: Move some code to ...
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index bbb0693..8e576bd 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -4421,7 +4421,14 @@ linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 
 /* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
    memory at MEMADDR.  On failure (cannot write to the inferior)
-   returns the value of errno.  */
+   returns the value of errno.
+
+   6-Mar-13, Jeremy Bennett: [PR gdb/15236] This function can be called with
+   length 0 (for example with a zero length X packet). If memaddr is aligned
+   to sizeof (PTRACE_XFER_TYPE), then count will be zero and nothing may be
+   allocated for buffer (architecture dependent). The function must return
+   early in this circumstance, to avoid stack corruption when assigning
+   to buffer[0]. */
 
 static int
 linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
@@ -4440,6 +4447,10 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 
   int pid = lwpid_of (get_thread_lwp (current_inferior));
 
+  if (0 == len) {
+    return 0;			/* Zero length write always succeeds. */
+  }
+
   if (debug_threads)
     {
       /* Dump up to four bytes.  */


Best wishes,

Jeremy

-- 
Tel:      +44 (1590) 610184
Cell:     +44 (7970) 676050
SkypeID: jeremybennett
Email:   jeremy.bennett@embecosm.com
Web:     www.embecosm.com


             reply	other threads:[~2013-03-06 18:04 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-06 18:04 Jeremy Bennett [this message]
2013-03-06 19:07 ` Pedro Alves
2013-03-07  8:52   ` Jeremy Bennett
2013-03-07  9:07     ` Yao Qi
2013-03-07  9:13       ` Jeremy Bennett
2013-03-07  9:56         ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1362593035.2235.57.camel@laria \
    --to=jeremy.bennett@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox