diff options
author | Zheng Bin <zhengbin13@huawei.com> | 2020-06-29 09:23:49 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-07-22 09:22:17 +0200 |
commit | 3373994d658f6b4ed3b58b344ce0ab32f720e608 (patch) | |
tree | 7676ff77a48b9379d7b37608440eaa9b003f2f2d /drivers/block | |
parent | 7f3efcf16a11c159824a3fb8c6fc99314d0f067b (diff) | |
download | linux-stable-3373994d658f6b4ed3b58b344ce0ab32f720e608.tar.gz linux-stable-3373994d658f6b4ed3b58b344ce0ab32f720e608.tar.bz2 linux-stable-3373994d658f6b4ed3b58b344ce0ab32f720e608.zip |
nbd: Fix memory leak in nbd_add_socket
[ Upstream commit 579dd91ab3a5446b148e7f179b6596b270dace46 ]
When adding first socket to nbd, if nsock's allocation failed, the data
structure member "config->socks" was reallocated, but the data structure
member "config->num_connections" was not updated. A memory leak will occur
then because the function "nbd_config_put" will free "config->socks" only
when "config->num_connections" is not zero.
Fixes: 03bf73c315ed ("nbd: prevent memory leak")
Reported-by: syzbot+934037347002901b8d2a@syzkaller.appspotmail.com
Signed-off-by: Zheng Bin <zhengbin13@huawei.com>
Reviewed-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/nbd.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 8f56e6b2f114..f22fad977c91 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -960,25 +960,26 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, test_bit(NBD_BOUND, &config->runtime_flags))) { dev_err(disk_to_dev(nbd->disk), "Device being setup by another task"); - sockfd_put(sock); - return -EBUSY; + err = -EBUSY; + goto put_socket; + } + + nsock = kzalloc(sizeof(*nsock), GFP_KERNEL); + if (!nsock) { + err = -ENOMEM; + goto put_socket; } socks = krealloc(config->socks, (config->num_connections + 1) * sizeof(struct nbd_sock *), GFP_KERNEL); if (!socks) { - sockfd_put(sock); - return -ENOMEM; + kfree(nsock); + err = -ENOMEM; + goto put_socket; } config->socks = socks; - nsock = kzalloc(sizeof(struct nbd_sock), GFP_KERNEL); - if (!nsock) { - sockfd_put(sock); - return -ENOMEM; - } - nsock->fallback_index = -1; nsock->dead = false; mutex_init(&nsock->tx_lock); @@ -990,6 +991,10 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, atomic_inc(&config->live_connections); return 0; + +put_socket: + sockfd_put(sock); + return err; } static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) |