You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Textures module can handle textures in unsafe ways #6045
This came out of analyzing a crash report provided by a user using the "Detailed Weather" mod published on the Steam workshop. This mod dynamically creates a large number of surfaces which it cycles through DFHack's mechanics to push textures into DF's texture system. This runs at very high velocity and exposes a couple of bugs in DFHack's texture handlers:
The g_handle_to_surface cache map can, under some circumstances, hold dangled SDL_Surface* - specifically, the cache map can still hold references to surfaces that will be deleted DF calls delete_all_post_init_textures and so a handle that remains in this map across one of DF's texture clears (which occur during world load) will be stale.
while (surface->recount) DFSDL_FreeSurface(surface) has an (obvious) UAF: FreeSurface deletes surface if its refcount goes to 0, and so when the refcount goes to user surface no longer points to a live object, and so the next (and final) iteration of the loop reads via surface which is now a dangled pointer. Unlikely to actually malfunction, but still incorrect.
The first bug is the one that caused the crash reported in Discord: the user loaded a game while Detailed Weather was active, unloaded that game, then loaded another one. Detailed Weather uses amortized unloading of disposed dynamic textures to avoid frame lags, but doesn't dump its queue when the world it's running in is unloaded, so if a second world is loaded in the same session, it'll resume trying to remove old dynamic textures from the previously loaded world, which DF has already dumped, resulting in a UAF. The fact that Detailed Weather doesn't handle its deferred deletion queue correctly is a bug in Detailed Weather, but their defect shouldn't cause DFHack to crash.
@myk002 you were the architect of this solution, so any insights you might have as to how to best fix it would be welcome
===== DFHack crash report =====
DFHack 53.17-r1, DF 53.17
Exception 0xc0000005 at 00007FFFC65D3609 (module: ?), thread 31152
access violation reading address 00000000000000E9
lua53.dll on native stack: yes
thread-local active lua_State: 000001E754C9C3F8
lua_State 000001E754C9C3F8 traceback:
crash while Lua was executing
stack traceback:
[C]: in field 'deleteHandle'
...)/scripts_modactive/internal/detailed_weather/colour.lua:660: in upvalue 'empty_trash'
...)/scripts_modactive/internal/detailed_weather/colour.lua:1417: in local 'fn'
...iled_weather (14)/scripts_modactive/detailed_weather.lua:539: in method 'timed'
...iled_weather (14)/scripts_modactive/detailed_weather.lua:555: in method 'draw_weather'
...iled_weather (14)/scripts_modactive/detailed_weather.lua:526: in method 'onRenderFrame'
F:\SteamLibrary\steamapps\common\DFHack\hack\lua\gui.lua:813: in method 'render'
...ary\steamapps\common\DFHack\hack\lua\plugins\overlay.lua:571: in local 'fn'
...ary\steamapps\common\DFHack\hack\lua\plugins\overlay.lua:435: in upvalue 'detect_frame_change'
...ary\steamapps\common\DFHack\hack\lua\plugins\overlay.lua:570: in upvalue '_render_viewscreen_widgets'
...ary\steamapps\common\DFHack\hack\lua\plugins\overlay.lua:582: in function 'plugins.overlay.render_viewscreen_widgets'
===== end DFHack crash report =====
(Yes, the crashlogger added in #6000 works, at least it did here)
Activity
ab9rf commentedon Nov 14, 2026
dfhack lua crashlog for this issue:
(Yes, the crashlogger added in #6000 works, at least it did here)
ab9rf commentedon Nov 14, 2026
df crashlog for this issue:
the crash is fairly clearly caused by trying to delete a SDL surface that has already been deleted
myk002 commentedon Nov 15, 2026
I'll take a look
myk002 commentedon Nov 15, 2026
Just notes for myself from my memory: I thought we increased the surface refcount so df's call to free wouldn't actually deallocate the surface