From: Adriano Cordova <adrianox@gmail.com>
To: tytso@mit.edu
Cc: adilger.kernel@dilger.ca, libaokun@linux.alibaba.com,
jack@suse.cz, ojaswin@linux.ibm.com, ritesh.list@gmail.com,
yi.zhang@huawei.com, linux-ext4@vger.kernel.org,
linux-kernel@vger.kernel.org,
Adriano Cordova <adrianox@gmail.com>,
syzbot+09bec78ee77613a3efdd@syzkaller.appspotmail.com
Subject: [PATCH v2] ext4: don't append a directory block already mapped in the inode
Date: Sun, 4 Oct 2026 21:35:28 -0300 [thread overview]
Message-ID: <20261005003528.92046-1-adrianox@gmail.com> (raw)
ext4_append() grows a directory by one block. It checks that the target
logical block is a hole, but a corrupt block bitmap can still make the
allocator hand back a physical block that is already in use by this
inode. The in-memory copy of a block is keyed by its physical block
number, so the "new" block and that existing one are the same memory;
callers that split a directory (make_indexed_dir()/do_split()) then move
entries between two aliased buffers and corrupt the directory, until a
bogus rec_len read from the middle of a name runs the wipe out of bounds:
BUG: KASAN: slab-use-after-free in dx_move_dirents [inline]
Write of size 90458 ...
Reject the block and report the corrupt bitmap instead of corrupting
memory.
Reported-by: syzbot+09bec78ee77613a3efdd@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=09bec78ee77613a3efdd
Tested-by: syzbot+09bec78ee77613a3efdd@syzkaller.appspotmail.com
Signed-off-by: Adriano Cordova <adrianox@gmail.com>
---
Changes in v2:
- Rework after review of v1 ("ext4: wipe moved dirents with their real
length"). dx_make_map() already validates each entry, so the bad
rec_len does not come from disk. The problem is that the block
allocator was handing back a block already mapped by the inode.
fs/ext4/namei.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 3b9740c1c16d..ff6013306b74 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -83,6 +83,25 @@ static struct buffer_head *ext4_append(handle_t *handle,
bh = ext4_bread(handle, inode, *block, EXT4_GET_BLOCKS_CREATE);
if (IS_ERR(bh))
return bh;
+
+ for (map.m_lblk = 0; map.m_lblk < *block; map.m_lblk += map.m_len) {
+ map.m_len = *block - map.m_lblk;
+ err = ext4_map_blocks(NULL, inode, &map, 0);
+ if (err < 0)
+ goto out;
+ if (err == 0) {
+ map.m_len = 1;
+ continue;
+ }
+ if (unlikely(map.m_pblk == bh->b_blocknr)) {
+ EXT4_ERROR_INODE(inode,
+ "new block %llu already mapped",
+ (unsigned long long)bh->b_blocknr);
+ err = -EFSCORRUPTED;
+ goto out;
+ }
+ }
+
inode->i_size += inode->i_sb->s_blocksize;
EXT4_I(inode)->i_disksize = inode->i_size;
err = ext4_mark_inode_dirty(handle, inode);
--
2.51.0
next reply other threads:[~2026-10-05 0:35 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-05 0:35 Adriano Cordova [this message]
2026-10-05 0:46 ` [PATCH v2] ext4: don't append a directory block already mapped in the inode sashiko-bot
2026-10-05 11:15 ` Jan Kara
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=20261005003528.92046-1-adrianox@gmail.com \
--to=adrianox@gmail.com \
--cc=adilger.kernel@dilger.ca \
--cc=jack@suse.cz \
--cc=libaokun@linux.alibaba.com \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ojaswin@linux.ibm.com \
--cc=ritesh.list@gmail.com \
--cc=syzbot+09bec78ee77613a3efdd@syzkaller.appspotmail.com \
--cc=tytso@mit.edu \
--cc=yi.zhang@huawei.com \
/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.