CVE-2026-99180: unicode: free the map after a grace period
In the Linux kernel, the following vulnerability has been resolved:
unicode: free the map after a grace period
genericcidhash() and genericcidcompare() read sb->sencoding and dereference the unicode map while a pathwalk in rcu mode holds nothing but rcureadlock(). The filesystems that use them, ext4, f2fs and tmpfs, drop the map with utf8unload() from ->putsuper(), which runs when the last reference to the mount goes away. A lookup that is still inside such a filesystem at that point reads a freed map.
With a pathwalk held up in utf8casefoldhash() while the last reference to a casefolded tmpfs goes away:
BUG: KASAN: slab-use-after-free in utf8nlookup+0x74c/0x950 Read of size 8 at addr ff110001030fe658 by task walker/98 Call Trace: <TASK> utf8nlookup+0x74c/0x950 utf8byte+0x160/0x1560 utf8casefoldhash+0x167/0x230 genericcidhash+0xdd/0x1c0 linkpathwalk+0x11ad/0x1d30 pathlookupat+0x63/0xb00 filenamelookup+0x1f1/0x5b0 vfsstatx+0xd7/0x3b0 [...] Allocated by task 94: kmalloccachenoprof+0x249/0x560 utf8load+0x4e/0x570 shmemparseoptcasefold.isra.0+0x92/0x270 [...] Freed by task 97: kfree+0x1db/0x5b0 shmemputsuper+0x72/0x170 genericshutdownsuper+0x14c/0x530 killanonsuper+0x3a/0x60 deactivatelockedsuper+0x9c/0xf0 cleanupmnt+0x9f/0x130
So far that has been hard to hit. umount(2) waits for a grace period in namespaceunlock() before it drops the mount, so only a mount whose last reference goes away elsewhere, like the close of a file or a chdir out of a lazily unmounted directory, can race a walker. So it is reachable.
Delay the free until a grace period has passed. The map and the data table it holds a reference to then outlive any pathwalk that found the superblock before the mount went away. The reference on the data table module is dropped from the rcu callback as well. utf8-core is built in whenever CONFIGUNICODE is set, so there is no module exit that would have to wait for the callbacks.
Overlayfs points the sencoding of an overlay at the map of its first layer without taking a reference of its own. That stays correct. The layer is held by the overlay, so its map is dropped only after the overlay is gone.
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
Delay freeing the Unicode map until an RCU grace period has passed; for casefolded tmpfs, drop the map with utf8_unload() from ->put_super().