lkml.org 
[lkml]   [2022]   [Aug]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 490/545] dm thin: fix use-after-free crash in dm_sm_register_threshold_callback
    Date
    From: Luo Meng <luomeng12@huawei.com>

    [ Upstream commit 3534e5a5ed2997ca1b00f44a0378a075bd05e8a3 ]

    Fault inject on pool metadata device reports:
    BUG: KASAN: use-after-free in dm_pool_register_metadata_threshold+0x40/0x80
    Read of size 8 at addr ffff8881b9d50068 by task dmsetup/950

    CPU: 7 PID: 950 Comm: dmsetup Tainted: G W 5.19.0-rc6 #1
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-1.fc33 04/01/2014
    Call Trace:
    <TASK>
    dump_stack_lvl+0x34/0x44
    print_address_description.constprop.0.cold+0xeb/0x3f4
    kasan_report.cold+0xe6/0x147
    dm_pool_register_metadata_threshold+0x40/0x80
    pool_ctr+0xa0a/0x1150
    dm_table_add_target+0x2c8/0x640
    table_load+0x1fd/0x430
    ctl_ioctl+0x2c4/0x5a0
    dm_ctl_ioctl+0xa/0x10
    __x64_sys_ioctl+0xb3/0xd0
    do_syscall_64+0x35/0x80
    entry_SYSCALL_64_after_hwframe+0x46/0xb0

    This can be easily reproduced using:
    echo offline > /sys/block/sda/device/state
    dd if=/dev/zero of=/dev/mapper/thin bs=4k count=10
    dmsetup load pool --table "0 20971520 thin-pool /dev/sda /dev/sdb 128 0 0"

    If a metadata commit fails, the transaction will be aborted and the
    metadata space maps will be destroyed. If a DM table reload then
    happens for this failed thin-pool, a use-after-free will occur in
    dm_sm_register_threshold_callback (called from
    dm_pool_register_metadata_threshold).

    Fix this by in dm_pool_register_metadata_threshold() by returning the
    -EINVAL error if the thin-pool is in fail mode. Also fail pool_ctr()
    with a new error message: "Error registering metadata threshold".

    Fixes: ac8c3f3df65e4 ("dm thin: generate event when metadata threshold passed")
    Cc: stable@vger.kernel.org
    Reported-by: Hulk Robot <hulkci@huawei.com>
    Signed-off-by: Luo Meng <luomeng12@huawei.com>
    Signed-off-by: Mike Snitzer <snitzer@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/md/dm-thin-metadata.c | 7 +++++--
    drivers/md/dm-thin.c | 4 +++-
    2 files changed, 8 insertions(+), 3 deletions(-)

    diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
    index 6ebb2127f3e2..842d79e5ea3a 100644
    --- a/drivers/md/dm-thin-metadata.c
    +++ b/drivers/md/dm-thin-metadata.c
    @@ -2058,10 +2058,13 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
    dm_sm_threshold_fn fn,
    void *context)
    {
    - int r;
    + int r = -EINVAL;

    pmd_write_lock_in_core(pmd);
    - r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context);
    + if (!pmd->fail_io) {
    + r = dm_sm_register_threshold_callback(pmd->metadata_sm,
    + threshold, fn, context);
    + }
    pmd_write_unlock(pmd);

    return r;
    diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
    index fff4c50df74d..a196d7cb51bd 100644
    --- a/drivers/md/dm-thin.c
    +++ b/drivers/md/dm-thin.c
    @@ -3401,8 +3401,10 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
    calc_metadata_threshold(pt),
    metadata_low_callback,
    pool);
    - if (r)
    + if (r) {
    + ti->error = "Error registering metadata threshold";
    goto out_flags_changed;
    + }

    dm_pool_register_pre_commit_callback(pool->pmd,
    metadata_pre_commit_callback, pool);
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-19 18:48    [W:4.944 / U:0.260 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site