All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Christian Brauner" <brauner@kernel.org>
Cc: "Joel Becker" <jlbec@evilplan.org>,
	"Joseph Qi" <joseph.qi@linux.alibaba.com>,
	"Mark Fasheh" <mark@fasheh.com>,
	linux-ext4@vger.kernel.org, dsterba@suse.cz, tytso@mit.edu
Subject: Re: [PATCH RFC 09/28] hfs: don't set SB_RDONLY after MDB write errors
Date: Mon, 12 Oct 2026 10:41:34 +0000	[thread overview]
Message-ID: <sashiko-outbox-167974@kernel.org> (raw)
In-Reply-To: <20261012-work-fs-sb_rdonly-v1-9-60743a3dc326@kernel.org>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] hfs: mmap writes bypass emergency read-only enforcement
- [High] hfs: b-tree corruption on mount due to mismatched MDB and b-tree header
--

commit 438a15bb409c797940d5b4b61b0567260f26030a
Author: Christian Brauner <brauner@kernel.org>

    hfs: don't set SB_RDONLY after MDB write errors
    
    Since commit fdbb95ff89b2 ("hfs: don't re-dirty MDB buffers after a
    write failure") hfs_mdb_commit() sets SB_RDONLY when the MDB or the
    alternate MDB buffer lost BH_Uptodate after a failed write.

[ ... ]

> diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
> index f066a99a863bc..dab31f159b1aa 100644
> --- a/fs/hfs/extent.c
> +++ b/fs/hfs/extent.c
> @@ -350,6 +350,9 @@ int hfs_get_block(struct inode *inode, sector_t block,
>  		if (block > HFS_I(inode)->fs_blocks)
>  			return -EIO;
>  		if (ablock >= HFS_I(inode)->alloc_blocks) {
> +			/* No new allocations after an error. */
> +			if (unlikely(hfs_emergency_ro(sb)))
> +				return -EROFS;
>  			res = hfs_extend_file(inode);
>  			if (res)
>  				return res;

[Severity: High]
Does this code allow data modification on a filesystem in an emergency
read-only state?

If a user memory-maps a file with PROT_WRITE and modifies the pages after the
filesystem enters the emergency read-only state, the page fault succeeds
because hfs does not override page_mkwrite to check hfs_emergency_ro().

When the VM triggers writeback, hfs_writepages() calls mpage_writepages(),
which calls hfs_get_block(). For existing file blocks where
ablock < HFS_I(inode)->alloc_blocks, hfs_get_block() bypasses this new check,
maps the block, and successfully writes dirty pages to disk, violating the
read-only guarantee.

[ ... ]

> diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
> index 2aef3c36a150a..42a2c2e390b23 100644
> --- a/fs/hfs/inode.c
> +++ b/fs/hfs/inode.c
> @@ -472,6 +479,20 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
>  	int res;
>  
>  	hfs_dbg("ino %llu\n", inode->i_ino);
> +	if (unlikely(hfs_emergency_ro(inode->i_sb))) {
> +		/*
> +		 * Writeback still writes the b-tree nodes. Keep the headers in
> +		 * sync with them so the trees on disk stay intact.
> +		 */
> +		if (inode->i_ino == HFS_EXT_CNID)
> +			hfs_btree_write(HFS_SB(inode->i_sb)->ext_tree);
> +		else if (inode->i_ino == HFS_CAT_CNID)
> +			hfs_btree_write(HFS_SB(inode->i_sb)->cat_tree);
> +		else
> +			return -EROFS;
> +		return 0;
> +	}
> +

[ ... ]

> diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
> index 277de712f9d47..ce20824bbdc84 100644
> --- a/fs/hfs/mdb.c
> +++ b/fs/hfs/mdb.c
> @@ -338,12 +338,18 @@ int hfs_mdb_commit(struct super_block *sb)
>  	struct hfs_mdb *mdb = HFS_SB(sb)->mdb;
>  	int ret = 0;
>  
> -	if (sb_rdonly(sb))
> +	if (sb_rdonly(sb) || hfs_emergency_ro(sb))
>  		return 0;

[Severity: High]
Can writing the updated b-tree header in hfs_write_inode() but dropping
the MDB update here cause b-tree corruption on the next mount?

The commit message notes that b-tree growth through hfs_bmap_reserve() isn't
refused. If a read operation triggers a cache flush of an extent record,
allocating new physical blocks, the b-tree header is updated and written to
disk with an increased node_count.

However, since hfs_mdb_commit() now returns early when hfs_emergency_ro() is
true, the MDB is not updated on disk. This causes the on-disk MDB size fields
(such as drXTFlSize and drXTExtRec) to desync from the b-tree header.

On the next mount, the b-tree file size is initialized from the stale MDB and
is smaller than node_count * node_size. Accessing the newly allocated nodes
reads past EOF, which the VFS zero-fills, resulting in -EIO during tree
traversal. Furthermore, the newly allocated blocks are not marked as used in
the MDB bitmap, leading to potential data overwrites.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261012-work-fs-sb_rdonly-v1-0-60743a3dc326@kernel.org?part=9

  reply	other threads:[~2026-10-12 10:41 UTC|newest]

Thread overview: 102+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-12 10:20 [PATCH RFC 00/28] fs: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-12 10:20 ` Christian Brauner
2026-10-12 10:20 ` [PATCH RFC 01/28] ecryptfs: don't leak the inode when a lookup can't open the lower file Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:34   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 02/28] ecryptfs: fall back to a read-only " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:32   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 03/28] ext2: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:44   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 04/28] jfs: " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:41   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 05/28] nilfs2: " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:34   ` sashiko-bot
2026-10-13 16:01   ` Ryusuke Konishi
2026-10-13 16:01     ` Ryusuke Konishi
2026-10-12 10:20 ` [PATCH RFC 06/28] fat: " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:37   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 07/28] exfat: keep the current mount options on remount Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:36   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 08/28] exfat: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:35   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 09/28] hfs: don't set SB_RDONLY after MDB write errors Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:41   ` sashiko-bot [this message]
2026-10-12 22:57   ` [Jfs-discussion] " Viacheslav Dubeyko
2026-10-12 22:57     ` Viacheslav Dubeyko
2026-10-12 10:20 ` [PATCH RFC 10/28] hfsplus: don't set SB_RDONLY when creating the attributes tree Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:36   ` sashiko-bot
2026-10-12 22:34   ` [Jfs-discussion] " Viacheslav Dubeyko
2026-10-12 22:34     ` Viacheslav Dubeyko
2026-10-12 10:20 ` [PATCH RFC 11/28] affs: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:41   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 12/28] ufs: " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:39   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 13/28] hpfs: " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:35   ` sashiko-bot
2026-10-12 10:20 ` [PATCH RFC 14/28] ntfs: " Christian Brauner
2026-10-12 10:20   ` Christian Brauner
2026-10-12 10:45   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 15/28] ocfs2: keep options that can't change on remount Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:45   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 16/28] ocfs2: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:59   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 17/28] zonefs: don't set SB_RDONLY after I/O errors Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:42   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 18/28] btrfs: check BTRFS_FS_STATE_RO instead of SB_RDONLY at runtime Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:53   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 19/28] btrfs: don't set SB_RDONLY after filesystem errors Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 11:05   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 20/28] gfs2: wait for a pending withdraw before remounting read-only Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:44   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 21/28] gfs2: don't set SB_RDONLY on withdraw Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:48   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 22/28] efivarfs: stop using SB_RDONLY for read-only efivar ops Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:52   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 23/28] ubifs: don't set SB_RDONLY after errors Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 11:05   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 24/28] selftests/filesystems: test filesystem errors while frozen Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:47   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 25/28] ext4: allow remounting read-only in the emergency state Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:49   ` sashiko-bot
2026-10-12 16:38   ` Jan Kara
2026-10-12 16:38     ` Jan Kara
2026-10-12 10:21 ` [PATCH RFC 26/28] selftests/filesystems: test ext4 remounts " Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:52   ` sashiko-bot
2026-10-12 10:21 ` [PATCH RFC 27/28] xfs: allow remounting read-only after a shutdown Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:55   ` sashiko-bot
2026-10-13  7:38   ` Christoph Hellwig
2026-10-13  7:38     ` Christoph Hellwig
2026-10-12 10:21 ` [PATCH RFC 28/28] selftests/filesystems: test xfs remounts " Christian Brauner
2026-10-12 10:21   ` Christian Brauner
2026-10-12 10:51   ` sashiko-bot
2026-10-13  7:40   ` Christoph Hellwig
2026-10-13  7:40     ` Christoph Hellwig
2026-10-12 16:53 ` [PATCH RFC 00/28] fs: don't set SB_RDONLY after filesystem errors Jan Kara
2026-10-12 16:53   ` Jan Kara
2026-10-13 19:39   ` Christian Brauner
2026-10-13 19:39     ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-167974@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=brauner@kernel.org \
    --cc=dsterba@suse.cz \
    --cc=jlbec@evilplan.org \
    --cc=joseph.qi@linux.alibaba.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=mark@fasheh.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.