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