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

Fix argument metadata when binding methods #1509

Merged
merged 1 commit into from
Jul 6, 2024

Conversation

YuriSizov
Copy link
Contributor

@YuriSizov YuriSizov commented Jun 27, 2024

While there doesn't seem to be any runtime issues, this triggers the address sanitizer in a few ways, depending on what kind of method you're binding.

For a method like this, with a return value

ClassDB::bind_method(D_METHOD("get_operator_count"), &SiOPMChannelParams::get_operator_count);

you get a container overflow. It even reaches the Godot side of things, but the bug is caused by godot-cpp all the same: the argument metadata is invalid.

=================================================================
==21404==ERROR: AddressSanitizer: container-overflow on address 0x11fd3863b4b0 at pc 0x7ffaad1ccfbe bp 0x000b78fea5e0 sp 0x000b78fea5e0
READ of size 4 at 0x11fd3863b4b0 thread T0
    #0 0x7ffaad1ccfbd in godot::ClassDB::bind_method_godot(class godot::StringName const &, class godot::MethodBind *) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:227
    #1 0x7ffaad1cc77d in godot::ClassDB::bind_methodfi(unsigned int, class godot::MethodBind *, struct godot::MethodDefinition const &, void const **, int) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:183
    #2 0x7ffaace60e75 in godot::ClassDB::bind_method<struct godot::MethodDefinition, int (__cdecl SiOPMChannelParams::*)(void) const>(struct godot::MethodDefinition, int (__cdecl SiOPMChannelParams::*)(void) const) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:305
    #3 0x7ffaace55855 in SiOPMChannelParams::_bind_methods(void) C:\Projects\godot-extensions\gdsion\src\chip\siopm_channel_params.cpp:251
    #4 0x7ffaacda8843 in SiOPMChannelParams::initialize_class(void) C:\Projects\godot-extensions\gdsion\src\chip\siopm_channel_params.h:22
    #5 0x7ffaacd5fe36 in godot::ClassDB::_register_class<class SiOPMChannelParams, 1>(bool, bool, bool) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:271
    #6 0x7ffaacd71c3f in godot::ClassDB::register_abstract_class<class SiOPMChannelParams>(void) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:284
    #7 0x7ffaacd34cf8 in initialize_sion_module(enum godot::ModuleInitializationLevel) C:\Projects\godot-extensions\gdsion\src\register_types.cpp:89
    #8 0x7ffaad17d698 in godot::GDExtensionBinding::initialize_level(void *, enum GDExtensionInitializationLevel) C:\Projects\godot-extensions\gdsion\godot-cpp\src\godot.cpp:509
    #9 0x7ff7b34c3b91 in GDExtension::initialize_library(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:856
    #10 0x7ff7b28af558 in GDExtensionManager::initialize_extensions(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension_manager.cpp:185
    #11 0x7ff7a4fa6578 in Main::setup2(void) C:\Projects\godot-engine\master\main\main.cpp:3116
    #12 0x7ff7a4f9c1ec in Main::setup(char const *, int, char **const, bool) C:\Projects\godot-engine\master\main\main.cpp:2465
    #13 0x7ff7a4dc5430 in widechar_main(int, wchar_t **) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:165
    #14 0x7ff7a4dc5906 in _main(void) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:206
    #15 0x7ff7a4dc5981 in main C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:220
    #16 0x7ff7a4dc478c in WinMain C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:233
    #17 0x7ff7b44e0379 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102
    #18 0x7ff7b44e0379 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #19 0x7ffb5070257c  (C:\Windows\System32\KERNEL32.DLL+0x18001257c)
    #20 0x7ffb51f0af27  (C:\Windows\SYSTEM32\ntdll.dll+0x18005af27)

