lkml.org 
[lkml]   [2022]   [Jul]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 103/230] btrfs: dont access possibly stale fs_info data in device_list_add
    Date
    From: Dongliang Mu <mudongliangabcd@gmail.com>

    [ Upstream commit 79c9234ba596e903907de20573fd4bcc85315b06 ]

    Syzbot reported a possible use-after-free in printing information
    in device_list_add.

    Very similar with the bug fixed by commit 0697d9a61099 ("btrfs: don't
    access possibly stale fs_info data for printing duplicate device"),
    but this time the use occurs in btrfs_info_in_rcu.

    Call Trace:
    kasan_report.cold+0x83/0xdf mm/kasan/report.c:459
    btrfs_printk+0x395/0x425 fs/btrfs/super.c:244
    device_list_add.cold+0xd7/0x2ed fs/btrfs/volumes.c:957
    btrfs_scan_one_device+0x4c7/0x5c0 fs/btrfs/volumes.c:1387
    btrfs_control_ioctl+0x12a/0x2d0 fs/btrfs/super.c:2409
    vfs_ioctl fs/ioctl.c:51 [inline]
    __do_sys_ioctl fs/ioctl.c:874 [inline]
    __se_sys_ioctl fs/ioctl.c:860 [inline]
    __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:860
    do_syscall_x64 arch/x86/entry/common.c:50 [inline]
    do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
    entry_SYSCALL_64_after_hwframe+0x44/0xae

    Fix this by modifying device->fs_info to NULL too.

    Reported-and-tested-by: syzbot+82650a4e0ed38f218363@syzkaller.appspotmail.com
    CC: stable@vger.kernel.org # 4.19+
    Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
    Reviewed-by: David Sterba <dsterba@suse.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/btrfs/volumes.c | 13 ++++++-------
    1 file changed, 6 insertions(+), 7 deletions(-)

    diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
    index cec54c6e1cdd..89ce0b449c22 100644
    --- a/fs/btrfs/volumes.c
    +++ b/fs/btrfs/volumes.c
    @@ -955,6 +955,11 @@ static noinline struct btrfs_device *device_list_add(const char *path,
    /*
    * We are going to replace the device path for a given devid,
    * make sure it's the same device if the device is mounted
    + *
    + * NOTE: the device->fs_info may not be reliable here so pass
    + * in a NULL to message helpers instead. This avoids a possible
    + * use-after-free when the fs_info and fs_info->sb are already
    + * torn down.
    */
    if (device->bdev) {
    int error;
    @@ -968,12 +973,6 @@ static noinline struct btrfs_device *device_list_add(const char *path,

    if (device->bdev->bd_dev != path_dev) {
    mutex_unlock(&fs_devices->device_list_mutex);
    - /*
    - * device->fs_info may not be reliable here, so
    - * pass in a NULL instead. This avoids a
    - * possible use-after-free when the fs_info and
    - * fs_info->sb are already torn down.
    - */
    btrfs_warn_in_rcu(NULL,
    "duplicate device %s devid %llu generation %llu scanned by %s (%d)",
    path, devid, found_transid,
    @@ -981,7 +980,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
    task_pid_nr(current));
    return ERR_PTR(-EEXIST);
    }
    - btrfs_info_in_rcu(device->fs_info,
    + btrfs_info_in_rcu(NULL,
    "devid %llu device path %s changed to %s scanned by %s (%d)",
    devid, rcu_str_deref(device->name),
    path, current->comm,
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-07-11 11:50    [W:4.144 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site