summaryrefslogtreecommitdiffstats
path: root/chksum.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-04-06 20:06:18 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-04-06 20:06:18 -0700
commit174182a29c785493ed41231caff36f35c56819cf (patch)
treeebe0f5d3f1d26a5fbc360a8c064d07990e4d257e /chksum.h
parent695bd0d14d03e2b3380d2913b87dadc60383235f (diff)
downloadtxr-174182a29c785493ed41231caff36f35c56819cf.tar.gz
txr-174182a29c785493ed41231caff36f35c56819cf.tar.bz2
txr-174182a29c785493ed41231caff36f35c56819cf.zip
gc: fix astonishing bug in weak hash processing.
This is a flaw that has been in the code since the initial implementation in 2009. Weak hash tables are only partially marked during the initial garbage collection marking phase. They are put into a global list, which is then walked again to do the weak processing: to expire items which are not reachable, and then finish walking the table objects. Problem is, the code assumes that this late processing will not discover more hash tables and put them into that global list. This creates a problem when weak hash table contain weak hash tables, such as in the important and very common case when a global variable (binding stored in a weak hash table) contains a weak hash table! These hash tables discovered during weak hash table processing are partially marked, and left that way. The result is that their table vectors get prematurely scavenged by the garbage collector, and then fall victim to use-after-free crashing. Note: do_iters doesn't have this bug. Though the reachable_iters list resembles reachable_weak_hashes, the key difference is that do_iters does not do any marking, and so will not discover any more reachable objects. All it does is update some counts in the hashes to which the still-reachable iterators point. * hash.c (do_weak_tables): Clear the reachable_weak_hashes list on entry into the function, taking a local copy of its head. After walking the list, check the global variable again; it if has become non-null, it means more weak tables were discovered and added to the list. In that case, make a recursive call (susceptible to tail call treatment) to process the list again.
Diffstat (limited to 'chksum.h')
0 files changed, 0 insertions, 0 deletions