gisle / tcl.pm

Tcl extension module for Perl
http://search.cpan.org/dist/Tcl
9 stars 8 forks source link

Tcl.xs: actually remove interp from interps hash #45

Closed chrstphrchvz closed 2 years ago

chrstphrchvz commented 2 years ago

Tcl_DESTROY() has never actually deleted interp from hvInterps, due to passing interp instead of &interp to hv_delete(). This allowed the underlying Tcl_Interp to be accessed during Tcl__Finalize() after it was already freed during Tcl_DESTROY(), which AddressSanitizer (-fsanitize=address) detects:

tcl.pm $ perl -Mblib t/info.t
1..6 todo 2;
# Running under perl version 5.034000 for linux
# Current time local: Fri Apr 15 16:23:10 2022
# Current time GMT:   Fri Apr 15 21:23:10 2022
# Using Test.pm version 1.31
ok 1
ok 2 # (t/info.t at line 25 TODO?!)
ok 3
ok 4
ok 5
ok 6
=================================================================
==4056==ERROR: AddressSanitizer: heap-use-after-free on address 0xb1401980 at pc 0xaf3033ce bp 0xbfe4a948 sp 0xbfe4a938
READ of size 4 at 0xb1401980 thread T0
    #0 0xaf3033cd in Tcl_DeleteInterp tcl/generic/tclBasic.c:1344
    #1 0xb5b96090 in XS_Tcl__Finalize tcl.pm/Tcl.xs:1437
    #2 0xb778f9bb in Perl_pp_entersub (/usr/lib/perl5/5.34/core_perl/CORE/libperl.so+0xec9bb)
    #3 0xb7785fe8 in Perl_runops_standard (/usr/lib/perl5/5.34/core_perl/CORE/libperl.so+0xe2fe8)
    #4 0xb76ed7ed in Perl_call_sv (/usr/lib/perl5/5.34/core_perl/CORE/libperl.so+0x4a7ed)
    #5 0xb76eff75 in Perl_call_list (/usr/lib/perl5/5.34/core_perl/CORE/libperl.so+0x4cf75)
    #6 0xb76f1ef9 in perl_destruct (/usr/lib/perl5/5.34/core_perl/CORE/libperl.so+0x4eef9)
    #7 0x4ad17e in main (/usr/bin/perl+0x117e)
    #8 0xb74b6258 in __libc_start_call_main (/usr/lib/libc.so.6+0x25258)
    #9 0xb74b6333 in __libc_start_main_impl (/usr/lib/libc.so.6+0x25333)
    #10 0x4ad224 in _start (/usr/bin/perl+0x1224)

0xb1401980 is located 256 bytes inside of 844-byte region [0xb1401880,0xb1401bcc)
freed by thread T0 here:
    #0 0xb7a6c71d in __interceptor_free /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0xaf2d5794 in TclpFree tcl/generic/tclAlloc.c:722
    #2 0xaf3086e5 in DeleteInterpProc tcl/generic/tclBasic.c:1684
    #3 0xafbdb368 in Tcl_EventuallyFree tcl/generic/tclPreserve.c:296
    #4 0xaf3035da in Tcl_DeleteInterp tcl/generic/tclBasic.c:1360
    #5 0xb5b96cb1 in XS_Tcl_DESTROY tcl.pm/Tcl.xs:1407

previously allocated by thread T0 here:
    #0 0xb7a6ca75 in __interceptor_malloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0xaf2d576e in TclpAlloc tcl/generic/tclAlloc.c:699
    #2 0xaf36ca49 in Tcl_Alloc tcl/generic/tclCkalloc.c:1059
    #3 0xaf2f7f04 in Tcl_CreateInterp tcl/generic/tclBasic.c:514
    #4 0xb5b98a85 in XS_Tcl__new tcl.pm/Tcl.xs:1029

SUMMARY: AddressSanitizer: heap-use-after-free tcl/generic/tclBasic.c:1344 in Tcl_DeleteInterp
Shadow bytes around the buggy address:
  0x362802e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x362802f0: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x36280300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x36280310: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x36280320: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x36280330:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x36280340: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x36280350: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x36280360: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x36280370: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
  0x36280380: 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):
…
  Heap left redzone:       fa
  Freed heap region:       fd
…
==4056==ABORTING