Bug 20037 - GDB use-after-free error
Summary: GDB use-after-free error
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: python (show other bugs)
Version: 7.11
: P2 normal
Target Milestone: 7.11.1
Assignee: Pedro Alves
URL:
Keywords:
: 18207 18948 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-05-03 06:49 UTC by Ian Mallett
Modified: 2016-05-24 15:44 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Mallett 2016-05-03 06:49:53 UTC
GDB appears to have a use-after-free error.  This was detected with libasan.  Consider the call:

LD_PRELOAD=libasan.so.2 gdb gdb

On an ARM-based test machine, it produces:



=================================================================
==11973==ERROR: AddressSanitizer: heap-use-after-free on address 0x72d03f40 at pc 0x76a2079b bp 0x7ef47150 sp 0x7ef4715c
READ of size 2 at 0x72d03f40 thread T0
    #0 0x76a20799  (/usr/lib/arm-linux-gnueabihf/libasan.so.2+0x42799)

0x72d03f40 is located 0 bytes inside of 181-byte region [0x72d03f40,0x72d03ff5)
freed by thread T0 here:
    #0 0x76a5317d in free (/usr/lib/arm-linux-gnueabihf/libasan.so.2+0x7517d)
    #1 0x3673ef  (/usr/bin/gdb+0x3673ef)

previously allocated by thread T0 here:
    #0 0x76a53393 in malloc (/usr/lib/arm-linux-gnueabihf/libasan.so.2+0x75393)
    #1 0x3673ef  (/usr/bin/gdb+0x3673ef)

SUMMARY: AddressSanitizer: heap-use-after-free ??:0 ??
Shadow bytes around the buggy address:
  0x2e5a0790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05
  0x2e5a07a0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x2e5a07b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06
  0x2e5a07c0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x2e5a07d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05
=>0x2e5a07e0: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
  0x2e5a07f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x2e5a0800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x2e5a0810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x2e5a0820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x2e5a0830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==11973==ABORTING



In an x86-64 VM, it produces:



=================================================================
==10105==ERROR: AddressSanitizer: heap-use-after-free on address 0x610000007e40 at pc 0x7f5ad3ec8205 bp 0x7ffd7f753a30 sp 0x7ffd7f7531d8
READ of size 2 at 0x610000007e40 thread T0
    #0 0x7f5ad3ec8204  (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x51204)
    #1 0x502bb5 in _initialize_python (/usr/bin/gdb+0x502bb5)
    #2 0x6df82f in initialize_all_files (/usr/bin/gdb+0x6df82f)
    #3 0x69ee3c in gdb_init (/usr/bin/gdb+0x69ee3c)
    #4 0x5cd734  (/usr/bin/gdb+0x5cd734)
    #5 0x5c9d0c in catch_errors (/usr/bin/gdb+0x5c9d0c)
    #6 0x5ce3ba in gdb_main (/usr/bin/gdb+0x5ce3ba)
    #7 0x45ec74 in main (/usr/bin/gdb+0x45ec74)
    #8 0x7f5ad1be082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #9 0x45ecb8 in _start (/usr/bin/gdb+0x45ecb8)

0x610000007e40 is located 0 bytes inside of 181-byte region [0x610000007e40,0x610000007ef5)
freed by thread T0 here:
    #0 0x7f5ad3f0f24a in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9824a)
    #1 0x7f5ad1beb3e5 in setlocale (/lib/x86_64-linux-gnu/libc.so.6+0x2b3e5)

previously allocated by thread T0 here:
    #0 0x7f5ad3f0f54a in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9854a)
    #1 0x7f5ad1beaa9d  (/lib/x86_64-linux-gnu/libc.so.6+0x2aa9d)

SUMMARY: AddressSanitizer: heap-use-after-free ??:0 ??
Shadow bytes around the buggy address:
  0x0c207fff8f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05
  0x0c207fff8f80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c207fff8f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06
  0x0c207fff8fa0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c207fff8fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05
=>0x0c207fff8fc0: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
  0x0c207fff8fd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0c207fff8fe0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c207fff8ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c207fff9000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c207fff9010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==10105==ABORTING
Comment 1 Pedro Alves 2016-05-03 08:57:19 UTC
I guess you're using Python3.  I have a patch for a use-after-free in:

    #1 0x502bb5 in _initialize_python (/usr/bin/gdb+0x502bb5)

that I had noticed with Valgrind.

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'.
Comment 2 Sourceware Commits 2016-05-03 11:17:45 UTC
The master branch has been updated by Pedro Alves <palves@sourceware.org>:

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.
Comment 3 Sourceware Commits 2016-05-03 11:19:57 UTC
The gdb-7.11-branch branch has been updated by Pedro Alves <palves@sourceware.org>:

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

commit 329dec6fc5f2efa83d626583135081b53abe8729
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.
Comment 4 Pedro Alves 2016-05-03 11:22:44 UTC
Should be fixed now, master and 7.11.1.
Comment 5 Ilya Yu. Malakhov 2016-05-06 20:51:09 UTC
*** Bug 18207 has been marked as a duplicate of this bug. ***
Comment 6 Tom Tromey 2016-05-24 15:44:05 UTC
*** Bug 18948 has been marked as a duplicate of this bug. ***