compiling pidgin causes python to read freed memory

dequis dx at dxzone.com.ar
Fri Apr 14 15:16:30 EDT 2017


Ack. Not security sensitive. Should only affect finch, but if it does
somehow affect pidgin that's another bug

libgnt is using Py_SetProgramName incorrectly, passing a useless
value. It should be passing argv[0] or, for python3, a decoded version
of it.

It appears to be optional and used to determine other parameters (in a
fairly convoluted way), and the default value (python) is better at
determining those values than what we're currently passing. For
example, sys.executable is an empty string with program name set to
'gnt', but it's /usr/bin/python3 without setting it.

https://docs.python.org/3/c-api/init.html#c.Py_SetProgramName

Here's my suggested patch, just nuking the whole thing.

diff --git a/finch/libgnt/gntwm.c b/finch/libgnt/gntwm.c
index 310d6c621..b92fb45df 100644
--- a/finch/libgnt/gntwm.c
+++ b/finch/libgnt/gntwm.c
@@ -1581,17 +1581,6 @@ gnt_wm_class_init(GntWMClass *klass)
     gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass),
"run-python", run_python,
                 GNT_KEY_F3, NULL);
     if (!Py_IsInitialized()) {
-#if PY_MAJOR_VERSION >= 3
-        wchar_t *name;
-        size_t len;
-        len = mbstowcs(NULL, "gnt", 0);
-        name = g_new(wchar_t, len + 1);
-        mbstowcs(name, "gnt", len + 1);
-        Py_SetProgramName(name);
-        g_free(name);
-#else
-        Py_SetProgramName("gnt");
-#endif
         Py_Initialize();
         started_python = TRUE;
     }



The alternatives are letting it leak, assigning the pointer to a
static buffer, having a static buffer with size FILENAME_MAX, etc, but
all of them require gnt to get access to argv[0] somehow because
setting "gnt" is just making things worse, not improving anything.

