[PATCH 10/10] ufs: refuse read-write mount of check-hashed filesystems
Ali Ahmet Memis <[email protected]> Sat, 1 Aug 2026 22:55:30 +0000
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Modern UFS2 protects metadata with check hashes. fs_metackhash says which kinds are in use, CK_SUPERBLOCK, CK_CYLGRP, CK_INODE, CK_INDIR and CK_DIR, and the hashes themselves live in fs_ckhash, cg_ckhash and di_ckhash. FreeBSD recomputes them on every metadata write, for inodes in ffs_update() right before the inode goes to disk, and treats a mismatch as an integrity failure. Linux knows about none of these fields. It happily allocates blocks, changes inodes and rewrites cylinder groups without touching a single hash, so an ordinary touch /mnt/x chmod 600 /mnt/x leaves the filesystem valid by its own rules but failing every check hash it advertises. Back on FreeBSD that surfaces as inode, cylinder group and superblock check-hash failures on a filesystem that was never damaged in any other way. Implementing the hashes is a lot more work than this series is doing, so stay read-only instead. Both the flag and a non-zero fs_metackhash are required, so a filesystem that advertises the feature without actually maintaining any hash is still writable. This does change what userspace can do with an existing image: modern FreeBSD enables check hashes by default, so filesystems that mount read-write today will start coming up read-only. That is the point, but it is a policy call rather than a plain bug fix, and it is the one patch here that could be dropped without affecting the rest. Signed-off-by: Ali Ahmet Memis <[email protected]> --- fs/ufs/super.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 6132c28c4308..52de393aebe2 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -799,6 +799,11 @@ static bool ufs_features_allow_write(struct super_block *sb) return false; } } + if ((fsflags & UFS_FS_METACKHASH) && + fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_metackhash)) { + pr_err("%s(): fs uses metadata check hashes\n", __func__); + return false; + } return true; } -- 2.55.0