[Bug threads/19942] AddressSanitizer: heap-use-after-free in thread_apply_all_command

cvs-commit at gcc dot gnu.org sourceware-bugzilla@sourceware.org
Mon Apr 10 13:41:00 GMT 2017


https://sourceware.org/bugzilla/show_bug.cgi?id=19942

--- Comment #1 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Yao Qi <qiyao@sourceware.org>:

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

commit 803bdfe43083475c7df3db38dc96f4e20d05457d
Author: Yao Qi <yao.qi@linaro.org>
Date:   Mon Apr 10 14:39:41 2017 +0100

    Don't delete thread_info if refcount isn't zero

    I build GDB with asan, and run test case hook-stop.exp, and
threadapply.exp,
    I got the following asan error,

    =================================================================^M
    ^[[1m^[[31m==2291==ERROR: AddressSanitizer: heap-use-after-free on address
0x6160000999c4 at pc 0x000000826022 bp 0x7ffd28a8ff70 sp 0x7ffd28a8ff60^M
    ^[[1m^[[0m^[[1m^[[34mREAD of size 4 at 0x6160000999c4 thread T0^[[1m^[[0m^M
        #0 0x826021 in release_stop_context_cleanup
../../binutils-gdb/gdb/infrun.c:8203^M
        #1 0x72798a in do_my_cleanups
../../binutils-gdb/gdb/common/cleanups.c:154^M
        #2 0x727a32 in do_cleanups(cleanup*)
../../binutils-gdb/gdb/common/cleanups.c:176^M
        #3 0x826895 in normal_stop() ../../binutils-gdb/gdb/infrun.c:8381^M
        #4 0x815208 in fetch_inferior_event(void*)
../../binutils-gdb/gdb/infrun.c:4011^M
        #5 0x868aca in inferior_event_handler(inferior_event_type, void*)
../../binutils-gdb/gdb/inf-loop.c:44^M
    ....
    ^[[1m^[[32m0x6160000999c4 is located 68 bytes inside of 568-byte region
[0x616000099980,0x616000099bb8)^M
    ^[[1m^[[0m^[[1m^[[35mfreed by thread T0 here:^[[1m^[[0m^M
        #0 0x7fb0bc1312ca in __interceptor_free
(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)^M
        #1 0xb8c62f in xfree(void*)
../../binutils-gdb/gdb/common/common-utils.c:100^M
        #2 0x83df67 in free_thread ../../binutils-gdb/gdb/thread.c:207^M
        #3 0x83dfd2 in init_thread_list() ../../binutils-gdb/gdb/thread.c:223^M
        #4 0x805494 in kill_command ../../binutils-gdb/gdb/infcmd.c:2595^M
    ....

    Detaching from program:
/home/yao.qi/SourceCode/gnu/build-with-asan/gdb/testsuite/outputs/gdb.threads/threadapply/threadapply,
process 2399^M
    =================================================================^M
    ^[[1m^[[31m==2387==ERROR: AddressSanitizer: heap-use-after-free on address
0x6160000a98c0 at pc 0x00000083fd28 bp 0x7ffd401c3110 sp 0x7ffd401c3100^M
    ^[[1m^[[0m^[[1m^[[34mREAD of size 4 at 0x6160000a98c0 thread T0^[[1m^[[0m^M
        #0 0x83fd27 in thread_alive ../../binutils-gdb/gdb/thread.c:741^M
        #1 0x844277 in thread_apply_all_command
../../binutils-gdb/gdb/thread.c:1804^M
    ....
    ^M
    ^[[1m^[[32m0x6160000a98c0 is located 64 bytes inside of 568-byte region
[0x6160000a9880,0x6160000a9ab8)^M
    ^[[1m^[[0m^[[1m^[[35mfreed by thread T0 here:^[[1m^[[0m^M
        #0 0x7f59a7e322ca in __interceptor_free
(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x982ca)^M
        #1 0xb8c62f in xfree(void*)
../../binutils-gdb/gdb/common/common-utils.c:100^M
        #2 0x83df67 in free_thread ../../binutils-gdb/gdb/thread.c:207^M
        #3 0x83dfd2 in init_thread_list() ../../binutils-gdb/gdb/thread.c:223^M

    This patch fixes the issue by deleting thread_info object if it is
    deletable, otherwise, mark it as exited (by set_thread_exited).
    Function set_thread_exited is shared from delete_thread_1.  This patch
    also moves field "refcount" to private and methods incref and
    decref.  Additionally, we stop using "ptid_t" in
    "struct current_thread_cleanup" to reference threads, instead we use
    "thread_info" directly.  Due to this change, we don't need
    restore_current_thread_ptid_changed anymore.

    gdb:

    2017-04-10  Yao Qi  <yao.qi@linaro.org>

        PR gdb/19942
        * gdbthread.h (thread_info::deletable): New method.
        (thread_info::incref): New method.
        (thread_info::decref): New method.
        (thread_info::refcount): Move it to private.
        * infrun.c (save_stop_context): Call inc_refcount.
        (release_stop_context_cleanup): Likewise.
        * thread.c (set_thread_exited): New function.
        (init_thread_list): Delete "tp" only it is deletable, otherwise
        call set_thread_exited.
        (delete_thread_1): Call set_thread_exited.
        (current_thread_cleanup) <inferior_pid>: Remove.
        <thread>: New field.
        (restore_current_thread_ptid_changed): Removed.
        (do_restore_current_thread_cleanup): Adjust.
        (restore_current_thread_cleanup_dtor): Don't call
        find_thread_ptid.
        (set_thread_refcount): Use dec_refcount.
        (make_cleanup_restore_current_thread): Adjust.
        (thread_apply_all_command): Call inc_refcount.
        (_initialize_thread): Don't call
        observer_attach_thread_ptid_changed.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Gdb-prs mailing list