[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <779966af-844a-3dba-93f8-9daabde8c85b@huaweicloud.com>
Date: Fri, 28 Jul 2023 15:10:38 +0800
From: Yu Kuai <yukuai1@...weicloud.com>
To: Zhong Jinghua <zhongjinghua@...weicloud.com>, josef@...icpanda.com,
axboe@...nel.dk
Cc: linux-block@...r.kernel.org, nbd@...er.debian.org,
linux-kernel@...r.kernel.org, yi.zhang@...wei.com,
"yukuai (C)" <yukuai3@...wei.com>
Subject: Re: [PATCH -next] nbd: get config_lock before sock_shutdown
在 2023/07/07 14:22, Zhong Jinghua 写道:
> Config->socks in sock_shutdown may trigger a UAF problem.
> The reason is that sock_shutdown does not hold the config_lock,
> so that nbd_ioctl can release config->socks at this time.
>
> T0: NBD_SET_SOCK
> T1: NBD_DO_IT
>
> T0 T1
>
> nbd_ioctl
> mutex_lock(&nbd->config_lock)
> // get lock
> __nbd_ioctl
> nbd_start_device_ioctl
> nbd_start_device
> mutex_unlock(&nbd->config_lock)
> // relase lock
> wait_event_interruptible
> (kill, enter sock_shutdown)
> sock_shutdown
> nbd_ioctl
> mutex_lock(&nbd->config_lock)
> // get lock
> __nbd_ioctl
> nbd_add_socket
> krealloc
> kfree(p)
> //config->socks is NULL
> nbd_sock *nsock = config->socks // error
>
> Fix it by moving config_lock up before sock_shutdown.
LGTM
Reviewed-by: Yu Kuai <yukuai3@...wei.com>
>
> Signed-off-by: Zhong Jinghua <zhongjinghua@...weicloud.com>
> ---
> drivers/block/nbd.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index c410cf29fb0c..accbe99ebb7e 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -1428,13 +1428,18 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd)
> mutex_unlock(&nbd->config_lock);
> ret = wait_event_interruptible(config->recv_wq,
> atomic_read(&config->recv_threads) == 0);
> +
> + /*
> + * recv_work in flush_workqueue will not get this lock, because nbd_open
> + * will hold nbd->config_refs
> + */
> + mutex_lock(&nbd->config_lock);
> if (ret) {
> sock_shutdown(nbd);
> nbd_clear_que(nbd);
> }
>
> flush_workqueue(nbd->recv_workq);
> - mutex_lock(&nbd->config_lock);
> nbd_bdev_reset(nbd);
> /* user requested, ignore socket errors */
> if (test_bit(NBD_RT_DISCONNECT_REQUESTED, &config->runtime_flags))
>
Powered by blists - more mailing lists