Commit 4b53fff3 authored by Zhong Jinghua's avatar Zhong Jinghua Committed by Yongqiang Liu
Browse files

nbd: get config_lock before sock_shutdown

hulk inclusion
category: bugfix
bugzilla: 188799, https://gitee.com/openeuler/kernel/issues/I79QWO


CVE: NA

----------------------------------------

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.

Signed-off-by: default avatarZhong Jinghua <zhongjinghua@huawei.com>
Reviewed-by: default avatarYu Kuai <yukuai3@huawei.com>
Reviewed-by: default avatarHou Tao <houtao1@huawei.com>
Signed-off-by: default avatarYongqiang Liu <liuyongqiang13@huawei.com>
parent d9d1ff02
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -1347,11 +1347,16 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b
	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);
	flush_workqueue(nbd->recv_workq);

	mutex_lock(&nbd->config_lock);
	nbd_bdev_reset(bdev);
	/* user requested, ignore socket errors */
	if (test_bit(NBD_RT_DISCONNECT_REQUESTED, &config->runtime_flags))