For lightning effect we using ps_rand() function which expects number in range [0, 0x7fff], but RAND_MAX is 0x7fffffff (INT_MAX, for 64-bit systems). In result lightnings strikes on every allowed frame and leads to epilepsy.
Possibly fixes#530.
physics/findintersection.cpp:4711:64: runtime error: index -1 out of bounds for type 'fvi_face_room_list [200]'
=================================================================
SIGNAL 11 caught, aborting
$GIT/Descent3/multi_external.h:286:31: runtime error: store to misaligned address 0x7f3f760a3041 for type 'int16_t', which requires 2 byte alignment
$GIT/Descent3/multi_external.h:291:32: runtime error: store to misaligned address 0x7f3f760a3043 for type 'uint16_t', which requires 2 byte alignment
$GIT/Descent3/room.cpp:629:28: runtime error: member access within misaligned address 0x7fde8b011d6e for type 'struct roomUVL', which requires 4 byte alignment
$GIT/Descent3/LoadLevel.cpp:1978:24: runtime error: member access within misaligned address 0x7fde8b011d6e for type 'struct roomUVL', which requires 4 byte alignment
$GIT/Descent3/room.cpp:608:13: runtime error: member access within misaligned address 0x7fde8b0243d4 for type 'struct face', which requires 8 byte alignment
$GIT/vecmat/vector.cpp:180:18: runtime error: member access within misaligned address 0x7fde8b03dfda for type 'const struct vector', which requires 4 byte alignment
$GIT/Descent3/BOA.cpp:1213:27: runtime error: member access within misaligned address 0x7fde8b0243d4 for type 'struct face', which requires 8 byte alignment
RoomMemAlloc failed to aligned returned pointers to the type they are
being used for.
Things seem fine on level 1 and 2, but saving on level 4:
$GIT/Descent3/matcen.cpp:813:36: runtime error: index -1 out of bounds for type 'sound_info [1000]'
=================================================================
==38205==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000480e974 at pc 0x7f396b280c66 bp 0x7ffc328e1f90 sp 0x7ffc328e1750
READ of size 1 at 0x00000480e974 thread T0
f1 matcen::SaveData(CFILE*) $GIT/Descent3/matcen.cpp:813
f2 SGSMatcens(CFILE*) $GIT/Descent3/gamesave.cpp:1320
f3 SaveGameState(char const*, char const*) $GIT/Descent3/gamesave.cpp:803
f4 SaveGameDialog() $GIT/Descent3/gamesave.cpp:494
f5 RunGameMenu() $GIT/Descent3/gamesequence.cpp:2161
f6 GameSequencer() $GIT/Descent3/gamesequence.cpp:1218
f7 PlayGame() $GIT/Descent3/game.cpp:834
f8 MainLoop() $GIT/Descent3/descent.cpp:555
f9 Descent3() $GIT/Descent3/descent.cpp:508
f10 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
Giving off a shot in level 1 triggers an ASAN OOB notice without stacktrace/abort.
Descent3/scorch.cpp:200:53: runtime error: index -1 out of bounds for type 'scorch [500]'
for (i = Scorch_start, sp = &Scorches[Scorch_start];;) {
^
At the beginning of a level, Scorch_start is still -1. Computing
``&Scorches[Scorch_start]``, i.e. ``&Scorches[-1]``, is legal but
conceptually wrong. ``sp`` is then dereferenced inside the loop body
ahead of checking for the terminating condition.
Add a guarding termination condition in the loop head so that we
never even start the loop if Scorch_start<0. Never compute ``sp`` if
the loop is not entered.
Starting level 4 triggers an OOB access.
$GIT/Descent3/AIGoal.cpp:793:55: runtime error: index -1 out of bounds for type 'ai_dynamic_path [50]'
$GIT/Descent3/AIGoal.cpp:793:116: runtime error: index -1 out of bounds for type 'short unsigned int [5]'
=================================================================
==29374==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000003b1f8f8 at pc 0x00000147b488 bp 0x7fff6cf12a60 sp 0x7fff6cf12a58
READ of size 4 at 0x000003b1f8f8 thread T0
f0 vm_SubVectors(vector*, vector const*, vector const*) $GIT/vecmat/vector.cpp:180
f1 vm_VectorDistance(vector const*, vector const*) $GIT/vecmat/vector.cpp:191
f2 GoalDoFrame(object*) $GIT/Descent3/AIGoal.cpp:792
f3 AIDoFrame(object*) $GIT/Descent3/AImain.cpp:6212
f4 ObjDoFrame(object*) $GIT/Descent3/object.cpp:2674
f5 ObjDoFrameAll() $GIT/Descent3/object.cpp:2988
f6 GameFrame() $GIT/Descent3/GameLoop.cpp:2980
f7 GameSequencer() $GIT/Descent3/gamesequence.cpp:1221
f8 PlayGame() $GIT/Descent3/game.cpp:834
f9 MainLoop() $GIT/Descent3/descent.cpp:555
f10 Descent3() $GIT/Descent3/descent.cpp:508
f11 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x000003b1f8f8 is located 8 bytes after global variable 'AI_RenderedList' defined in '$GIT/Descent3/AImain.cpp:1628:5' (0x3b1e180) of size 6000
0x000003b1f8f8 is located 40 bytes before global variable 'AI_NumHostileAlert' defined in '$GIT/Descent3/AImain.cpp:1630:5' (0x3b1f920) of size 4
Giving off a laser shot in level 1 causes a double OOB.
$GIT/Descent3/AIGoal.cpp:756:57: runtime error: index -1 out of bounds for type 'ai_dynamic_path [50]'
$GIT/Descent3/AIGoal.cpp:756:118: runtime error: index -1 out of bounds for type 'short unsigned int [5]'
=================================================================
==58320==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000003b1f7f8 at pc 0x00000147b414 bp 0x7ffe6fdab4f0 sp 0x7ffe6fdab4e8
READ of size 4 at 0x000003b1f7f8 thread T0
f0 vm_SubVectors(vector*, vector const*, vector const*) $GIT/vecmat/vector.cpp:180
f1 vm_VectorDistance(vector const*, vector const*) $GIT/vecmat/vector.cpp:191
f2 GoalDoFrame(object*) $GIT/Descent3/AIGoal.cpp:755
float dist = vm_VectorDistance(
&AIDynamicPath[ai_info->path.num_paths - 1].pos[ai_info->path.path_end_node[ai_info->path.num_paths - 1]],
^ ^
posp);
f3 AIDoFrame(object*) $GIT/Descent3/AImain.cpp:6212
f4 ObjDoFrame(object*) $GIT/Descent3/object.cpp:2674
f5 ObjDoFrameAll() $GIT/Descent3/object.cpp:2988
f6 GameFrame() $GIT/Descent3/GameLoop.cpp:2980
f7 GameSequencer() $GIT/Descent3/gamesequence.cpp:1221
f8 PlayGame() $GIT/Descent3/game.cpp:834
f9 MainLoop() $GIT/Descent3/descent.cpp:555
f10 Descent3() $GIT/Descent3/descent.cpp:508
f11 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
f12 main $GIT/Descent3/sdlmain.cpp:334
0x000003b1f7f8 is located 8 bytes after global variable 'AI_RenderedList' defined in '$GIT/Descent3/AImain.cpp:1628:5' (0x3b1e080) of size 6000
0x000003b1f7f8 is located 40 bytes before global variable 'AI_NumHostileAlert' defined in '$GIT/Descent3/AImain.cpp:1630:5' (0x3b1f820) of size 4
Collecting the mine pickup, or just outright using the inventory
cheat code, triggers OOB:
id=92 Chaff
..icon_handle=493
....bm_handle=513
id=94 betty
..icon_handle=493
....bm_handle=513
id=95 SeekerMine
..icon_handle=-1
$GIT/Descent3/Inventory.cpp:585:17: runtime error: index -1 out of bounds for type 'texture [3100]'
==6498==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000003bcf918 at pc 0x000000844eac bp 0x7ffc0823f310 sp 0x7ffc0823f308
READ of size 4 at 0x000003bcf918 thread T0
f0 Inventory::AddCounterMeasure(int, int, int, int, char const*) $GIT/Descent3/Inventory.cpp:585
(char *)mem_malloc(strlen(GameBitmaps[GameTextures[Weapons[id].icon_handle].bm_handle].name) + 1);
^
f1 Inventory::Add(int, int, object*, int, int, int, char const*) $GIT/Descent3/Inventory.cpp:521
f2 DemoCheats(int) $GIT/Descent3/GameCheat.cpp:608
f3 ProcessKeys() $GIT/Descent3/GameLoop.cpp:2418
f4 GameFrame() $GIT/Descent3/GameLoop.cpp:2963
f5 GameSequencer() $GIT/Descent3/gamesequence.cpp:1221
f6 PlayGame() $GIT/Descent3/game.cpp:834
f7 MainLoop() $GIT/Descent3/descent.cpp:555
f8 Descent3() $GIT/Descent3/descent.cpp:508
f9 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x000003bcf918 is located 48 bytes after global variable 'm_start_tstamp' defined in '$GIT/ddio/chrono_timer.h:25:59' (0x3bcf8e0) of size 8
0x000003bcf918 is located 8 bytes before global variable 'Num_textures' defined in '$GIT/Descent3/gametexture.cpp:286:5' (0x3bcf920) of size 4
Array index j underflows.
==50803==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000003edbeb8 at pc 0x000000d02e13 bp 0x7ffdda72ec10 sp 0x7ffdda72ec08
READ of size 4 at 0x000003edbeb8 thread T0
f0 SortPostrenders() $GIT/Descent3/postrender.cpp:142
f1 PostRender(int) $GIT/Descent3/postrender.cpp:241
f2 GameRenderWorld(object*, vector*, int, matrix*, float, bool) $GIT/Descent3/GameLoop.cpp:2475
f3 GameDrawMainView() $GIT/Descent3/GameLoop.cpp:2503
f4 GameRenderFrame() $GIT/Descent3/GameLoop.cpp:2600
f5 GameFrame() $GIT/Descent3/GameLoop.cpp:3055
f6 GameSequencer() $GIT/Descent3/gamesequence.cpp:1221
f7 PlayGame() $GIT/Descent3/game.cpp:834
f8 MainLoop() $GIT/Descent3/descent.cpp:555
f9 Descent3() $GIT/Descent3/descent.cpp:508
f10 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x000003edbeb8 is located 40 bytes before global variable 'Postrender_list' defined in '$GIT/Descent3/postrender.cpp:90:19' (0x3edbee0) of size 36000
0x000003edbeb8 is located 52 bytes after global variable 'Num_waypoints' defined in '$GIT/Descent3/Player.cpp:3787:5' (0x3edbe80) of size 4
When ENTER is pressed too quickly in the menu system, an OOB happens.
(Press ENTER to activate "New Game". It looks like the mission list
is not populated (yet), therefore m_SelectedIndex is -1. If the
keypress event arrives before the list is filled, OOB occurs.)
==67061==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50700003f40c at pc 0x000000b5a400 bp 0x7ffd2bd478c0 sp 0x7ffd2bd478b8
READ of size 4 at 0x50700003f40c thread T0
f0 newuiListBox::OnKeyDown(int) $GIT/Descent3/newui_core.cpp:3230
f1 UIGadget::Process(bool, bool, bool) $GIT/ui/UIGadget.cpp:236
f2 UIWindow::Process() $GIT/ui/UIWindow.cpp:409
f3 ui_ProcessFocusedWindow() $GIT/ui/UISystem.cpp:439
f4 ui_DoFrame(bool) $GIT/ui/UISystem.cpp:503
f5 DoUIFrame() $GIT/Descent3/newui_core.cpp:633
f6 newuiTiledWindow::DoUI() $GIT/Descent3/newui_core.cpp:4148
f7 MenuNewGame() $GIT/Descent3/menu.cpp:1232
f8 MainMenu() $GIT/Descent3/menu.cpp:830
f9 MainLoop() $GIT/Descent3/descent.cpp:546
f10 Descent3() $GIT/Descent3/descent.cpp:508
f11 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x50700003f40c is located 4 bytes before 80-byte region [0x50700003f410,0x50700003f460)
allocated by thread T0 here:
f0 malloc (/lib64/libasan.so.8)
f1 newuiListBox::AddItem(char const*) $GIT/Descent3/newui_core.cpp:2726
f2 operator() $GIT/Descent3/menu.cpp:1101
f3 __invoke_impl<void, generate_mission_listbox(newuiListBox*, int, char**, const std::filesystem::__cxx11::path&)::<lambda(const std::filesystem::__cxx11::path&)>&, std::filesystem::__cxx11::path> /usr/include/c++/14/bits/invoke.h:61
f4 __invoke_r<void, generate_mission_listbox(newuiListBox*, int, char**, const std::filesystem::__cxx11::path&)::<lambda(const std::filesystem::__cxx11::path&)>&, std::filesystem::__cxx11::path> /usr/include/c++/14/bits/invoke.h:111
f5 _M_invoke /usr/include/c++/14/bits/std_function.h:290
f6 std::function<void (std::filesystem::__cxx11::path)>::operator()(std::filesystem::__cxx11::path) const /usr/include/c++/14/bits/std_function.h:591
f7 ddio_DoForeachFile(std::filesystem::__cxx11::path const&, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, std::function<void (std::filesystem::__cxx11::path)> const&) $GIT/ddio/file.cpp:154
f8 generate_mission_listbox $GIT/Descent3/menu.cpp:1093
f9 MenuNewGame() $GIT/Descent3/menu.cpp:1198
f10 MainMenu() $GIT/Descent3/menu.cpp:830
f11 MainLoop() $GIT/Descent3/descent.cpp:546
f12 Descent3() $GIT/Descent3/descent.cpp:508
f13 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
As level 1's in-engine cutscene runs, an OOB happens after about 3s.
x=0 object[x].type=4
x=1 object[x].type=18
x=2 object[x].type=255
$GIT/physics/findintersection.cpp:2196:80: runtime error: index 255 out of bounds for type 'unsigned char [26]'
$GIT/physics/findintersection.cpp:2196:80: runtime error: load of address 0x00000475a97f with insufficient space for an object of type 'uint8_t'
==28871==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000475a97f at pc 0x000001242275 bp 0x7fffc1ced720 sp 0x7fffc1ced718
READ of size 1 at 0x00000475a97f thread T0
f0 fvi_QuickDistObjectList(vector*, int, float, short*, int, bool, bool, bool, bool) $GIT/physics/findintersection.cpp:2196
f1 AIDoMemFrame $GIT/Descent3/AImain.cpp:6066
f2 AIDoFrame(object*) $GIT/Descent3/AImain.cpp:6187
f3 ObjDoFrame(object*) $GIT/Descent3/object.cpp:2674
f4 ObjDoFrameAll() $GIT/Descent3/object.cpp:2988
f5 GameFrame() $GIT/Descent3/GameLoop.cpp:2980
f6 GameSequencer() $GIT/Descent3/gamesequence.cpp:1221
f7 PlayGame() $GIT/Descent3/game.cpp:834
f8 MainLoop() $GIT/Descent3/descent.cpp:555
f9 Descent3() $GIT/Descent3/descent.cpp:508
f10 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x00000475a97f is located 30 bytes after global variable 'FVI_always_check_ceiling' defined in '$GIT/physics/findintersection.cpp:888:6' (0x475a960) of size 1
'FVI_always_check_ceiling' is ascii string ''
0x00000475a97f is located 33 bytes before global variable 'fvi_visit_list' defined in '$GIT/physics/findintersection.cpp:895:5' (0x475a9a0) of size 51
$GIT/Descent3/render.cpp:249:30: runtime error: index -1 out of bounds for type 'bms_bitmap [5000]'
==1231==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000043aa93a at pc 0x000000d2b4ec bp 0x7ffd141b7590 sp 0x7ffd141b7588
READ of size 1 at 0x0000043aa93a thread T0
f0 GetFaceAlpha $GIT/Descent3/render.cpp:249
f1 RenderRoomUnsorted(room*) $GIT/Descent3/render.cpp:2311
f2 RenderRoom(room*) $GIT/Descent3/render.cpp:2963
f3 RenderMine(int, int, int) $GIT/Descent3/render.cpp:3472
f4 GameRenderWorld(object*, vector*, int, matrix*, float, bool) $GIT/Descent3/GameLoop.cpp:2465
f5 GameDrawMainView() $GIT/Descent3/GameLoop.cpp:2503
f6 GameRenderFrame() $GIT/Descent3/GameLoop.cpp:2600
f7 GameFrame() $GIT/Descent3/GameLoop.cpp:3055
f8 GameSequencer() $GIT/Descent3/gamesequence.cpp:1221
f9 PlayGame() $GIT/Descent3/game.cpp:834
f10 MainLoop() $GIT/Descent3/descent.cpp:555
f11 Descent3() $GIT/Descent3/descent.cpp:508
f12 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x0000043aa93a is located 22 bytes after global variable 'Num_of_bitmaps' defined in '$GIT/bitmap/bitmain.cpp:322:5' (0x43aa920) of size 4
0x0000043aa93a is located 38 bytes before global variable 'GameBitmaps' defined in '$GIT/bitmap/bitmain.cpp:323:12' (0x43aa960) of size 280000
GetFaceAlpha intentionally is called with -1.
(gdb) bt
f4 GetFaceAlpha (fp=0x7fffda30c862, bm_handle=-1) at $GIT/Descent3/render.cpp:244
f5 RenderRoomUnsorted (rp=0x4058330 <Rooms+25200>) at $GIT/Descent3/render.cpp:2313
2313 if (Render_mirror_for_room == false && (fogged_portal || (GetFaceAlpha(fp, -1) & (ATF_CONSTANT + ATF_VERTEX)))) {
f6 RenderRoom (rp=0x4058330 <Rooms+25200>) at $GIT/Descent3/render.cpp:2965
f7 RenderMine (viewer_roomnum=33, flag_automap=1, called_from_terrain=0) at $GIT/Descent3/render.cpp:3474
f8 GameRenderWorld (viewer=0x3d23750 <Objects+230000>, viewer_eye=0x3d23770 <Objects+230032>, viewer_roomnum=33, viewer_orient=0x3d2377c <Objects+230044>, zoom=0.726000011, rear_view=false) at $GIT/Descent3/GameLoop.cpp:2465
f9 GameDrawMainView () at $GIT/Descent3/GameLoop.cpp:2503
f10 GameRenderFrame () at $GIT/Descent3/GameLoop.cpp:2600
f11 GameFrame () at $GIT/Descent3/GameLoop.cpp:3055
f12 GameSequencer () at $GIT/Descent3/gamesequence.cpp:1221
f13 PlayGame () at $GIT/Descent3/game.cpp:834
f14 MainLoop () at $GIT/Descent3/descent.cpp:555
f15 Descent3 () at $GIT/Descent3/descent.cpp:508
f16 oeD3LnxApp::run (this=0x7ffff460db50) at $GIT/Descent3/sdlmain.cpp:151
y2=256 is a legitimate argument to the RecurseLODDeltas function, and
the array is too short to accomodate it.
$GIT/Descent3/terrain.cpp:166:57: runtime error: index 65540 out of bounds for type 'terrain_segment [65536]'
$GIT/Descent3/terrain.cpp:166:59: runtime error: load of address 0x00000424b9f0 with insufficient space for an object of type 'float'
y2=256 midx=4
==39949==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000424b8f4 at pc 0x000000e62047 bp 0x7ffcd5ea2390 sp 0x7ffcd5ea2388
READ of size 4 at 0x00000424b8f4 thread T0
f0 RecurseLODDeltas(int, int, int, int, int) $GIT/Descent3/terrain.cpp:165
f1 RecurseLODDeltas(int, int, int, int, int) $GIT/Descent3/terrain.cpp:176
f2 RecurseLODDeltas(int, int, int, int, int) $GIT/Descent3/terrain.cpp:176
f3 GenerateLODDeltas() $GIT/Descent3/terrain.cpp:288
f4 BuildMinMaxTerrain() $GIT/Descent3/terrain.cpp:336
f5 ReadTerrainChunks(CFILE*, int) $GIT/Descent3/LoadLevel.cpp:3468
f6 LoadLevel(char*, void (*)(char const*, int, int)) $GIT/Descent3/LoadLevel.cpp:3937
f7 LoadMissionLevel(int) $GIT/Descent3/Mission.cpp:1278
f8 LoadAndStartCurrentLevel() $GIT/Descent3/gamesequence.cpp:1669
f9 GameSequencer() $GIT/Descent3/gamesequence.cpp:1197
f10 PlayGame() $GIT/Descent3/game.cpp:834
f11 MainLoop() $GIT/Descent3/descent.cpp:555
f12 Descent3() $GIT/Descent3/descent.cpp:508
f13 oeD3LnxApp::run() $GIT/Descent3/sdlmain.cpp:151
0x00000424b8f4 is located 20 bytes after global variable 'Terrain_seg' defined in '$GIT/Descent3/terrain.cpp:51:17' (0x410b8e0) of size 1310720
0x00000424b8f4 is located 12 bytes before global variable 'Terrain_tex_seg' defined in '$GIT/Descent3/terrain.cpp:52:21' (0x424b900) of size 4096
Use orphaned "buffer update streaming" to eliminate synchronization
delays, due to CPU->GPU latency, causing framerate slowdowns. This sends
vertex data to the GPU via partial updates to a buffer and reallocates
the buffer once it fills up, ensuring that no synchronization is ever
needed. The buffer is sized to balance memory usage vs allocation rate,
and the GL driver ensures that "orphaned" buffers are only destroyed
when all GL commands using them are retired.