From: xiubli@redhat.com
To: josef@toxicpanda.com, axboe@kernel.dk, ming.lei@redhat.com
Cc: nbd@other.debian.org, linux-block@vger.kernel.org,
jdillama@redhat.com, mgolub@suse.de, Xiubo Li <xiubli@redhat.com>
Subject: [PATCH v2 1/2] nbd: fix use-after-freed crash for nbd->recv_workq
Date: Mon, 2 Nov 2020 22:07:57 -0500 [thread overview]
Message-ID: <20201103030758.317781-2-xiubli@redhat.com> (raw)
In-Reply-To: <20201103030758.317781-1-xiubli@redhat.com>
From: Xiubo Li <xiubli@redhat.com>
The crash call trace:
<6>[ 1012.319386] block nbd1: NBD_DISCONNECT
<1>[ 1012.319437] BUG: kernel NULL pointer dereference, address: 0000000000000020
<1>[ 1012.319439] #PF: supervisor write access in kernel mode
<1>[ 1012.319441] #PF: error_code(0x0002) - not-present page
<6>[ 1012.319442] PGD 0 P4D 0
<4>[ 1012.319448] Oops: 0002 [#1] SMP NOPTI
<4>[ 1012.319454] CPU: 9 PID: 25111 Comm: rbd-nbd Tainted: G E 5.9.0+ #6
[...]
<4>[ 1012.319505] PKRU: 55555554
<4>[ 1012.319506] Call Trace:
<4>[ 1012.319560] flush_workqueue+0x81/0x440
<4>[ 1012.319598] nbd_disconnect_and_put+0x50/0x70 [nbd]
<4>[ 1012.319607] nbd_genl_disconnect+0xc7/0x170 [nbd]
<4>[ 1012.319627] genl_rcv_msg+0x1dd/0x2f9
<4>[ 1012.319642] ? genl_start+0x140/0x140
<4>[ 1012.319644] netlink_rcv_skb+0x49/0x110
<4>[ 1012.319649] genl_rcv+0x24/0x40
<4>[ 1012.319651] netlink_unicast+0x1a5/0x280
<4>[ 1012.319653] netlink_sendmsg+0x23d/0x470
<4>[ 1012.319667] sock_sendmsg+0x5b/0x60
<4>[ 1012.319676] ____sys_sendmsg+0x1ef/0x260
<4>[ 1012.319679] ? copy_msghdr_from_user+0x5c/0x90
<4>[ 1012.319680] ? ____sys_recvmsg+0xa5/0x180
<4>[ 1012.319682] ___sys_sendmsg+0x7c/0xc0
<4>[ 1012.319683] ? copy_msghdr_from_user+0x5c/0x90
<4>[ 1012.319685] ? ___sys_recvmsg+0x89/0xc0
<4>[ 1012.319692] ? __wake_up_common_lock+0x87/0xc0
<4>[ 1012.319715] ? __check_object_size+0x46/0x173
<4>[ 1012.319727] ? _copy_to_user+0x22/0x30
<4>[ 1012.319729] ? move_addr_to_user+0xc3/0x100
<4>[ 1012.319731] __sys_sendmsg+0x57/0xa0
<4>[ 1012.319744] do_syscall_64+0x33/0x40
<4>[ 1012.319760] entry_SYSCALL_64_after_hwframe+0x44/0xa9
<4>[ 1012.319780] RIP: 0033:0x7f5baa8e3ad5
In case the reference of nbd->config has reached zero and the
related resource has been released, if another process tries to
send the DISCONENCT cmd by using the netlink, it will potentially
crash like this.
Signed-off-by: Xiubo Li <xiubli@redhat.com>
---
drivers/block/nbd.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index f46e26c9d9b3..3bb8281bb753 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -2003,16 +2003,31 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
static void nbd_disconnect_and_put(struct nbd_device *nbd)
{
+ bool flush = true;
+
mutex_lock(&nbd->config_lock);
nbd_disconnect(nbd);
nbd_clear_sock(nbd);
- mutex_unlock(&nbd->config_lock);
/*
- * Make sure recv thread has finished, so it does not drop the last
- * config ref and try to destroy the workqueue from inside the work
- * queue.
+ * In very rare case that the nbd->recv_workq may already have been
+ * released by the recv_work().
*/
- flush_workqueue(nbd->recv_workq);
+ if (likely(!nbd->recv_workq))
+ refcount_inc(&nbd->config_refs);
+ else
+ flush = false;
+ mutex_unlock(&nbd->config_lock);
+
+ if (flush) {
+ /*
+ * Make sure recv thread has finished, so it does not drop
+ * the last config ref and try to destroy the workqueue
+ * from inside the work queue.
+ */
+ flush_workqueue(nbd->recv_workq);
+ nbd_config_put(nbd);
+ }
+
if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
&nbd->config->runtime_flags))
nbd_config_put(nbd);
--
2.18.4
next prev parent reply other threads:[~2020-11-03 3:08 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-03 3:07 [PATCH v2 0/2] nbd: fix use-after-freed and double lock bugs xiubli
2020-11-03 3:07 ` xiubli [this message]
2020-11-03 4:12 ` [PATCH v2 1/2] nbd: fix use-after-freed crash for nbd->recv_workq Ming Lei
2020-11-03 6:40 ` Xiubo Li
2020-11-03 3:07 ` [PATCH v2 2/2] nbd: add comments about double lock for config_lock confusion xiubli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201103030758.317781-2-xiubli@redhat.com \
--to=xiubli@redhat.com \
--cc=axboe@kernel.dk \
--cc=jdillama@redhat.com \
--cc=josef@toxicpanda.com \
--cc=linux-block@vger.kernel.org \
--cc=mgolub@suse.de \
--cc=ming.lei@redhat.com \
--cc=nbd@other.debian.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox