godot/scene/resources
HP van Braam eb948bc5a8 Fix a crash trying to save an empty AudioStream
My friends, gather around as I learned something about the C standard
that is horrifying and may keep you, dear reader, up at night.

My journey began trying to fix something entirely unrelated and not
wanting to wait for ubsan builds when changing a testcase. So me, in my
infinite naivete just built the engine with tests=yes, but
optimizations turned on.

This resulted in a segfault on "[Audio][AudioStreamWAV] Save empty file".

Well, then, I thought. Lets built with asan then and find out where this
happens! Would it surprise you, my fellow traveler, that the results
were that no such crash occurred?

Thus, to the debugger I go! Fearless, with great optimism. Where I find
that through many an indirection the crash came because, somehow,
CowData::_unref() was getting called with a _ptr set to 0x1.

This can of course only end in tears. Or segmentation faults as we try
to read an atomic variable at the somewhat inconveniently situated
address at 0xfffffffffffffff0.

So I went and looked at the likely culprit, blaming many an innocent
recent change along the way. I shall spare you the falsly accused. But
if for some reason you slept poorly last night, I can assure you that
the voodoo dolls have been put away and will not be harmed further.

So in AudioStreamWAV::get_data() we go, where we find a perfectly
reasonable function! It checks to see whether or not its data is empty,
and if it is not it will resize a temporary Vector to have data_bytes of
space, after which it will do a perfectly pedestrian memcpy() and all is
well in the world.

Or so it seems! After many an hour of despair and disassembly I, at
last, decided to look at where the data gets set! A breakthrough!
Because of the padding data is never empty! So the code always runs!

Eureka! One would think. But then, foolishly, I looked into the
get_data() function one more. My mortal enemy was staring me in the
face, laughing. Because it did not care about this. Sure, the check was
worthless but still... What are we left with.

At this point I could feel the method mocking me.

"I resize the vector to 0, I then memcpy zero bytes into it." It said,
DARING me to object to this state of affairs.

And yet, if I changed the function to check for "data_bytes" rather
than data.is_empty() no crashes.

Was this a compiler bug? Am I losing my mind? But then... I remembered
the mantra of the wise compiler druids... "It Is Not A Compiler Bug".

But what then! The bug does not happen when memory is being watched!
Valgrind agreed that while accessing the SafeRefCount at
0xfffffffffffffff0 was incredibly rude, it did not inform me of anything
else untoward happening. So I read the memcpy() manpage... nothing... I
read the the memcpy() posix spec... nothing.

Finally, in despair and because I had nothing left to lose... The ISO C
language specification. As I was reading, I could hear
AudioStreamWAV::get_data() cackling, knowing that its time was up, but
proud of the madness it caused in my soul. Knowing I would never be the
same.

The behavior is undefined if either dest or src is an invalid or null pointer.

So... Here I stand before you, a broken person. But one richer in
knowledge.

I write you this from the depths of madness in the hopes that you, dear
reader, can be spared this ordeal.

May god have mercy on our souls.

We trigger the following sequence of events:

* memcpy(null, null, 0) is UB, thus dest and src cannot be null
* we inline the calls to the ctor and dtor
* now we have a function that does something that "proves"
  dest cannot be null
* we inline cowdata::_unref() which does a null check, on something
  that the compiler just convinced itself cannot be null
* the compiler removes the dead code branch where _ptr == nullptr
* we start to do pointer arithmetic on a nullptr and get send to
  uninitialized memory.

