This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix gdb/python/python.c use-after-free


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=86f1abec458df24ea7d4a38a7b3e21861c5b9bd8

commit 86f1abec458df24ea7d4a38a7b3e21861c5b9bd8
Author: Pedro Alves <palves@redhat.com>
Date:   Tue May 3 12:16:56 2016 +0100

    Fix gdb/python/python.c use-after-free
    
    Valgrind shows:
    
     ==26964== Invalid read of size 1
     ==26964==    at 0x6E14100: __GI_strcmp (strcmp.S:180)
     ==26964==    by 0x6DB55AA: setlocale (setlocale.c:238)
     ==26964==    by 0x4E0455: _initialize_python() (python.c:1731)
     ==26964==    by 0x786731: initialize_all_files() (init.c:319)
     ==26964==    by 0x72EF0A: gdb_init(char*) (top.c:1929)
     ==26964==    by 0x60BCAC: captured_main(void*) (main.c:863)
     ==26964==    by 0x606AD5: catch_errors(int (*)(void*), void*, char*, return_mask) (exceptions.c:234)
     ==26964==    by 0x60C608: gdb_main(captured_main_args*) (main.c:1165)
     ==26964==    by 0x40CAEC: main (gdb.c:32)
     ==26964==  Address 0x81d30a0 is 0 bytes inside a block of size 181 free'd
     ==26964==    at 0x4C29CF0: free (vg_replace_malloc.c:530)
     ==26964==    by 0x6DB5B65: setname (setlocale.c:201)
     ==26964==    by 0x6DB5B65: setlocale (setlocale.c:388)
     ==26964==    by 0x4E037F: _initialize_python() (python.c:1712)
     ==26964==    by 0x786731: initialize_all_files() (init.c:319)
     ==26964==    by 0x72EF0A: gdb_init(char*) (top.c:1929)
     ==26964==    by 0x60BCAC: captured_main(void*) (main.c:863)
     ==26964==    by 0x606AD5: catch_errors(int (*)(void*), void*, char*, return_mask) (exceptions.c:234)
     ==26964==    by 0x60C608: gdb_main(captured_main_args*) (main.c:1165)
     ==26964==    by 0x40CAEC: main (gdb.c:32)
    
    The problem is doing this:
    
      oldloc = setlocale (LC_ALL, NULL);
      setlocale (LC_ALL, "");
      ...
      setlocale (LC_ALL, oldloc);
    
    I.e., the second setlocale call frees 'oldloc'.
    
    From http://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html :
    
     "The returned string pointer might be invalidated or the string
     content might be overwritten by a subsequent call to setlocale()."
    
    gdb/ChangeLog:
    2016-05-03  Pedro Alves <palves@redhat.com>
    
    	PR python/20037
    	* python/python.c (_initialize_python) [IS_PY3K]: xstrdup/xfree
    	oldloc.

Diff:
---
 gdb/ChangeLog       | 6 ++++++
 gdb/python/python.c | 5 ++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c5b7325..8627cb7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
 2016-05-03  Pedro Alves <palves@redhat.com>
 
+	PR python/20037
+	* python/python.c (_initialize_python) [IS_PY3K]: xstrdup/xfree
+	oldloc.
+
+2016-05-03  Pedro Alves <palves@redhat.com>
+
 	* python/python.c (_initialize_python) [IS_PY3K]: Remove dead
 	code.
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index ea9cf85..c706644 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1708,22 +1708,25 @@ message == an error message without a stack will be printed."),
   progname = concat (ldirname (python_libdir), SLASH_STRING, "bin",
 		     SLASH_STRING, "python", (char *) NULL);
 #ifdef IS_PY3K
-  oldloc = setlocale (LC_ALL, NULL);
+  oldloc = xstrdup (setlocale (LC_ALL, NULL));
   setlocale (LC_ALL, "");
   progsize = strlen (progname);
   progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
   if (!progname_copy)
     {
+      xfree (oldloc);
       fprintf (stderr, "out of memory\n");
       return;
     }
   count = mbstowcs (progname_copy, progname, progsize + 1);
   if (count == (size_t) -1)
     {
+      xfree (oldloc);
       fprintf (stderr, "Could not convert python path to string\n");
       return;
     }
   setlocale (LC_ALL, oldloc);
+  xfree (oldloc);
 
   /* Note that Py_SetProgramName expects the string it is passed to
      remain alive for the duration of the program's execution, so


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]