There is one use-after-free warning when running NBD_CMD_CONNECT and
NBD_CLEAR_SOCK:
nbd_genl_connect
nbd_alloc_and_init_config // config_refs=1
nbd_start_device // config_refs=2
set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3
recv_work done // config_refs=2
NBD_CLEAR_SOCK // config_refs=1
close nbd // config_refs=0
refcount_inc -> uaf
------------[ cut here ]------------
refcount_t: addition on 0; use-after-free.
WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290
nbd_genl_connect+0x16d0/0x1ab0
genl_family_rcv_msg_doit+0x1f3/0x310
genl_rcv_msg+0x44a/0x790
The issue can be easily reproduced by adding a small delay before
refcount_inc(&nbd->config_refs) in nbd_genl_connect():
mutex_unlock(&nbd->config_lock);
if (!ret) {
set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags);
+ printk("before sleep\n");
+ mdelay(5 * 1000);
+ printk("after sleep\n");
refcount_inc(&nbd->config_refs);
nbd_connect_reply(info, nbd->index);
}
Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface")
Signed-off-by: Zheng Qixing <zhengqixing@huawei.com>
Reviewed-by: Yu Kuai <yukuai@fnnas.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
ret = nbd_start_device(nbd);
out:
- mutex_unlock(&nbd->config_lock);
if (!ret) {
set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags);
refcount_inc(&nbd->config_refs);
nbd_connect_reply(info, nbd->index);
}
+ mutex_unlock(&nbd->config_lock);
+
nbd_config_put(nbd);
if (put_dev)
nbd_put(nbd);