DF-3111 / fix.diff
--- a/sys/vfs/hammer/hammer_subs.c +++ b/sys/vfs/hammer/hammer_subs.c @@ -1031,6 +1031,21 @@ hpanic("bad algorithm %p", dip); break; } + + /* + * Clamp the iteration count so the consumers' unchecked + * 'cursor.key_end.key += max_iterations' (hammer_vnops.c: + * hammer_vop_nlookup / hammer_vop_nrename / hammer_dounlink) + * cannot overflow the positive key space. Directory keys only + * use the positive key space (see hammer_ip_add_direntry()). + * Without the clamp a crafted filename whose namekey lands in + * the top 0xFFFFFF of the key space wraps key_end negative and + * truncates the hash-chain scan: the dirent becomes permanently + * unfindable and unremovable. + */ + if (key > 0x7FFFFFFFFFFFFFFFLL - (int64_t)*max_iterationsp) + *max_iterationsp = (uint32_t)(0x7FFFFFFFFFFFFFFFLL - key); + return(key); } |