git: ext2fs: pass dirbuf itself and the whole block to vn_rdwr in ext2_rename
Aaron LI
aly at crater.dragonflybsd.org
Fri Oct 23 06:19:05 PDT 2026
commit fc7d23c18d5d611575d546c728bc6608052539c0
Author: David Bidner <david at crap.solutions>
Date: Thu Oct 22 14:04:53 2026 +0200
ext2fs: pass dirbuf itself and the whole block to vn_rdwr in ext2_rename
ext2_rename() allocates a filesystem-block-sized buffer in dirbuf and
uses vn_rdwr() to read and rewrite the target directory's first block,
but passes (caddr_t)&dirbuf, the address of the pointer variable, and
only sizeof(struct dirtemplate) (24) bytes. vn_rdwr() therefore writes
the directory data over the pointer and 16 bytes of adjacent stack, and
the following dirbuf->dotdot_type read uses directory bytes as a pointer
address. The kernel takes a general protection fault in ext2_rename:
Fatal trap 9: general protection fault while in kernel mode
instruction pointer = 0x8:...8280e6b3 (ext2_rename+0x943)
A partial block is also wrong on checksummed filesystems:
ext2_dirent_csum_set() looks for the dirent tail at e2fs_bsize - 12,
which is zeroed memory outside the 24 bytes that were read, so the
directory checksum is left unchanged while the new ".." entry is
written.
Pass the buffer itself and e2fs_bsize for both the read and the write,
as FreeBSD's ext2fs does.
Reached when a directory is moved to a different parent directory, for
example mv a/x b/. Without a serial console this looks like a hang,
because the fault enters ddb, which then polls the VGA keyboard
indefinitely.
Bug: https://bugs.dragonflybsd.org/issues/3456
Summary of changes:
sys/vfs/ext2fs/ext2_vnops.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/fc7d23c18d5d611575d546c728bc6608052539c0
--
DragonFly BSD source repository
More information about the Commits
mailing list