Co-Authored-By: Jason Beckmann <jasonabeckmann@gmail.com>
2024-12-17 23:14:39 +01:00
..
2d Improve NavMeshGenerator2D::generator_bake_from_source_geometry_data performance 2024-11-11 12:31:19 +01:00
3d Fix very large radius SphereMesh and CapsuleMesh normals 2024-12-13 09:26:59 +01:00
animated_texture.cpp
animated_texture.h
animation_library.cpp Add contains_char() for single-character 'contains' calls. 2024-12-06 20:23:35 +01:00
animation_library.h Add RetargetModifier3D for realtime retarget to keep original rest 2024-11-18 22:44:55 +09:00
animation.compat.inc
animation.cpp Set clang-format RemoveSemicolon rule to true 2024-10-25 13:49:43 -04:00
animation.h Add markers to animation 2024-09-29 17:27:36 +09:00
atlas_texture.cpp
atlas_texture.h
audio_stream_polyphonic.compat.inc
audio_stream_polyphonic.cpp Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
audio_stream_polyphonic.h Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
audio_stream_wav.cpp Fix a crash trying to save an empty AudioStream 2024-12-17 23:14:39 +01:00
audio_stream_wav.h Use qoa.c and custom compress procedure 2024-12-05 13:20:09 -03:00
bit_map.cpp Avoid expensive sqrt operation in hot loop of BitMap.grow_mask 2024-09-12 11:04:57 -03:00
bit_map.h
bone_map.cpp
bone_map.h
camera_attributes.cpp Set clang-format RemoveSemicolon rule to true 2024-10-25 13:49:43 -04:00
camera_attributes.h Style: Apply new clang-format changes 2024-09-20 08:09:48 -05:00
camera_texture.cpp Add linux camera support 2024-09-25 12:08:06 +02:00
camera_texture.h Add linux camera support 2024-09-25 12:08:06 +02:00
canvas_item_material.cpp Fix deadlock possibility in threaded load of materials 2024-12-13 12:49:10 +01:00
canvas_item_material.h
color_palette.cpp Save color palette as resources to reuse later 2024-12-06 20:16:06 +07:00
color_palette.h Save color palette as resources to reuse later 2024-12-06 20:16:06 +07:00
compositor.cpp CompositorEffect should use GDVIRTUAL_CALL() so it works with GDExtension 2024-12-03 12:57:56 -06:00
compositor.h CompositorEffect should use GDVIRTUAL_CALL() so it works with GDExtension 2024-12-03 12:57:56 -06:00
compressed_texture.cpp
compressed_texture.h
curve_texture.cpp
curve_texture.h
curve.cpp Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
curve.h Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
environment.cpp Added external camera feed from external plugin on Android 2024-10-30 18:30:28 +01:00
environment.h
external_texture.cpp ExternalTexture: Avoid error when destroyed without having been used 2024-10-23 10:04:38 +02:00
external_texture.h ExternalTexture: Avoid error when destroyed without having been used 2024-10-23 10:04:38 +02:00
font.compat.inc
font.cpp Merge pull request #98664 from bruvzg/ts_reset_subpixel_shift 2024-12-02 17:20:07 +01:00
font.h Merge pull request #98664 from bruvzg/ts_reset_subpixel_shift 2024-12-02 17:20:07 +01:00
gradient_texture.cpp Fix pink GradientTexture2D 2024-09-26 09:50:55 -03:00
gradient_texture.h Fix pink GradientTexture2D 2024-09-26 09:50:55 -03:00
gradient.cpp
gradient.h
image_texture.cpp
image_texture.h
immediate_mesh.cpp Fix immediate mesh modifications that don't call set_mesh 2024-10-03 18:08:49 -06:00
immediate_mesh.h
label_settings.cpp [Label] Handle text as multiple independent paragraphs. 2024-11-14 11:29:46 +02:00
label_settings.h [Label] Handle text as multiple independent paragraphs. 2024-11-14 11:29:46 +02:00
material.cpp Fix deadlock possibility in threaded load of materials 2024-12-13 12:49:10 +01:00
material.h Restore dirty list for BaseMaterial3D but don't use it on resource loader. 2024-11-27 10:37:19 -03:00
mesh_data_tool.compat.inc
mesh_data_tool.cpp
mesh_data_tool.h
mesh_texture.cpp
mesh_texture.h
mesh.cpp Improve Scene Tree editor performance 2024-12-12 22:47:05 +01:00
mesh.h GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
multimesh.cpp Fix MultiMesh errors in editor and resource duplication 2024-10-26 02:45:54 -03:00
multimesh.h
navigation_mesh.cpp Core: Integrate Ref::instantiate where possible 2024-11-10 12:41:26 -06:00
navigation_mesh.h Extract navigation-related defaults to separate header 2024-08-27 20:12:10 +02:00
packed_scene.cpp Revert "Avoid duplicating signals from scene instances into packed scenes" 2024-12-10 10:42:58 +01:00
packed_scene.h Implement typed dictionaries 2024-09-04 10:27:26 -05:00
particle_process_material.cpp Merge pull request #98747 from tetrapod00/standardize-renderer-strings 2024-12-13 16:19:37 -06:00
particle_process_material.h Add cone angle control to particle emission ring shape 2024-09-02 14:35:51 +02:00
physics_material.cpp
physics_material.h
placeholder_textures.cpp
placeholder_textures.h
portable_compressed_texture.cpp Core: Integrate Ref::instantiate where possible 2024-11-10 12:41:26 -06:00
portable_compressed_texture.h
resource_format_text.cpp Use (r)find_char instead of (r)find for single characters 2024-11-17 10:02:18 +01:00
resource_format_text.h Universalize UID support in all resource types 2024-11-11 15:59:56 +01:00
SCsub Use qoa.c and custom compress procedure 2024-12-05 13:20:09 -03:00
shader_include.cpp
shader_include.h
shader.compat.inc Allow setting a cubemap as default parameter to shader 2024-08-27 09:43:05 +03:00
shader.cpp Merge pull request #97205 from tetrapod00/inspect-native-shader-code 2024-10-21 16:39:13 -05:00
shader.h Merge pull request #97205 from tetrapod00/inspect-native-shader-code 2024-10-21 16:39:13 -05:00
skeleton_profile.cpp Add RetargetModifier3D for realtime retarget to keep original rest 2024-11-18 22:44:55 +09:00
skeleton_profile.h Add RetargetModifier3D for realtime retarget to keep original rest 2024-11-18 22:44:55 +09:00
sky.cpp
sky.h
sprite_frames.cpp Use SceneStringName in more places 2024-12-02 14:39:16 +01:00
sprite_frames.h Add duplicate animation 2024-09-01 17:00:47 +02:00
style_box_flat.cpp Codestyle improvements in style_box_flat.cpp 2024-12-03 22:03:53 +02:00
style_box_flat.h
style_box_line.cpp
style_box_line.h
style_box_texture.cpp
style_box_texture.h
style_box.cpp GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
style_box.h GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
surface_tool.cpp Rewrite index optimization code for maximum efficiency 2024-11-04 06:58:06 -08:00
surface_tool.h Rewrite index optimization code for maximum efficiency 2024-11-04 06:58:06 -08:00
syntax_highlighter.cpp Use (r)find_char instead of (r)find for single characters 2024-11-17 10:02:18 +01:00
syntax_highlighter.h
text_file.cpp
text_file.h
text_line.cpp Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
text_line.h Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
text_paragraph.cpp Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
text_paragraph.h Get rid of easily removable uses of const_cast 2024-12-01 17:50:13 -08:00
texture_rd.cpp Fix inability to set TextureLayeredRD as TEXTURE_TYPE_CUBE or TEXTURE_TYPE_CUBE_ARRAY 2024-11-11 15:31:43 +03:00
texture_rd.h
texture.cpp GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
texture.h GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
theme.cpp Add contains_char() for single-character 'contains' calls. 2024-12-06 20:23:35 +01:00
theme.h Improve Editor Inspector/Theme item lookup performance 2024-08-20 13:39:40 -04:00
video_stream.cpp GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
video_stream.h GDExtension: Mark virtual function as is_required in extension_api.json 2024-09-11 16:48:14 -05:00
visual_shader_nodes.compat.inc Allow setting a cubemap as default parameter to shader 2024-08-27 09:43:05 +03:00
visual_shader_nodes.cpp Merge pull request #97365 from aaronp64/vector_compose_input_defaults 2024-11-29 22:46:05 +01:00
visual_shader_nodes.h VisualShader: Add LinearToSRGB and SRGBToLinear to ColorFunc node 2024-10-19 12:18:34 -07:00
visual_shader_particle_nodes.cpp
visual_shader_particle_nodes.h
visual_shader_sdf_nodes.cpp
visual_shader_sdf_nodes.h
visual_shader.cpp Add contains_char() for single-character 'contains' calls. 2024-12-06 20:23:35 +01:00
visual_shader.h Allow setting a cubemap as default parameter to shader 2024-08-27 09:43:05 +03:00
world_2d.cpp
world_2d.h