All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ana Bobillo <anabobillo3@gmail.com>
To: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.u-boot-project.org, Tony Dinh <mibodhi@gmail.com>,
	Simon Glass <sjg@chromium.org>
Subject: [PATCH 1/6] fs: ext4: refuse to write with an unexpected first data block
Date: Sun, 08 Nov 2026 15:11:58 +0000	[thread overview]
Message-ID: <d02a2d6f-89d9-48dd-93d0-c764fdf33e14@gmail.com> (raw)
In-Reply-To: <5072bec2-e2e3-405d-91eb-58fe78ea6669@gmail.com>

From: Ana Bobillo <anabobillo3@gmail.com>

ext4fs_blk_to_group() computes the block group of a block from
s_first_data_block, as Linux does. The rest of the write path takes the
first data block to be block 1 with 1 KiB blocks and block 0 otherwise,
which is what mke2fs makes: ext4fs_set_block_bmap() and
ext4fs_reset_block_bmap() find the bit of a block from the block number
alone, _get_new_blk_no() numbers the blocks of a group the same way, and
ext4fs_init() reads the group descriptor table from the block after it.

With any other s_first_data_block the two disagree, and the delete path
clears the bit of a block in the bitmap of another group. With 4 KiB
blocks and a first data block of 1, for example, block 32768 is in
group 0 for ext4fs_blk_to_group(), and ext4fs_reset_block_bmap() then
reads the byte just past the end of group 0's bitmap buffer and clears
a bit of it.

Add the first data block to the layout check of ext4fs_init(), so that
the write path refuses a filesystem whose first data block is not the
one it assumes, as it refuses other layouts its bitmap code cannot
handle. Linux refuses a first data block of 0 with 1 KiB blocks too,
unless clusters are larger.

Signed-off-by: Ana Bobillo <anabobillo3@gmail.com>
---
 fs/ext4/ext4_write.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 0cbbdc6c934..11d9957de11 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -617,6 +617,7 @@ int ext4fs_init(void)
 	struct ext2_sblock *sblock = &ext4fs_root->sblock;
 	uint32_t blk_per_grp = le32_to_cpu(sblock->blocks_per_group);
 	uint32_t inode_per_grp = le32_to_cpu(sblock->inodes_per_group);
+	uint32_t first_data_block = le32_to_cpu(sblock->first_data_block);
 
 	/* populate fs */
 	fs->blksz = EXT2_BLOCK_SIZE(ext4fs_root);
@@ -625,14 +626,20 @@ int ext4fs_init(void)
 	/*
 	 * The bitmap code finds the bitmap bits of group n at n * blocksize
 	 * bytes, so every group must hold one bitmap block's worth of
-	 * blocks, unless there is only one group. Check this before the
+	 * blocks, unless there is only one group. It also takes the first
+	 * data block, which holds the superblock, to be block 1 with 1 KiB
+	 * blocks and block 0 otherwise, as mke2fs makes it, and so does the
+	 * write path when it finds the group descriptor table; with any
+	 * other first data block, ext4fs_blk_to_group() puts a block in
+	 * another group than the bitmap code does. Check this before the
 	 * journal is replayed, so that nothing is written to a filesystem
 	 * that is refused.
 	 */
 	if (!blk_per_grp || blk_per_grp > fs->blksz * 8 ||
 	    (blk_per_grp != fs->blksz * 8 &&
-	     le32_to_cpu(sblock->total_blocks) -
-	     le32_to_cpu(sblock->first_data_block) > blk_per_grp) ||
+	     le32_to_cpu(sblock->total_blocks) - first_data_block >
+	     blk_per_grp) ||
+	    first_data_block != (fs->blksz == EXT2_MIN_BLOCK_SIZE) ||
 	    !inode_per_grp || inode_per_grp > fs->blksz * 8) {
 		printf("Unsupported block group layout, not writing\n");
 		return -EINVAL;

  reply	other threads:[~2026-11-08 15:12 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-08 15:11 [PATCH 0/6] fs: ext4: check on-disk values in the write path Ana Bobillo
2026-11-08 15:11 ` Ana Bobillo [this message]
2026-11-08 15:12 ` [PATCH 2/6] fs: ext4: use ext4fs_blk_to_group() in ext4fs_get_new_blk_no() Ana Bobillo
2026-11-08 15:12 ` [PATCH 3/6] fs: ext4: check directory entries before using them Ana Bobillo
2026-11-08 15:12 ` [PATCH 4/6] fs: ext4: bound the journal entry tables Ana Bobillo
2026-11-08 15:12 ` [PATCH 5/6] fs: ext4: stop the journal scan at the end of the log Ana Bobillo
2026-11-08 15:12 ` [PATCH 6/6] test: fs: ext4: add tests for the write path checks Ana Bobillo

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=d02a2d6f-89d9-48dd-93d0-c764fdf33e14@gmail.com \
    --to=anabobillo3@gmail.com \
    --cc=mibodhi@gmail.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.u-boot-project.org \
    /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.