0x11fd3863b4b0 is located 0 bytes inside of 4-byte region [0x11fd3863b4b0,0x11fd3863b4b4)
allocated by thread T0 here:
    #0 0x7ffaad35891e in operator new(unsigned __int64) D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win_new_scalar_thunk.cpp:40
    #1 0x7ffaacd7f8a2 in std::_Default_allocate_traits::_Allocate(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory:77
    #2 0x7ffaacd365d1 in std::_Allocate<16, struct std::_Default_allocate_traits, 0>(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory:235
    #3 0x7ffaad1fc9bf in std::allocator<enum GDExtensionClassMethodArgumentMetadata>::allocate(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory:951
    #4 0x7ffaad1f8b6e in std::vector<enum GDExtensionClassMethodArgumentMetadata, class std::allocator<enum GDExtensionClassMethodArgumentMetadata>>::_Reallocate_exactly(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector:1608
    #5 0x7ffaad2002b3 in std::vector<enum GDExtensionClassMethodArgumentMetadata, class std::allocator<enum GDExtensionClassMethodArgumentMetadata>>::reserve(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector:1683
    #6 0x7ffaad1fe480 in godot::MethodBind::get_arguments_metadata_list(void) const C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\method_bind.hpp:134
    #7 0x7ffaad1ccb74 in godot::ClassDB::bind_method_godot(class godot::StringName const &, class godot::MethodBind *) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:197
    #8 0x7ffaad1cc77d in godot::ClassDB::bind_methodfi(unsigned int, class godot::MethodBind *, struct godot::MethodDefinition const &, void const **, int) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:183
    #9 0x7ffaace60e75 in godot::ClassDB::bind_method<struct godot::MethodDefinition, int (__cdecl SiOPMChannelParams::*)(void) const>(struct godot::MethodDefinition, int (__cdecl SiOPMChannelParams::*)(void) const) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:305
    #10 0x7ffaace55855 in SiOPMChannelParams::_bind_methods(void) C:\Projects\godot-extensions\gdsion\src\chip\siopm_channel_params.cpp:251
    #11 0x7ffaacda8843 in SiOPMChannelParams::initialize_class(void) C:\Projects\godot-extensions\gdsion\src\chip\siopm_channel_params.h:22
    #12 0x7ffaacd5fe36 in godot::ClassDB::_register_class<class SiOPMChannelParams, 1>(bool, bool, bool) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:271
    #13 0x7ffaacd71c3f in godot::ClassDB::register_abstract_class<class SiOPMChannelParams>(void) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:284
    #14 0x7ffaacd34cf8 in initialize_sion_module(enum godot::ModuleInitializationLevel) C:\Projects\godot-extensions\gdsion\src\register_types.cpp:89
    #15 0x7ffaad17d698 in godot::GDExtensionBinding::initialize_level(void *, enum GDExtensionInitializationLevel) C:\Projects\godot-extensions\gdsion\godot-cpp\src\godot.cpp:509
    #16 0x7ff7b34c3b91 in GDExtension::initialize_library(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:856
    #17 0x7ff7b28af558 in GDExtensionManager::initialize_extensions(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension_manager.cpp:185
    #18 0x7ff7a4fa6578 in Main::setup2(void) C:\Projects\godot-engine\master\main\main.cpp:3116
    #19 0x7ff7a4f9c1ec in Main::setup(char const *, int, char **const, bool) C:\Projects\godot-engine\master\main\main.cpp:2465
    #20 0x7ff7a4dc5430 in widechar_main(int, wchar_t **) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:165
    #21 0x7ff7a4dc5906 in _main(void) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:206
    #22 0x7ff7a4dc5981 in main C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:220
    #23 0x7ff7a4dc478c in WinMain C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:233
    #24 0x7ff7b44e0379 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102
    #25 0x7ff7b44e0379 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #26 0x7ffb5070257c  (C:\Windows\System32\KERNEL32.DLL+0x18001257c)
    #27 0x7ffb51f0af27  (C:\Windows\SYSTEM32\ntdll.dll+0x18005af27)

HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0.
If you suspect a false positive see also: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow.
SUMMARY: AddressSanitizer: container-overflow C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:227 in godot::ClassDB::bind_method_godot(class godot::StringName const &, class godot::MethodBind *)
Shadow bytes around the buggy address:
  0x0438df5c7640: fa fa 00 fa fa fa 00 00 fa fa 00 fa fa fa fd fa
  0x0438df5c7650: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0438df5c7660: fa fa 00 fa fa fa fd fa fa fa 00 fa fa fa fd fa
  0x0438df5c7670: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0438df5c7680: fa fa 00 fa fa fa 00 fa fa fa 00 00 fa fa 00 00
=>0x0438df5c7690: fa fa 00 fa fa fa[fc]fa fa fa fa fa fa fa fa fa
  0x0438df5c76a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0438df5c76b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0438df5c76c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0438df5c76d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0438df5c76e0: 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
Address Sanitizer Error: Container overflow

A method like this, without a return value and with arguments

ClassDB::bind_method(D_METHOD("set_operator_count", "value"), &SiOPMChannelParams::set_operator_count);

causes heap buffer overflow. The return value metadata is invalid.

=================================================================
==19688==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x11d0c9ebb4f4 at pc 0x7ff7b34efdaa bp 0x00a4acdec700 sp 0x00a4acdec700
READ of size 4 at 0x11d0c9ebb4f4 thread T0
    #0 0x7ff7b34efda9 in GDExtensionMethodBind::update(struct GDExtensionClassMethodInfo const *) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:355
    #1 0x7ff7b34d5673 in GDExtensionMethodBind::GDExtensionMethodBind(struct GDExtensionClassMethodInfo const *) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:379
    #2 0x7ff7b34b85f3 in GDExtension::_register_extension_class_method(void *, void const *, struct GDExtensionClassMethodInfo const *) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:594
    #3 0x7ffaad1cd0f7 in godot::ClassDB::bind_method_godot(class godot::StringName const &, class godot::MethodBind *) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:234
    #4 0x7ffaad1cc77d in godot::ClassDB::bind_methodfi(unsigned int, class godot::MethodBind *, struct godot::MethodDefinition const &, void const **, int) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:183
    #5 0x7ffaace980f5 in godot::ClassDB::bind_method<struct godot::MethodDefinition, void (__cdecl SiOPMChannelBase::*)(int)>(struct godot::MethodDefinition, void (__cdecl SiOPMChannelBase::*)(int)) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:305
    #6 0x7ffaace90fdf in SiOPMChannelBase::_bind_methods(void) C:\Projects\godot-extensions\gdsion\src\chip\channels\siopm_channel_base.cpp:469
    #7 0x7ffaacda8703 in SiOPMChannelBase::initialize_class(void) C:\Projects\godot-extensions\gdsion\src\chip\channels\siopm_channel_base.h:28
    #8 0x7ffaacd5e576 in godot::ClassDB::_register_class<class SiOPMChannelBase, 1>(bool, bool, bool) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:271
    #9 0x7ffaacd71bbf in godot::ClassDB::register_abstract_class<class SiOPMChannelBase>(void) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:284
    #10 0x7ffaacd34cf8 in initialize_sion_module(enum godot::ModuleInitializationLevel) C:\Projects\godot-extensions\gdsion\src\register_types.cpp:89
    #11 0x7ffaad17d698 in godot::GDExtensionBinding::initialize_level(void *, enum GDExtensionInitializationLevel) C:\Projects\godot-extensions\gdsion\godot-cpp\src\godot.cpp:509
    #12 0x7ff7b34c3b91 in GDExtension::initialize_library(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:856
    #13 0x7ff7b28af558 in GDExtensionManager::initialize_extensions(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension_manager.cpp:185
    #14 0x7ff7a4fa6578 in Main::setup2(void) C:\Projects\godot-engine\master\main\main.cpp:3116
    #15 0x7ff7a4f9c1ec in Main::setup(char const *, int, char **const, bool) C:\Projects\godot-engine\master\main\main.cpp:2465
    #16 0x7ff7a4dc5430 in widechar_main(int, wchar_t **) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:165
    #17 0x7ff7a4dc5906 in _main(void) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:206
    #18 0x7ff7a4dc5981 in main C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:220
    #19 0x7ff7a4dc478c in WinMain C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:233
    #20 0x7ff7b44e0379 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102
    #21 0x7ff7b44e0379 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #22 0x7ffb5070257c  (C:\Windows\System32\KERNEL32.DLL+0x18001257c)
    #23 0x7ffb51f0af27  (C:\Windows\SYSTEM32\ntdll.dll+0x18005af27)

