Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddressSanitizer reports heap-use-after-free in object_instance_id_when_freed integration test #89

Closed
ttencate opened this issue Jan 27, 2023 · 0 comments · Fixed by #133
Labels
bug c: ffi Low-level components and interaction with GDExtension API ub Undefined behavior

Comments

@ttencate
Copy link
Contributor

I built a custom Godot 4 binary using:

$ scons optimize=debug debug_symbols=yes use_ubsan=yes use_asan=yes use_lsan=yes use_msan=yes

ASAN triggers an abort in the integration test on the is_instance_valid call here:

https://github.com/godot-rust/gdextension/blob/c37d0ce51cbc40292914015bce24bde1ab1a791a/itest/rust/src/object_test.rs#L156-L157

Full trace:

   -- object_instance_id_when_freed
=================================================================
==231428==ERROR: AddressSanitizer: heap-use-after-free on address 0x61a000031e90 at pc 0x55bbd4aa611d bp 0x7ffe8e2ab610 sp 0x7ffe8e2ab600
READ of size 8 at 0x61a000031e90 thread T0
    #0 0x55bbd4aa611c in gdextension_object_get_instance_id core/extension/gdextension_interface.cpp:935
    #1 0x7f4e3fac3e48 in godot_core::obj::gd::Gd$LT$T$GT$::instance_id_or_none::h6bf6c0272958a527 godot-core/src/obj/gd.rs:245
    #2 0x7f4e3fac3a3d in godot_core::obj::gd::Gd$LT$T$GT$::is_instance_valid::h141dab810e85fcaa godot-core/src/obj/gd.rs:273
    #3 0x7f4e3fabb7ec in itest::object_test::object_instance_id_when_freed::_$u7b$$u7b$closure$u7d$$u7d$::hfe59ff15c9d5bed3 itest/rust/src/object_test.rs:157
    #4 0x7f4e3fae0cbb in std::panicking::try::do_call::h104e89f3d9fa7b31 /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:483
    #5 0x7f4e3faef7fa in __rust_try (/home/thomas/gdextension/itest/godot/../../target/debug/libitest.so+0xef7fa)
    #6 0x7f4e3fad6c95 in std::panicking::try::h0ac213656080ecc2 /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:447
    #7 0x7f4e3fad2728 in std::panic::catch_unwind::h91a171faba7069ab /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panic.rs:137
    #8 0x7f4e3fa44410 in itest::object_test::object_instance_id_when_freed::h57b9df4b7dbd655c itest/rust/src/object_test.rs:151
    #9 0x7f4e3fa424f5 in itest::object_test::run::h1094db215a0ea691 itest/rust/src/object_test.rs:33
    #10 0x7f4e3faaf1a3 in itest::run_tests::hb5d66f5c57c15ab5 itest/rust/src/lib.rs:37
    #11 0x7f4e3faaf2ca in itest::IntegrationTests::run::h02b98bbdbf1e9732 itest/rust/src/lib.rs:65
    #12 0x7f4e3faaf01d in _$LT$itest..IntegrationTests$u20$as$u20$godot_core..obj..traits..cap..ImplementsGodotApi$GT$::__register_methods::function::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h96e4d73b028b49ff godot-core/src/macros.rs:110
    #13 0x7f4e3fb0aca7 in core::ops::function::FnOnce::call_once::hd8e3e1fcd5d67a4a /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:251
    #14 0x7f4e3fa26807 in _$LT$$LP$R$C$$RP$$u20$as$u20$godot_core..builtin..meta..signature..SignatureTuple$GT$::ptrcall::hefc81992d74e99c4 godot-core/src/builtin/meta/signature.rs:161
    #15 0x7f4e3faaeff0 in _$LT$itest..IntegrationTests$u20$as$u20$godot_core..obj..traits..cap..ImplementsGodotApi$GT$::__register_methods::function::_$u7b$$u7b$closure$u7d$$u7d$::he26c1c1d176e0cb9 godot-core/src/macros.rs:104
    #16 0x7f4e3fae5c08 in std::panicking::try::do_call::h9c147f7996c369c6 /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:483
    #17 0x7f4e3faef7fa in __rust_try (/home/thomas/gdextension/itest/godot/../../target/debug/libitest.so+0xef7fa)
    #18 0x7f4e3fadcf0f in std::panicking::try::h944674e78df8af86 /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panicking.rs:447
    #19 0x7f4e3fad20b7 in std::panic::catch_unwind::h64f12795b33108fb /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/std/src/panic.rs:137
    #20 0x7f4e3faafd3f in _$LT$itest..IntegrationTests$u20$as$u20$godot_core..obj..traits..cap..ImplementsGodotApi$GT$::__register_methods::function::h84eb79f17ccba806 godot-core/src/macros.rs:103
    #21 0x55bbd4a88a2a in GDExtensionMethodBind::ptrcall(Object*, void const**, void*) const core/extension/gdextension.cpp:197
    #22 0x55bbbbdf1271 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_vm.cpp:1864
    #23 0x55bbbb757afb in GDScriptInstance::callp(StringName const&, Variant const**, int, Callable::CallError&) modules/gdscript/gdscript.cpp:1842
    #24 0x55bbc77a8be1 in bool Node::_gdvirtual__ready_call<false>() scene/main/node.h:242
    #25 0x55bbc77a8be1 in Node::_notification(int) scene/main/node.cpp:155
    #26 0x55bbba4fcabb in Node::_notificationv(int, bool) scene/main/node.h:46
    #27 0x55bbd4b734b5 in Object::notification(int, bool) core/object/object.cpp:790
    #28 0x55bbc77501c7 in Node::_propagate_ready() scene/main/node.cpp:188
    #29 0x55bbc774fb49 in Node::_propagate_ready() scene/main/node.cpp:180
    #30 0x55bbc7758ffc in Node::_set_tree(SceneTree*) scene/main/node.cpp:2596
    #31 0x55bbc7886d10 in SceneTree::initialize() scene/main/scene_tree.cpp:410
    #32 0x55bbb9c03b30 in OS_LinuxBSD::run() platform/linuxbsd/os_linuxbsd.cpp:866
    #33 0x55bbb9bf9fb3 in main platform/linuxbsd/godot_linuxbsd.cpp:73
    #34 0x7f4e4dc3c28f  (/usr/lib/libc.so.6+0x2328f)
    #35 0x7f4e4dc3c349 in __libc_start_main (/usr/lib/libc.so.6+0x23349)
    #36 0x55bbb9bf99c4 in _start (/home/thomas/godot/bin/godot.linuxbsd.editor.x86_64.san+0x33f5c9c4)

