godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.31k stars 20.23k forks source link

Executing `SoftBody.get_point_transform` crashes Godot #53331

Closed qarmin closed 2 years ago

qarmin commented 2 years ago

Godot version

3.4.beta.custom_build. 01ae4888e

System information

Ubuntu 21.04 - Nvidia GTX 970, Gnome shell 3.38 X11

Issue description

When executing

    var temp_variable10264 = SoftBody.new()
    add_child(temp_variable10264)
    temp_variable10264.set_physics_enabled(false)
    temp_variable10264.set_mesh(PlaneMesh.new())
    temp_variable10264.set_physics_enabled(true)
    temp_variable10264.get_point_transform(-39)

Godot crashes with this info

==11184==ERROR: AddressSanitizer: heap-use-after-free on address 0x6160000df378 at pc 0x0000044ad777 bp 0x7ffd2ee51020 sp 0x7ffd2ee51010
READ of size 4 at 0x6160000df378 thread T0
    #0 0x44ad776 in B_TO_G(btVector3 const&, Vector3&) modules/bullet/bullet_types_converter.cpp:39
    #1 0x2fa49f4 in SoftBodyBullet::get_node_position(int, Vector3&) const modules/bullet/soft_body_bullet.cpp:179
    #2 0x2e8c30c in BulletPhysicsServer::soft_body_get_point_global_position(RID, int) modules/bullet/bullet_physics_server.cpp:1146
    #3 0xdecc7be in SoftBody::get_point_transform(int) scene/3d/soft_body.cpp:701
    #4 0xdeeff1a in MethodBind1R<Vector3, int>::call(Object*, Variant const**, int, Variant::CallError&) core/method_bind.gen.inc:961
    #5 0x11d31e39 in Object::call(StringName const&, Variant const**, int, Variant::CallError&) core/object.cpp:918
    #6 0x11fbb4c6 in Variant::call_ptr(StringName const&, Variant const**, int, Variant*, Variant::CallError&) core/variant_call.cpp:1175
    #7 0x1e61777 in GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Variant::CallError&, GDScriptFunction::CallState*) modules/gdscript/gdscript_function.cpp:1046
    #8 0x1c92bec in GDScriptInstance::call_multilevel(StringName const&, Variant const**, int) modules/gdscript/gdscript.cpp:1184
    #9 0xc4b2ea3 in Node::_notification(int) scene/main/node.cpp:56
    #10 0x1b3e1ef in Node::_notificationv(int, bool) scene/main/node.h:45
    #11 0x1b40664 in CanvasItem::_notificationv(int, bool) scene/2d/canvas_item.h:163
    #12 0xe0f5cb0 in Node2D::_notificationv(int, bool) scene/2d/node_2d.h:37
    #13 0x11d322d3 in Object::notification(int, bool) core/object.cpp:927
    #14 0xc5e6107 in SceneTree::_notify_group_pause(StringName const&, int) scene/main/scene_tree.cpp:973
    #15 0xc5d6695 in SceneTree::idle(float) scene/main/scene_tree.cpp:528
    #16 0x198336f in Main::iteration() main/main.cpp:2183
    #17 0x185ac8a in OS_X11::run() platform/x11/os_x11.cpp:3641
    #18 0x17c5d8b in main platform/x11/godot_x11.cpp:55
    #19 0x7f0d078a4564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
    #20 0x17c59ad in _start (/usr/bin/godots+0x17c59ad)

0x6160000df378 is located 248 bytes inside of 565-byte region [0x6160000df280,0x6160000df4b5)
freed by thread T0 here:
    #0 0x7f0d088218f7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
    #1 0x851855e in png_free_default thirdparty/libpng/pngmem.c:252
    #2 0x851852b in png_free thirdparty/libpng/pngmem.c:242
    #3 0x851ec14 in png_read_destroy thirdparty/libpng/pngread.c:1030
    #4 0x851f940 in png_destroy_read_struct thirdparty/libpng/pngread.c:1112
    #5 0x8511ce9 in png_image_free_function thirdparty/libpng/png.c:4571
    #6 0x8511e7c in png_image_free thirdparty/libpng/png.c:4591
    #7 0x853527e in png_image_finish_read thirdparty/libpng/pngread.c:4273
    #8 0x826f481 in PNGDriverCommon::png_to_image(unsigned char const*, unsigned long, bool, Ref<Image>) drivers/png/png_driver_common.cpp:117
    #9 0x85f19d8 in ImageLoaderPNG::load_mem_png(unsigned char const*, int) drivers/png/image_loader_png.cpp:65
    #10 0x11c3274f in Image::Image(unsigned char const*, int) core/image.cpp:3327
    #11 0x197c9fe in Main::start() main/main.cpp:2047
    #12 0x17c5cbe in main platform/x11/godot_x11.cpp:54
    #13 0x7f0d078a4564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)

previously allocated by thread T0 here:
    #0 0x7f0d08821c47 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x8518069 in png_malloc_base thirdparty/libpng/pngmem.c:95
    #2 0x8518326 in png_malloc thirdparty/libpng/pngmem.c:179
    #3 0x859f692 in png_read_start_row thirdparty/libpng/pngrutil.c:4824
    #4 0x851a18d in png_read_update_info thirdparty/libpng/pngread.c:355
    #5 0x85338dc in png_image_read_direct thirdparty/libpng/pngread.c:4057
    #6 0x85176fc in png_safe_execute thirdparty/libpng/pngerror.c:951
    #7 0x8535269 in png_image_finish_read thirdparty/libpng/pngread.c:4270
    #8 0x826f481 in PNGDriverCommon::png_to_image(unsigned char const*, unsigned long, bool, Ref<Image>) drivers/png/png_driver_common.cpp:117
    #9 0x85f19d8 in ImageLoaderPNG::load_mem_png(unsigned char const*, int) drivers/png/image_loader_png.cpp:65
    #10 0x11c3274f in Image::Image(unsigned char const*, int) core/image.cpp:3327
    #11 0x197c9fe in Main::start() main/main.cpp:2047
    #12 0x17c5cbe in main platform/x11/godot_x11.cpp:54
    #13 0x7f0d078a4564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)

SUMMARY: AddressSanitizer: heap-use-after-free modules/bullet/bullet_types_converter.cpp:39 in B_TO_G(btVector3 const&, Vector3&)

Steps to reproduce

Above

Minimal reproduction project

No response

qarmin commented 2 years ago

Another crash

    var temp_variable10270 = SoftBody.new()
    add_child(temp_variable10270)
    temp_variable10270.set_physics_enabled(false)
    temp_variable10270.set_mesh(QuadMesh.new())
    temp_variable10270.set_physics_enabled(true)
    temp_variable10270.is_blocking_signals()
================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v3.4.beta.custom_build (01ae4888e938cee7e067f0aa09d1298ae40e78b8)
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x41040) [0x7f68bc409040] (??:0)
[2] btAlignedObjectArray<btSoftBody::Node>::size() const (/mnt/Miecz/godot3.2/thirdparty/bullet/LinearMath/btAlignedObjectArray.h:144)
[3] SoftBodyBullet::reset_all_node_positions() (/mnt/Miecz/godot3.2/modules/bullet/soft_body_bullet.cpp:239)
[4] SoftBodyBullet::set_soft_transform(Transform const&) (/mnt/Miecz/godot3.2/modules/bullet/soft_body_bullet.cpp:152)
[5] BulletPhysicsServer::soft_body_set_transform(RID, Transform const&) (/mnt/Miecz/godot3.2/modules/bullet/bullet_physics_server.cpp:1005)
[6] SoftBody::_notification(int) (/mnt/Miecz/godot3.2/scene/3d/soft_body.cpp:288)
[7] SoftBody::_notificationv(int, bool) (/mnt/Miecz/godot3.2/scene/3d/soft_body.h:66 (discriminator 14))
[8] Object::notification(int, bool) (/mnt/Miecz/godot3.2/core/object.cpp:929)
[9] SceneTree::flush_transform_notifications() (/mnt/Miecz/godot3.2/scene/main/scene_tree.cpp:153)
[10] SceneTree::idle(float) (/mnt/Miecz/godot3.2/scene/main/scene_tree.cpp:541)
[11] Main::iteration() (/mnt/Miecz/godot3.2/main/main.cpp:2183)
[12] OS_X11::run() (/mnt/Miecz/godot3.2/platform/x11/os_x11.cpp:3641)
[13] godot(main+0x125) [0x179933b] (/mnt/Miecz/godot3.2/platform/x11/godot_x11.cpp:57)
[14] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xd5) [0x7f68bc3f0565] (??:0)
[15] godot(_start+0x2e) [0x179915e] (??:?)
-- END OF BACKTRACE --
================================================================
LATRio commented 2 years ago

couldn't reproduce first crash on Windows 10, 64 bits

qarmin commented 2 years ago

Looks that this code corrupts memory and don't crash entire app.

To corrupt more memory which cause for me crash even with build without sanitizers you can use this code

func _process(delta) -> void:
    var temp_variable10264 = SoftBody.new()
    add_child(temp_variable10264)
    temp_variable10264.set_physics_enabled(false)
    temp_variable10264.set_mesh(PlaneMesh.new())
    temp_variable10264.set_physics_enabled(true)
    temp_variable10264.get_point_transform(randi() % 1000)
LATRio commented 2 years ago

found out that btAssert isn't defined when when debugging and adding BT_DEBUG through bullet module's SCsub doesn't seem to define it as well. This causes operator[] of tNodeArray (btAlignedObjectArray) to return data outside of array's bounds

akien-mga commented 2 years ago

Fixed by #53349 and #53335.