0x11d0c9ebb4f4 is located 4 bytes inside of 8-byte region [0x11d0c9ebb4f0,0x11d0c9ebb4f8)
allocated by thread T0 here:
    #0 0x7ffaad35891e in operator new(unsigned __int64) D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win_new_scalar_thunk.cpp:40
    #1 0x7ffaacd7f8a2 in std::_Default_allocate_traits::_Allocate(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory:77
    #2 0x7ffaacd365d1 in std::_Allocate<16, struct std::_Default_allocate_traits, 0>(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory:235
    #3 0x7ffaad1fc9bf in std::allocator<enum GDExtensionClassMethodArgumentMetadata>::allocate(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory:951
    #4 0x7ffaad1f8b6e in std::vector<enum GDExtensionClassMethodArgumentMetadata, class std::allocator<enum GDExtensionClassMethodArgumentMetadata>>::_Reallocate_exactly(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector:1608
    #5 0x7ffaad2002b3 in std::vector<enum GDExtensionClassMethodArgumentMetadata, class std::allocator<enum GDExtensionClassMethodArgumentMetadata>>::reserve(unsigned __int64) C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector:1683
    #6 0x7ffaad1fe480 in godot::MethodBind::get_arguments_metadata_list(void) const C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\method_bind.hpp:134
    #7 0x7ffaad1ccb74 in godot::ClassDB::bind_method_godot(class godot::StringName const &, class godot::MethodBind *) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:197
    #8 0x7ffaad1cc77d in godot::ClassDB::bind_methodfi(unsigned int, class godot::MethodBind *, struct godot::MethodDefinition const &, void const **, int) C:\Projects\godot-extensions\gdsion\godot-cpp\src\core\class_db.cpp:183
    #9 0x7ffaace980f5 in godot::ClassDB::bind_method<struct godot::MethodDefinition, void (__cdecl SiOPMChannelBase::*)(int)>(struct godot::MethodDefinition, void (__cdecl SiOPMChannelBase::*)(int)) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:305
    #10 0x7ffaace90fdf in SiOPMChannelBase::_bind_methods(void) C:\Projects\godot-extensions\gdsion\src\chip\channels\siopm_channel_base.cpp:469
    #11 0x7ffaacda8703 in SiOPMChannelBase::initialize_class(void) C:\Projects\godot-extensions\gdsion\src\chip\channels\siopm_channel_base.h:28
    #12 0x7ffaacd5e576 in godot::ClassDB::_register_class<class SiOPMChannelBase, 1>(bool, bool, bool) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:271
    #13 0x7ffaacd71bbf in godot::ClassDB::register_abstract_class<class SiOPMChannelBase>(void) C:\Projects\godot-extensions\gdsion\godot-cpp\include\godot_cpp\core\class_db.hpp:284
    #14 0x7ffaacd34cf8 in initialize_sion_module(enum godot::ModuleInitializationLevel) C:\Projects\godot-extensions\gdsion\src\register_types.cpp:89
    #15 0x7ffaad17d698 in godot::GDExtensionBinding::initialize_level(void *, enum GDExtensionInitializationLevel) C:\Projects\godot-extensions\gdsion\godot-cpp\src\godot.cpp:509
    #16 0x7ff7b34c3b91 in GDExtension::initialize_library(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension.cpp:856
    #17 0x7ff7b28af558 in GDExtensionManager::initialize_extensions(enum GDExtension::InitializationLevel) C:\Projects\godot-engine\master\core\extension\gdextension_manager.cpp:185
    #18 0x7ff7a4fa6578 in Main::setup2(void) C:\Projects\godot-engine\master\main\main.cpp:3116
    #19 0x7ff7a4f9c1ec in Main::setup(char const *, int, char **const, bool) C:\Projects\godot-engine\master\main\main.cpp:2465
    #20 0x7ff7a4dc5430 in widechar_main(int, wchar_t **) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:165
    #21 0x7ff7a4dc5906 in _main(void) C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:206
    #22 0x7ff7a4dc5981 in main C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:220
    #23 0x7ff7a4dc478c in WinMain C:\Projects\godot-engine\master\platform\windows\godot_windows.cpp:233
    #24 0x7ff7b44e0379 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:102
    #25 0x7ff7b44e0379 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #26 0x7ffb5070257c  (C:\Windows\System32\KERNEL32.DLL+0x18001257c)
    #27 0x7ffb51f0af27  (C:\Windows\SYSTEM32\ntdll.dll+0x18005af27)

