From: Pavel Skripkin <paskripkin@gmail.com>
To: syzbot <syzbot+44e40ac2cfe68e8ce207@syzkaller.appspotmail.com>
Cc: alex.dewar90@gmail.com, arnd@arndb.de,
gregkh@linuxfoundation.org, hdanton@sina.com, jhansen@vmware.com,
linux-kernel@vger.kernel.org, snovitoll@gmail.com,
syzkaller-bugs@googlegroups.com, vdasa@vmware.com
Subject: Re: [syzbot] possible deadlock in vmci_qp_broker_detach
Date: Thu, 1 Jul 2021 01:00:32 +0300 [thread overview]
Message-ID: <20210701010032.4046a863@gmail.com> (raw)
In-Reply-To: <00000000000017d93605c602cafd@google.com>
[-- Attachment #1: Type: text/plain, Size: 735 bytes --]
On Wed, 30 Jun 2021 14:56:06 -0700
syzbot <syzbot+44e40ac2cfe68e8ce207@syzkaller.appspotmail.com> wrote:
> Hello,
>
> syzbot has tested the proposed patch but the reproducer is still
> triggering an issue: INFO: task hung in vmci_ctx_destroy
>
> INFO: task syz-executor.4:4967 blocked for more than 143 seconds.
> Tainted: G W 5.13.0-syzkaller #0
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this
> message. task:syz-executor.4 state:D stack:29136 pid: 4967 ppid:
> 8823 flags:0x00004004 Call Trace:
Hmm, I forgot to change old vmci_ctx_put() in
vmci_ctx_enqueue_datagram()...
#syz test
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
With regards,
Pavel Skripkin
[-- Attachment #2: 0001-misc-vmv_vmci-fix-deadlock.patch --]
[-- Type: text/x-patch, Size: 5065 bytes --]
From 098680ce114e3f0aabdda0b87e8a0a52c9ebb7cc Mon Sep 17 00:00:00 2001
From: Pavel Skripkin <paskripkin@gmail.com>
Date: Thu, 1 Jul 2021 00:30:29 +0300
Subject: [PATCH] misc: vmv_vmci: fix deadlock
Ugly patch just to test general idea...
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
drivers/misc/vmw_vmci/vmci_context.c | 39 +++++++++++++++++++++++++---
drivers/misc/vmw_vmci/vmci_context.h | 4 +++
drivers/misc/vmw_vmci/vmci_host.c | 2 +-
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c
index 26ff49fdf0f7..8cbb2eae01d3 100644
--- a/drivers/misc/vmw_vmci/vmci_context.c
+++ b/drivers/misc/vmw_vmci/vmci_context.c
@@ -113,6 +113,8 @@ struct vmci_ctx *vmci_ctx_create(u32 cid, u32 priv_flags,
kref_init(&context->kref);
spin_lock_init(&context->lock);
+ atomic_set(&context->no_destroy, 0);
+ init_waitqueue_head(&context->destroy_wait);
INIT_LIST_HEAD(&context->list_item);
INIT_LIST_HEAD(&context->datagram_queue);
INIT_LIST_HEAD(&context->notifier_list);
@@ -192,6 +194,7 @@ void vmci_ctx_destroy(struct vmci_ctx *context)
spin_unlock(&ctx_list.lock);
synchronize_rcu();
+ wait_event(context->destroy_wait, !atomic_read(&context->no_destroy));
vmci_ctx_put(context);
}
@@ -307,7 +310,7 @@ int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg)
}
/* Get the target VM's VMCI context. */
- context = vmci_ctx_get(cid);
+ context = vmci_ctx_get_no_destroy(cid);
if (!context) {
pr_devel("Invalid context (ID=0x%x)\n", cid);
return VMCI_ERROR_INVALID_ARGS;
@@ -345,7 +348,7 @@ int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg)
context->datagram_queue_size + vmci_dg_size >=
VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE)) {
spin_unlock(&context->lock);
- vmci_ctx_put(context);
+ vmci_ctx_put_allow_destroy(context);
kfree(dq_entry);
pr_devel("Context (ID=0x%x) receive queue is full\n", cid);
return VMCI_ERROR_NO_RESOURCES;
@@ -357,7 +360,7 @@ int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg)
ctx_signal_notify(context);
wake_up(&context->host_context.wait_queue);
spin_unlock(&context->lock);
- vmci_ctx_put(context);
+ vmci_ctx_put_allow_destroy(context);
return vmci_dg_size;
}
@@ -416,6 +419,30 @@ struct vmci_ctx *vmci_ctx_get(u32 cid)
return context;
}
+/*
+ * Retrieves VMCI context corresponding to the given cid.
+ */
+struct vmci_ctx *vmci_ctx_get_no_destroy(u32 cid)
+{
+ struct vmci_ctx *c, *context = NULL;
+
+ if (cid == VMCI_INVALID_ID)
+ return NULL;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(c, &ctx_list.head, list_item) {
+ if (c->cid == cid) {
+ context = c;
+ atomic_set(&context->no_destroy, 1);
+ kref_get(&context->kref);
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ return context;
+}
+
/*
* Deallocates all parts of a context data structure. This
* function doesn't lock the context, because it assumes that
@@ -497,6 +524,12 @@ void vmci_ctx_put(struct vmci_ctx *context)
kref_put(&context->kref, ctx_free_ctx);
}
+void vmci_ctx_put_allow_destroy(struct vmci_ctx *context)
+{
+ kref_put(&context->kref, ctx_free_ctx);
+ atomic_set(&context->no_destroy, 0);
+}
+
/*
* Dequeues the next datagram and returns it to caller.
* The caller passes in a pointer to the max size datagram
diff --git a/drivers/misc/vmw_vmci/vmci_context.h b/drivers/misc/vmw_vmci/vmci_context.h
index 4db8701c9781..a3d711e11581 100644
--- a/drivers/misc/vmw_vmci/vmci_context.h
+++ b/drivers/misc/vmw_vmci/vmci_context.h
@@ -51,6 +51,8 @@ struct vmci_ctx {
*/
int user_version;
spinlock_t lock; /* Locks callQueue and handle_arrays. */
+ atomic_t no_destroy; /* Locks callQueue and handle_arrays. */
+ wait_queue_head_t destroy_wait;
/*
* queue_pairs attached to. The array of
@@ -134,7 +136,9 @@ int vmci_ctx_dequeue_datagram(struct vmci_ctx *context,
size_t *max_size, struct vmci_datagram **dg);
int vmci_ctx_pending_datagrams(u32 cid, u32 *pending);
struct vmci_ctx *vmci_ctx_get(u32 cid);
+struct vmci_ctx *vmci_ctx_get_no_destroy(u32 cid);
void vmci_ctx_put(struct vmci_ctx *context);
+void vmci_ctx_put_allow_destroy(struct vmci_ctx *context);
bool vmci_ctx_exists(u32 cid);
int vmci_ctx_add_notification(u32 context_id, u32 remote_cid);
diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c
index da1e2a773823..eedbe042a9ca 100644
--- a/drivers/misc/vmw_vmci/vmci_host.c
+++ b/drivers/misc/vmw_vmci/vmci_host.c
@@ -139,6 +139,7 @@ static int vmci_host_close(struct inode *inode, struct file *filp)
{
struct vmci_host_dev *vmci_host_dev = filp->private_data;
+ filp->private_data = NULL;
if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) {
vmci_ctx_destroy(vmci_host_dev->context);
vmci_host_dev->context = NULL;
@@ -154,7 +155,6 @@ static int vmci_host_close(struct inode *inode, struct file *filp)
vmci_host_dev->ct_type = VMCIOBJ_NOT_SET;
kfree(vmci_host_dev);
- filp->private_data = NULL;
return 0;
}
--
2.32.0
next prev parent reply other threads:[~2021-06-30 22:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-26 1:19 [syzbot] possible deadlock in vmci_qp_broker_detach syzbot
2021-04-12 17:29 ` syzbot
2021-06-30 17:21 ` syzbot
2021-06-30 21:36 ` Pavel Skripkin
2021-06-30 21:56 ` syzbot
2021-06-30 22:00 ` Pavel Skripkin [this message]
2021-06-30 22:20 ` syzbot
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=20210701010032.4046a863@gmail.com \
--to=paskripkin@gmail.com \
--cc=alex.dewar90@gmail.com \
--cc=arnd@arndb.de \
--cc=gregkh@linuxfoundation.org \
--cc=hdanton@sina.com \
--cc=jhansen@vmware.com \
--cc=linux-kernel@vger.kernel.org \
--cc=snovitoll@gmail.com \
--cc=syzbot+44e40ac2cfe68e8ce207@syzkaller.appspotmail.com \
--cc=syzkaller-bugs@googlegroups.com \
--cc=vdasa@vmware.com \
/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