From 4c2fb1cc1848790735cb6bc78b5dfb8a30d326c2 Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Thu, 18 Apr 2024 14:39:46 +0800 Subject: [PATCH] e2fsck: fix acl block leak when process orphan list There's a issue: []$~/e2fsprogs/e2fsck/e2fsck -f scsi-disk2.img e2fsck 1.47.0 (5-Feb-2023) scsi-disk2.img: recovering journal Clearing orphaned inode 12 (uid=0, gid=0, mode=0140777, size=0) Pass 1: Checking inodes, blocks, and sizes Extended attribute block 4247 has reference count 3, should be 2. Fix? no Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information Free blocks count wrong (249189, counted=249188). Fix? no Free inodes count wrong (65526, counted=65523). Fix? no scsi-disk2.img: ***** FILE SYSTEM WAS MODIFIED ***** scsi-disk2.img: ********** WARNING: Filesystem still has errors ********** scsi-disk2.img: 10/65536 files (0.0% non-contiguous), 12955/262144 blocks Above issue can reproduce as follows: step1: socat UNIX-LISTEN:/home/test/mysocket.sock,mode=777,reuseaddr,fork EXEC:/home/test & step2: setfacl some xattr for mysocket.sock step3: cp -a /home/test/mysocket.sock /home/test/sock1 cp -a /home/test/mysocket.sock /home/test/sock2 step4: sync step5: Power-off step6: run e2fsck As after commit 42475e281d22 add ext2fs_inode_has_valid_blocks() judgement in release_inode_blocks() which means socket type file skip realse block include ACL block. The kernel does not restrict the setting of extended attributes for socket files. So this will lead to ACL block leak. To solve above issue there's need to release ACL block for other kind of special file. Fixes: 42475e281d22 ("super.c (release_inode_blocks): Don't try to release the blocks if the orphaned inode is a device file, symlink, or some other kind of special file that doesn't have a block list.") Signed-off-by: Ye Bin Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20240418063946.2802835-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o --- e2fsck/super.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2fsck/super.c b/e2fsck/super.c index 60c690c..04d6dde 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -196,7 +196,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, __u32 count; if (!ext2fs_inode_has_valid_blocks2(fs, EXT2_INODE(inode))) - return 0; + goto release_acl; pb.buf = block_buf + 3 * ctx->fs->blocksize; pb.ctx = ctx; @@ -235,7 +235,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, if (pb.truncated_blocks) ext2fs_iblk_sub_blocks(fs, EXT2_INODE(inode), pb.truncated_blocks); - +release_acl: blk = ext2fs_file_acl_block(fs, EXT2_INODE(inode)); if (blk) { retval = ext2fs_adjust_ea_refcount3(fs, blk, block_buf, -1, -- 1.8.3.1