CVE-2026-97902 in Linux
Summary
by MITRE • 09/25/2026
In the Linux kernel, the following vulnerability has been resolved:
fs: don't return -EINVAL for successful nested thaw
Commit 7366f8b6fc6a ("fs: handle freezing from multiple devices") replaced the freeze_holders bitmask with per-holder counters to allow nested freezes. In the bitmask version, a thaw that released a shared hold while another holder remained returned 0. Since the rework, thaw_super_locked() drops the freeze reference via freeze_dec() but then returns -EINVAL when other freezers remain, misinforming the caller: the thaw did succeed, the superblock just stays frozen for the remaining holders.
This breaks bdev-initiated freezing. When a filesystem is frozen with FIFREEZE and additionally frozen via bdev_freeze() -- which nests by design, see fs_bdev_freeze() -- the subsequent bdev_thaw() receives -EINVAL from the holder op although its freeze reference was dropped, and therefore keeps bd_fsfreeze_count elevated. Then device-mapper's unlock_fs() ignores bdev_thaw()'s return value, so nothing rebalances the count. After the user's FITHAW and umount, the block device can never be mounted again:
dm-1: Can't mount, blockdev is frozen
There is no way for userspace to drop the leaked count; only destroying the block device (or a reboot) recovers the device.
Reproducer (any kernel since v6.8):
dmsetup create dut --table "0 $(blockdev --getsz "$DEV") linear $DEV 0" mkfs.ext4 /dev/mapper/dut mount /dev/mapper/dut /mnt fsfreeze --freeze /mnt # freeze_ucount == 1 dmsetup suspend dut # bd_fsfreeze_count == 1, ucount == 2 dmsetup resume dut # ucount 2 -> 1, but thaw_super() # returns -EINVAL, so bdev_thaw() # keeps bd_fsfreeze_count at 1 fsfreeze --unfreeze /mnt # filesystem thaws fine umount /mnt mount /dev/mapper/dut /mnt # EBUSY, forever
The same happens with fsfreeze held across an LVM snapshot of the origin volume.
fs_bdev_thaw()'s documentation already describes the intended semantics: "If this function returns zero it doesn't mean that the filesystem is unfrozen as it may have been frozen multiple times". Restore them by returning 0 when a nested thaw drops its hold while other freezers remain. Thawing without holding a freeze still fails with -EINVAL as may_unfreeze() rejects that case before the reference count is touched.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 09/25/2026
The Linux kernel filesystem subsystem contains a logic error in the superblock freezing mechanism introduced by commit 7366f8b6fc6a, which refactored freeze_holders from a bitmask to per-holder counters to support nested freezes. This change inadvertently altered the return value semantics of thaw_super_locked(), causing it to incorrectly report an invalid argument error when a thaw operation successfully releases its specific hold while other active freezers remain on the superblock. The function now returns -EINVAL instead of zero, despite the fact that the requested freeze reference was indeed decremented and the filesystem state transitioned correctly for that specific holder. This discrepancy violates the documented contract of fs_bdev_thaw(), which explicitly states that a return value of zero does not guarantee the filesystem is completely unfrozen if multiple holders exist.
This technical flaw has severe operational consequences, particularly in environments utilizing device-mapper or logical volume managers where block devices and filesystems are frozen independently but concurrently. When an application freezes a mounted filesystem using FIFREEZE and subsequently a kernel component such as dmsetup suspends the underlying block device via bdev_freeze(), two distinct freeze references are established on the superblock. Upon resuming the device, the system attempts to thaw both layers. The filesystem thaw succeeds in dropping its reference count but erroneously returns -EINVAL due to the lingering block device freeze hold. Consequently, the calling function bdev_thaw() interprets this error as a failure and fails to decrement the bd_fsfreeze_count for the block device layer. This results in a leaked frozen state where the internal counter remains elevated even though no active freezes should exist from the perspective of the user space application that initiated the initial freeze.
The impact manifests as an unrecoverable denial of service for the affected storage volume. After the user unmounts and attempts to remount the device, the kernel detects a non-zero bd_fsfreeze_count and rejects the mount operation with an EBUSY error, effectively locking the block device in a frozen state indefinitely. This condition persists until the system is rebooted or the specific device-mapper target is destroyed, as there is no standard userspace mechanism to manually reset this internal kernel counter. The vulnerability affects any configuration where filesystem freezing and block device suspension are used together, including common setups involving LVM snapshots or logical volume management tools that rely on precise freeze-thaw synchronization for consistency checks or backups.
From a classification perspective, this issue represents an improper check before removing resources, aligning with CWE-481: Incorrect Assignment of Operational Value. The error lies in the misinterpretation of state transitions during resource deallocation, where success is incorrectly flagged as failure based on incomplete context regarding other active holders. In terms of attack surface and behavior, this vulnerability facilitates a local denial-of-service scenario by allowing an unprivileged or privileged user to exhaust available mount points for specific block devices through simple freeze-unfreeze cycles combined with device suspension operations. This aligns with MITRE ATT&CK technique T1499: Endpoint Denial of Service, specifically under the sub-category of resource exhaustion via logical errors rather than brute force.
To mitigate this vulnerability, system administrators and developers must ensure that kernel versions are updated to include the fix for thaw_super_locked() return value logic. The patch corrects the function to return zero when a nested thaw successfully drops its hold, regardless of whether other freezers remain active. This restores consistency with fs_bdev_thaw documentation and ensures proper reference counting across both filesystem and block device layers. For systems running affected kernel versions prior to this fix, workarounds involve avoiding concurrent use of FIFREEZE on mounted filesystems while simultaneously suspending the underlying block devices via dmsetup or similar tools. Additionally, monitoring for EBUSY errors during mount operations can help identify instances where this leak has occurred, allowing for manual intervention such as unbinding and rebinding the device driver to reset internal counters if a reboot is not immediately feasible.