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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.