All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baokun Li <libaokun1@huawei.com>
To: <stable@vger.kernel.org>, <linux-ext4@vger.kernel.org>
Cc: <gregkh@linuxfoundation.org>, <tytso@mit.edu>,
	<adilger.kernel@dilger.ca>, <jack@suse.cz>,
	<ritesh.list@gmail.com>, <lczerner@redhat.com>,
	<enwlinux@gmail.com>, <linux-kernel@vger.kernel.org>,
	<yi.zhang@huawei.com>, <yebin10@huawei.com>, <yukuai3@huawei.com>,
	<libaokun1@huawei.com>, Hulk Robot <hulkci@huawei.com>
Subject: [PATCH 4.19] ext4: fix race condition between ext4_ioctl_setflags and ext4_fiemap
Date: Fri, 15 Jul 2022 10:39:28 +0800	[thread overview]
Message-ID: <20220715023928.2701166-1-libaokun1@huawei.com> (raw)

This patch and problem analysis is based on v4.19 LTS.
The d3b6f23f7167("ext4: move ext4_fiemap to use iomap framework") patch
is incorporated in v5.7-rc1. This patch avoids this problem by switching
to iomap in ext4_fiemap.

Hulk Robot reported a BUG on stable 4.19.252:
==================================================================
kernel BUG at fs/ext4/extents_status.c:762!
invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 7 PID: 2845 Comm: syz-executor Not tainted 4.19.252 #46
RIP: 0010:ext4_es_cache_extent+0x30e/0x370
[...]
Call Trace:
 ext4_cache_extents+0x238/0x2f0
 ext4_find_extent+0x785/0xa40
 ext4_fiemap+0x36d/0xe90
 do_vfs_ioctl+0x6af/0x1200
[...]
==================================================================

Above issue may happen as follows:
-------------------------------------
           cpu1		    cpu2
_____________________|_____________________
do_vfs_ioctl
 ext4_ioctl
  ext4_ioctl_setflags
   ext4_ind_migrate
                        do_vfs_ioctl
                         ioctl_fiemap
                          ext4_fiemap
                           ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)
                           ext4_fill_fiemap_extents
    down_write(&EXT4_I(inode)->i_data_sem);
    ext4_ext_check_inode
    ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS)
    memset(ei->i_data, 0, sizeof(ei->i_data))
    up_write(&EXT4_I(inode)->i_data_sem);
                            down_read(&EXT4_I(inode)->i_data_sem);
                            ext4_find_extent
                             ext4_cache_extents
                              ext4_es_cache_extent
                               BUG_ON(end < lblk)

We can easily reproduce this problem with the syzkaller testcase:
```
02:37:07 executing program 3:
r0 = openat(0xffffffffffffff9c, &(0x7f0000000040)='./file0\x00', 0x26e1, 0x0)
ioctl$FS_IOC_FSSETXATTR(r0, 0x40086602, &(0x7f0000000080)={0x17e})
mkdirat(0xffffffffffffff9c, &(0x7f00000000c0)='./file1\x00', 0x1ff)
r1 = openat(0xffffffffffffff9c, &(0x7f0000000100)='./file1\x00', 0x0, 0x0)
ioctl$FS_IOC_FIEMAP(r1, 0xc020660b, &(0x7f0000000180)={0x0, 0x1, 0x0, 0xef3, 0x6, []}) (async, rerun: 32)
ioctl$FS_IOC_FSSETXATTR(r1, 0x40086602, &(0x7f0000000140)={0x17e}) (rerun: 32)
```

To solve this issue, we use __generic_block_fiemap() instead of
generic_block_fiemap() and add inode_lock_shared to avoid race condition.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
---
 fs/ext4/extents.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 6c492fca60c4..38aaf48e94cb 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -5198,13 +5198,18 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 			return error;
 	}
 
+	inode_lock_shared(inode);
 	/* fallback to generic here if not in extents fmt */
-	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-		return generic_block_fiemap(inode, fieinfo, start, len,
+	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
+		error = __generic_block_fiemap(inode, fieinfo, start, len,
 			ext4_get_block);
+		goto out_unlock;
+	}
 
-	if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS))
-		return -EBADR;
+	if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS)) {
+		error = -EBADR;
+		goto out_unlock;
+	}
 
 	if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
 		error = ext4_xattr_fiemap(inode, fieinfo);
@@ -5225,6 +5230,8 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 		error = ext4_fill_fiemap_extents(inode, start_blk,
 						 len_blks, fieinfo);
 	}
+out_unlock:
+	inode_unlock_shared(inode);
 	return error;
 }
 
-- 
2.31.1


             reply	other threads:[~2022-07-15  2:27 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-15  2:39 Baokun Li [this message]
2022-07-15 14:10 ` [PATCH 4.19] ext4: fix race condition between ext4_ioctl_setflags and ext4_fiemap Greg KH
2022-07-16  2:33   ` Baokun Li
2022-07-19 11:26     ` Greg KH
2022-07-19 12:15       ` Baokun Li
2022-07-19 12:25         ` Greg KH
2022-07-19 18:57           ` Theodore Ts'o
2022-07-19 19:14             ` Greg KH
2022-07-20  2:04               ` Baokun Li
2022-07-19 14:06       ` Theodore Ts'o
2022-07-20  1:52         ` Baokun Li

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=20220715023928.2701166-1-libaokun1@huawei.com \
    --to=libaokun1@huawei.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=enwlinux@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hulkci@huawei.com \
    --cc=jack@suse.cz \
    --cc=lczerner@redhat.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ritesh.list@gmail.com \
    --cc=stable@vger.kernel.org \
    --cc=tytso@mit.edu \
    --cc=yebin10@huawei.com \
    --cc=yi.zhang@huawei.com \
    --cc=yukuai3@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.