0x61a000031e90 is located 16 bytes inside of 1264-byte region [0x61a000031e80,0x61a000032370)
freed by thread T0 here:
    #0 0x7f4e4e6be672 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x55bbd2d6ef3c in Memory::free_static(void*, bool) core/os/memory.cpp:168

previously allocated by thread T0 here:
    #0 0x7f4e4e6bfa89 in __interceptor_malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x55bbd2d6e67a in Memory::alloc_static(unsigned long, bool) core/os/memory.cpp:75
    #2 0x617000067827  (<unknown module>)

SUMMARY: AddressSanitizer: heap-use-after-free core/extension/gdextension_interface.cpp:935 in gdextension_object_get_instance_id
Shadow bytes around the buggy address:
  0x0c347fffe380: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe390: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe3a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
  0x0c347fffe3b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c347fffe3c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c347fffe3d0: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe3e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe3f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe410: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c347fffe420: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==231428==ABORTING
[Finished running. Exit status: 1]

Not sure if this is an issue with Godot or with gdextension, but recording it here for now.

@Bromeon Bromeon added bug c: ffi Low-level components and interaction with GDExtension API labels Jan 27, 2023
bors bot added a commit that referenced this issue Feb 4, 2023
109: Address sanitizers in integration tests r=Bromeon a=Bromeon

Also makes clippy more strict and fixes doctests on `master`.

Integration tests with address sanitizers currently support two setups (gcc + clang), and are allowed to fail until some of the underlying issues like #89 are fixed. Unless the two variants report different findings, we may reduce CI to use only one of the two memory checkers in the future.

Co-authored-by: Jan Haller <bromeon@gmail.com>
@bors bors bot closed this as completed in f9db5d6 Feb 26, 2023
@Bromeon Bromeon added the ub Undefined behavior label Jul 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug c: ffi Low-level components and interaction with GDExtension API ub Undefined behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants