Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Matthew Malcomson <hardenedapple@gmail.com>
To: Simon Marchi <simon.marchi@polymtl.ca>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH] fix bug with command `printf "%s\n", $_as_string($pc)`
Date: Sun, 26 Feb 2017 13:20:00 -0000	[thread overview]
Message-ID: <8e018305-1691-1049-412f-7f668075bfd1@gmail.com> (raw)
In-Reply-To: <2da82ddc637e4d9fb61ee5b446a94c57@polymtl.ca>

[-- Attachment #1: Type: text/plain, Size: 2030 bytes --]

I've attached the patch with correct formatting because my email client 
replaces tabs with spaces. I'll leave the changelog entries as you 
suggested.

Thanks again,
Matthew

> Just make sure to put each change in the relevant ChangeLog, the one 
> "closest" to the change in the directory structure.  For example, for 
> you change, I would do:
>
> gdb/ChangeLog:
>
>     * python/py-value.c (convert_value_from_python): Consider terminating
>     NULL byte in string length.
>
> gdb/doc/ChangeLog:
>
>     * gdb.texinfo (Convenience Variables for Tracepoints): Mention that
>     trace_func should not be used with output and not printf.
>
> gdb/testsuite/ChangeLog:
>
>     * gdb.python/py-as-string.c (malloc): New function.
>     * gdb.python/py-as-string.exp (test_as_string): Test $_as_string on
>     a string with printf.
>     * gdb.python/py-mi.exp: Adjust array length.
>
>>> IIUC, the goal of overriding malloc is to ensure that the memory 
>>> return by malloc is not all zeroes, which would potentially hide the 
>>> bug?  If that's right, you could instead write a wrapper for malloc 
>>> instead of a replacement.  The wrapper would memset the allocated 
>>> buffer to 'x'es, for example.  This way, it will be safer in case 
>>> there are many calls to malloc or calls with size > 51.
>>>
>>> See option #2 of this answer: http://stackoverflow.com/a/262481
>>
>> Yes, that was the reason. I used this way because I read that gdb also
>> worked on non-POSIX systems (windows especially) and thought having a
>> working test on all systems would be preferred (though I didn't check
>> that all systems support the testing framework).
>> I believe that no other calls to malloc are made in the inferior for
>> this test, and that this program isn't used anywhere else, so this
>> limit of 51 bytes is never hit.
>> I agree this is a bug waiting to happen, so I can accept if the
>> alternate would be preferred, but I thought I'd mention my reasoning.
>
> That's a good justification too, I'm ok with either.
>
>


[-- Attachment #2: formatted_patch.patch --]
[-- Type: text/x-patch, Size: 4031 bytes --]

commit 28312c70fcba81ef50a93ff52dde47230efc35cb
Author: Matthew Malcomson <hardenedapple@gmail.com>
Date:   Sun Feb 26 13:10:09 2017 +0000

    convert_value_from_python include terminating NULL
    
    When converting python strings to internal gdb Value strings, the NULL
    byte was initially left out, this can result in extra data from the
    inferior being printed when the resulting value is used with
    printf "%s\n", value

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 962325be3a..486b7899fb 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -13645,8 +13645,8 @@ The source file for the current trace snapshot.
 The name of the function containing @code{$tracepoint}.
 @end table
 
-Note: @code{$trace_file} is not suitable for use in @code{printf},
-use @code{output} instead.
+Note: @code{$trace_file} and @code{$trace_file} are not suitable for use in
+@code{printf}, use @code{output} instead.
 
 Here's a simple example of using these convenience variables for
 stepping through all the trace snapshots and printing some of their
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index eb3d307b19..c786f68865 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1615,7 +1615,7 @@ convert_value_from_python (PyObject *obj)
 	  gdb::unique_xmalloc_ptr<char> s
 	    = python_string_to_target_string (obj);
 	  if (s != NULL)
-	    value = value_cstring (s.get (), strlen (s.get ()),
+	    value = value_cstring (s.get (), strlen (s.get ()) + 1,
 				   builtin_type_pychar);
 	}
       else if (PyObject_TypeCheck (obj, &value_object_type))
diff --git a/gdb/testsuite/gdb.python/py-as-string.c b/gdb/testsuite/gdb.python/py-as-string.c
index de2e8a1951..e53f3a9b64 100644
--- a/gdb/testsuite/gdb.python/py-as-string.c
+++ b/gdb/testsuite/gdb.python/py-as-string.c
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <stddef.h>
+
 enum EnumType {
   ENUM_VALUE_A,
   ENUM_VALUE_B,
@@ -22,6 +24,20 @@ enum EnumType {
   ENUM_VALUE_D,
 };
 
+static char arena[51] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+
+/* Override malloc() so value_coerce_to_target() gets a known pointer, and we
+   know we'll see an error if $_as_string() returns a string that isn't NULL
+   terminated. */
+void
+*malloc (size_t size)
+{
+  if (size > sizeof (arena))
+    return NULL;
+
+  return arena;
+}
+
 static enum EnumType enum_valid = ENUM_VALUE_B;
 static enum EnumType enum_invalid = 20;
 
diff --git a/gdb/testsuite/gdb.python/py-as-string.exp b/gdb/testsuite/gdb.python/py-as-string.exp
index 0c44d5f174..e4625631c2 100644
--- a/gdb/testsuite/gdb.python/py-as-string.exp
+++ b/gdb/testsuite/gdb.python/py-as-string.exp
@@ -35,6 +35,13 @@ proc test_as_string { } {
     gdb_test "p \$_as_string(2)" "\"2\""
     gdb_test "p \$_as_string(enum_valid)" "\"ENUM_VALUE_B\""
     gdb_test "p \$_as_string(enum_invalid)" "\"20\""
+
+    # Test that the NULL character is included in the returned value.
+    gdb_test "printf \"%s\\n\", \$_as_string(\"hi\")" "\"hi\""
+    # Quote once to define the string, and once for the regexp.
+    gdb_test "interpreter-exec mi '-var-create test * \$_as_string(\"Hello\")'" \
+	"\\^done,name=\"test\",numchild=\"8\",value=\"\\\[8]\",type=\"char \\\[8]\",has_more=\"0\""
+    gdb_test "interpreter-exec mi '-var-delete test'" "\\^done,ndeleted=\"1\""
 }
 
 test_as_string
diff --git a/gdb/testsuite/gdb.python/py-mi.exp b/gdb/testsuite/gdb.python/py-mi.exp
index 736dc7a0d6..a5ad3f0f44 100644
--- a/gdb/testsuite/gdb.python/py-mi.exp
+++ b/gdb/testsuite/gdb.python/py-mi.exp
@@ -281,7 +281,7 @@ mi_create_dynamic_varobj nstype2 nstype2 1 \
   "create nstype2 varobj"
 
 mi_list_varobj_children nstype2 {
-    { {nstype2.<error at 0>} {<error at 0>} 6 {char \[6\]} }
+    { {nstype2.<error at 0>} {<error at 0>} 7 {char \[7\]} }
 } "list children after setting exception flag"
 
 mi_create_varobj me me \

  reply	other threads:[~2017-02-26 13:20 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-19 17:32 Matthew Malcomson
2017-02-20 18:20 ` Simon Marchi
2017-02-25 11:45   ` Matthew Malcomson
2017-02-25 18:33     ` Simon Marchi
2017-02-25 19:11       ` Matthew Malcomson
2017-02-25 21:33         ` Simon Marchi
2017-02-26 13:20           ` Matthew Malcomson [this message]
2017-02-26 14:44             ` Simon Marchi

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=8e018305-1691-1049-412f-7f668075bfd1@gmail.com \
    --to=hardenedapple@gmail.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@polymtl.ca \
    /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