dfhack icon indicating copy to clipboard operation
dfhack copied to clipboard

`fix/ownership` doesn't validate `building::assigned_unit` before trying to use it

Open ab9rf opened this issue 7 months ago • 2 comments

...pps\common\Dwarf Fortress\hack\scripts\fix\ownership.lua:36: Cannot read field building.assigned_unit: not found.
stack traceback:
	[C]: in metamethod '__index'
	...pps\common\Dwarf Fortress\hack\scripts\fix\ownership.lua:36: in local 'relink_zones'
	...pps\common\Dwarf Fortress\hack\scripts\fix\ownership.lua:57: in local 'script_code'
	...rary\steamapps\common\Dwarf Fortress\hack\lua\dfhack.lua:1107: in function 'dfhack.run_script_with_env'
	(...tail calls...)
	[C]: in field 'runCommand'
	...rary\steamapps\common\Dwarf Fortress\hack\lua\dfhack.lua:1150: in upvalue '_run_command'
	...rary\steamapps\common\Dwarf Fortress\hack\lua\dfhack.lua:1165: in function 'dfhack.run_command'
	...\steamapps\common\Dwarf Fortress\hack\scripts\repeat.lua:42: in upvalue 'func'
	...steamapps\common\Dwarf Fortress\hack\lua\repeat-util.lua:40: in function <...steamapps\common\Dwarf Fortress\hack\lua\repeat-util.lua:38>

related discord discussion

ab9rf avatar Apr 16 '25 23:04 ab9rf

Does this mean that zone is not a zone? The buildings are being pulled from the zone vectors, so having a non-zone in there seems wrong. Do you have the save where this error came up?

myk002 avatar Apr 16 '25 23:04 myk002

i do not have a save, just a crash log and a dfhack stderr.log. my conclusion is that the building subcats vectors in building_handlerst can't be relied on to be valid and have to be validated before use. we've seen this in other places, see e.g. #5088

this was reported to me as a crash which i traced down to a dynamic object on a DF vector with an invalid vtable. when i got the DFHack log from the OP, i saw the above tracebacks prior to the crash point; the only way this could happen is if there was an object on one of the four subvectors that had a valid vtable but that vtable pointed to a type that didn't have an assigned_unit member, which means it was indeed not a zone. i'm assuming we didn't do that, so it has to be DF doing it

validation consists of making sure the pointer appears on the "all" vector. if not found, the pointer can't be dereferenced because it might have an invalid vtable. any attempt to to access an object in lua that is supposed to have a vtable but doesn't will crash DFHack, hard

this is clearly DF heapsmashery (that, or unsafe use of invalidated iterators, which would totally not surprise me given what we know of toady's code) but we need to do as much as we can to make sure that DFHack isn't the crash locus

ab9rf avatar Apr 17 '25 04:04 ab9rf