On 14 April 2017 at 14:02, Joseph Bisch <joseph.bisch at gmail.com> wrote:
> Hi again,
>
> When compiling Pidgin with a Python 3 compiled with ASan, ASan detects
> a use after free. Specifically, Python is reading from memory that Gnt
> had prematurely freed.
>
> Analysis:
>
> My guess is that the issue is caused by freeing the name variable
> immediately after Py_SetProgramName() is called. Later, ASan triggers
> on the Py_Initialize() call.
>
> https://bitbucket.org/pidgin/main/src/107c6c2342ffd03ad2eae7a838f6b01adcf49291/finch/libgnt/gntwm.c?at=default&fileviewer=file-view-default#gntwm.c-1582
>
> Note that the Python documentation for the Py_SetProgramName()
> function explicitly states that the contents of the argument should
> not change for the duration of the program's execution.
>
> Joseph
>
> ASan output:
>
> =================================================================
> ==27341==ERROR: AddressSanitizer: heap-use-after-free on address
> 0x60200001fd70 at pc 0x000000447f71 bp 0x7ffe72c11d20 sp
> 0x7ffe72c114d0
> READ of size 16 at 0x60200001fd70 thread T0
>     #0 0x447f70 in __interceptor_wcslen
> /home/joseph/aur/llvm-svn/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:591
>     #1 0x7fedc4c65bed  (/usr/lib/libpython3.6m.so.1.0+0x224bed)
>     #2 0x7fedc4c66739  (/usr/lib/libpython3.6m.so.1.0+0x225739)
>     #3 0x7fedc4c67000 in Py_GetProgramFullPath
> (/usr/lib/libpython3.6m.so.1.0+0x226000)
>     #4 0x7fedc4c64826 in _PySys_Init (/usr/lib/libpython3.6m.so.1.0+0x223826)
>     #5 0x7fedc4c31150 in _Py_InitializeEx_Private
> (/usr/lib/libpython3.6m.so.1.0+0x1f0150)
>     #6 0x7fedc5c5ec65 in gnt_wm_class_init
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/gntwm.c:1587:3
>     #7 0x7fedc34eb4d6 in g_type_class_ref (/usr/lib/libgobject-2.0.so.0+0x304d6)
>     #8 0x50b781 in dump_properties
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/Gnt-2.9.c:137:15
>     #9 0x50aab7 in dump_object_type
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/Gnt-2.9.c:260:3
>     #10 0x50aab7 in dump_type
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/Gnt-2.9.c:402
>     #11 0x50aab7 in dump_irepository
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/Gnt-2.9.c:547
>     #12 0x50aab7 in main
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/Gnt-2.9.c:610
>     #13 0x7fedc2801510 in __libc_start_main (/usr/lib/libc.so.6+0x20510)
>     #14 0x41a8c9 in _start
> (/home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/.libs/lt-Gnt-2.9+0x41a8c9)
>
> 0x60200001fd70 is located 0 bytes inside of 16-byte region
> [0x60200001fd70,0x60200001fd80)
> freed by thread T0 here:
>     #0 0x4d0af0 in __interceptor_cfree.localalias.1
> /home/joseph/aur/llvm-svn/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:54
>     #1 0x7fedc5c5ec60 in gnt_wm_class_init
> /home/joseph/pidgin-fuzz/main2/finch/libgnt/gntwm.c:1583:3
>     #2 0x7fedc34eb4d6 in g_type_class_ref (/usr/lib/libgobject-2.0.so.0+0x304d6)
>
> previously allocated by thread T0 here:
>     #0 0x4d0ca8 in __interceptor_malloc
> /home/joseph/aur/llvm-svn/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
>     #1 0x7fedc2ff3bb8 in g_malloc (/usr/lib/libglib-2.0.so.0+0x4fbb8)
>     #2 0x7fedc34eb4d6 in g_type_class_ref (/usr/lib/libgobject-2.0.so.0+0x304d6)
>
> SUMMARY: AddressSanitizer: heap-use-after-free
> /home/joseph/aur/llvm-svn/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors.cc:591
> in __interceptor_wcslen
> Shadow bytes around the buggy address:
>   0x0c047fffbf50: fa fa 00 00 fa fa 00 04 fa fa 00 04 fa fa 00 00
>   0x0c047fffbf60: fa fa 03 fa fa fa 00 00 fa fa 00 00 fa fa 00 00
>   0x0c047fffbf70: fa fa 00 00 fa fa 03 fa fa fa 00 00 fa fa 00 00
>   0x0c047fffbf80: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 03 fa
>   0x0c047fffbf90: fa fa 00 00 fa fa 00 00 fa fa 03 fa fa fa 00 00
> =>0x0c047fffbfa0: fa fa 00 00 fa fa 00 03 fa fa 00 03 fa fa[fd]fd
>   0x0c047fffbfb0: fa fa fd fa fa fa 00 04 fa fa 00 04 fa fa 00 00
>   0x0c047fffbfc0: fa fa 00 01 fa fa 00 01 fa fa 00 00 fa fa 00 fa
>   0x0c047fffbfd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x0c047fffbfe0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x0c047fffbff0: 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
>   Freed heap region:       fd
>   Stack left redzone:      f1
>   Stack mid redzone:       f2
>   Stack right redzone:     f3
>   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
>   Left alloca redzone:     ca
>   Right alloca redzone:    cb
> ==27341==ABORTING
> Command '['/home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/Gnt-2.9',
> '--introspect-dump=/home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/functions.txt,/home/joseph/pidgin-fuzz/main2/finch/libgnt/tmp-introspectwzbhauez/dump.xml']'
> returned non-zero exit status 1.
> make[5]: *** [/usr/share/gobject-introspection-1.0/Makefile.introspection:156:
> Gnt-2.9.gir] Error 1
> _______________________________________________
> security mailing list
> security at pidgin.im
> https://pidgin.im/cgi-bin/mailman/listinfo/security


More information about the security mailing list