>From aafde8a3ce496f06fcb33909631bbe72a5e8d84e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20Z=C3=BChlsdorf?= Date: Thu, 24 Aug 2023 21:56:29 +0200 Subject: [PATCH] ext2fs: Fix initialization of orphan file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On block devices where discard produces random looking data instead of NULs, creating a file system fails: mke2fs 1.47.0 (5-Feb-2023) Discarding device blocks: done Creating filesystem with 4194304 4k blocks and 1048576 inodes Filesystem UUID: d379784e-c92d-431f-b527-c4088299a914 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done mke2fs: Inode checksum does not match inode while creating orphan file This is caused by ext2fs_create_orphan_file's call to ext2fs_read_inode() which is reading effectively uninitialized data, as the inode created just above hasn't been written to disk yet. Devices where discarding produces NULs are not affected as ext2fs_read_inode() returns a zeroed-out struct ext2_inode, for which the checksum calculation has a special case masking this bug. Make sure the inode is not read when it is not yet written. Fixes: 1d551c68 ("libext2fs: Support for orphan file feature") Signed-off-by: Sven Zühlsdorf Signed-off-by: Jan Kara --- lib/ext2fs/orphan.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c index e25f20ca247c..be27a086679b 100644 --- a/lib/ext2fs/orphan.c +++ b/lib/ext2fs/orphan.c @@ -134,24 +134,23 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks) return err; ext2fs_inode_alloc_stats2(fs, ino, +1, 0); ext2fs_mark_ib_dirty(fs); - } - - err = ext2fs_read_inode(fs, ino, &inode); - if (err) - return err; - if (EXT2_I_SIZE(&inode)) { - err = ext2fs_truncate_orphan_file(fs); + } else { + err = ext2fs_read_inode(fs, ino, &inode); if (err) return err; + if (EXT2_I_SIZE(&inode)) { + err = ext2fs_truncate_orphan_file(fs); + if (err) + return err; + } } memset(&inode, 0, sizeof(struct ext2_inode)); - if (ext2fs_has_feature_extents(fs->super)) { + if (ext2fs_has_feature_extents(fs->super)) inode.i_flags |= EXT4_EXTENTS_FL; - err = ext2fs_write_inode(fs, ino, &inode); - if (err) - return err; - } + err = ext2fs_write_new_inode(fs, ino, &inode); + if (err) + return err; err = ext2fs_get_mem(fs->blocksize, &buf); if (err) @@ -194,7 +193,7 @@ errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks) (unsigned long long)fs->blocksize * num_blocks); if (err) goto out; - err = ext2fs_write_new_inode(fs, ino, &inode); + err = ext2fs_write_inode(fs, ino, &inode); if (err) goto out; -- 2.35.3