SUMMARY: AddressSanitizer: heap-buffer-overflow C:\Projects\godot-engine\master\core\extension\gdextension.cpp:355 in GDExtensionMethodBind::update(struct GDExtensionClassMethodInfo const *)
Shadow bytes around the buggy address:
  0x0406e3157640: fa fa 00 fa fa fa 00 00 fa fa 00 fa fa fa fd fa
  0x0406e3157650: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0406e3157660: fa fa 00 fa fa fa fd fa fa fa 00 fa fa fa fd fa
  0x0406e3157670: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0406e3157680: fa fa 00 fa fa fa 00 fa fa fa 00 00 fa fa 00 00
=>0x0406e3157690: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa[04]fa
  0x0406e31576a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0406e31576b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0406e31576c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0406e31576d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0406e31576e0: 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
Address Sanitizer Error: Heap buffer overflow

Looks like this was introduced as is in #896, in commit e24b6b0. A similar method get_arguments_info_list had the same issue initially, but was corrected in b6ba0dc, all within the same PR.

I can't say if this change has any unexpected side effects, or if it fixes any outstanding issues (quite possible, anything related to arguments can be affected, I guess?), but I can confirm that with it included there are no asan issues in my project anymore.

While there doesn't seem to be any runtime issues,
this triggers the address sanitizer in a few ways,
depending on what kind of method you're
binding.
@YuriSizov YuriSizov requested a review from a team as a code owner June 27, 2024 16:52
@AThousandShips AThousandShips added bug This has been identified as a bug topic:gdextension This relates to the new Godot 4 extension implementation cherrypick:4.2 labels Jun 27, 2024
@AThousandShips AThousandShips added this to the 4.3 milestone Jun 27, 2024
Copy link
Member

@AThousandShips AThousandShips left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, and matches the code in get_arguments_info_list

Copy link
Collaborator

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great find, thanks!

@hazelnutcloud
Copy link

hazelnutcloud commented Jul 5, 2024

My extension fails at load because of this bug. Adding the changes here fixed it. Crashes when declaring the method_info variable in ClassDB::bind_method_godot when dereferencing the return_value_metadata which seems to be null because of an empty vector.

@dsnopek dsnopek merged commit 6d939e6 into godotengine:master Jul 6, 2024
12 checks passed
@YuriSizov YuriSizov deleted the method-bind-is-off-by-one branch July 6, 2024 18:04
@dsnopek
Copy link
Collaborator

dsnopek commented Jul 17, 2024

Cherry-picked for 4.2 in PR #1527

@dsnopek
Copy link
Collaborator

dsnopek commented Jul 17, 2024

Cherry-picked for 4.1 in PR #1529

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This has been identified as a bug topic:gdextension This relates to the new Godot 4 extension implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants