Re: [PATCH] jfs: validate dmap start before block allocation
From: Bartosz Chronowski
Date: Mon Oct 26 2026 - 12:16:09 EST
Gentle ping on this JFS patch. Is there anything you would like changed
before it can be queued?
Kind Regards / Mit freundlichen Grüßen
BART CHRONOWSKI
On Wed, Sep 30, 2026 at 10:25:08AM +0000, syzbot wrote:
> From: Bartosz Chronowski <immersa.bartosz.chronowski@xxxxxxxxx>
>
> A corrupted JFS filesystem image can cause a state where the block
> allocation map (bmap) and the dmap pages are out of sync. Specifically,
> dbAllocNear() and dbAllocDmapLev() derive the returned block number from
> on-disk dp->start, which can cause duplicate allocation if dp->start does
> not match the selected dmap boundary. In this scenario, the allocator
> returns a block number that is already in use (e.g., as an inode table
> block or metadata) while marking a completely different block as allocated.
> When a thread later attempts to lock this duplicate block (for example,
> during a directory btree split), txLock() detects a metapage conflict
> because the block is already locked for another purpose, triggering a
> kernel BUG:
>
> kernel BUG at fs/jfs/jfs_txnmgr.c:836!
> Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
> RIP: 0010:txLock+0x1cc3/0x1d10 fs/jfs/jfs_txnmgr.c:836
> Call Trace:
> <TASK>
> dtSplitRoot+0x38d/0x18a0 fs/jfs/jfs_dtree.c:1924
> dtSplitUp fs/jfs/jfs_dtree.c:990 [inline]
> dtInsert+0xeb2/0x5890 fs/jfs/jfs_dtree.c:868
> jfs_create+0x730/0xae0 fs/jfs/namei.c:138
> ...
>
> Validation of dp->start against the expected dmap boundary in dbAlloc() and
> the single-dmap path of dbAllocCtl() prevents inconsistent allocation.
> Rejecting a mismatched start with -EIO prevents duplicate allocations
> before txLock() is reached. Additionally, preserve the existing independent
> geometry check (dp->tree.budmin < 0) in dbAllocCtl(). Both a mismatched
> start and a negative budmin will now fail with -EIO early, preventing
> corrupted dmap structures from causing duplicate allocations and subsequent
> transaction lock crashes.
>
> Assisted-by: Gemini:gemini-3.8-flash syzbot
> Reported-by: syzbot+a843f6ae2130a987d63b@xxxxxxxxxxxxxxxxxxxxxxxxx
> Closes: https://syzkaller.appspot.com/bug?extid=a843f6ae2130a987d63b
> Link: https://syzkaller.appspot.com/ai_job?id=922ceb61-4be2-4af9-b2fe-9977a2549134
> Signed-off-by: Bartosz Chronowski <immersa.bartosz.chronowski@xxxxxxxxx>
>
> ---
> diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
> index a841cf21d..9bdbc55d8 100644
> --- a/fs/jfs/jfs_dmap.c
> +++ b/fs/jfs/jfs_dmap.c
> @@ -98,6 +98,9 @@ static int blkstol2(s64 nb);
> static int cntlz(u32 value);
> static int cnttz(u32 word);
>
> +static bool db_validate_dmap(struct super_block *sb, const struct dmap *dp,
> + s64 expected_start);
> +
> static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
> int nblocks);
> static int dbInitDmap(struct dmap * dp, s64 blkno, int nblocks);
> @@ -886,6 +889,12 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
>
> dp = (struct dmap *) mp->data;
>
> + if (!db_validate_dmap(ip->i_sb, dp,
> + blkno & ~(s64)(BPERDMAP - 1))) {
> + release_metapage(mp);
> + goto read_unlock;
> + }
> +
> /* first, try to satisfy the allocation request with the
> * blocks beginning at the hint.
> */
> @@ -1902,7 +1911,9 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
> return -EIO;
> dp = (struct dmap *) mp->data;
>
> - if (dp->tree.budmin < 0) {
> + if (dp->tree.budmin < 0 ||
> + !db_validate_dmap(bmp->db_ipbmap->i_sb, dp,
> + blkno & ~(s64)(BPERDMAP - 1))) {
> release_metapage(mp);
> return -EIO;
> }
> @@ -2134,6 +2145,18 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
> return (rc);
> }
>
> +static bool db_validate_dmap(struct super_block *sb, const struct dmap *dp,
> + s64 expected_start)
> +{
> + if (le64_to_cpu(dp->start) != expected_start) {
> + jfs_error(sb, "corrupt dmap page: start %lld expected %lld\n",
> + (long long)le64_to_cpu(dp->start),
> + (long long)expected_start);
> + return false;
> + }
> +
> + return true;
> +}
>
> /*
> * NAME: dbFreeDmap()
>
>
> base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
> --
> See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
> The person who has signed off on the patch is responsible for
> addressing comments.
> syzbot engineers can be reached at syzkaller@xxxxxxxxxxxxxxxx.