From: Viresh Kumar <viresh.kumar@linaro.org>
To: Juergen Gross <jgross@suse.com>,
Stefano Stabellini <sstabellini@kernel.org>,
Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Cc: "Viresh Kumar" <viresh.kumar@linaro.org>,
"Vincent Guittot" <vincent.guittot@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Al Viro" <viro@zeniv.linux.org.uk>,
xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/2] xen: privcmd: Fix possible access to a freed kirqfd instance
Date: Tue, 18 Jun 2024 15:12:29 +0530 [thread overview]
Message-ID: <9e884af1f1f842eacbb7afc5672c8feb4dea7f3f.1718703669.git.viresh.kumar@linaro.org> (raw)
In-Reply-To: <a66d7a7a9001424d432f52a9fc3931a1f345464f.1718703669.git.viresh.kumar@linaro.org>
Nothing prevents simultaneous ioctl calls to privcmd_irqfd_assign() and
privcmd_irqfd_deassign(). If that happens, it is possible that a kirqfd
created and added to the irqfds_list by privcmd_irqfd_assign() may get
removed by another thread executing privcmd_irqfd_deassign(), while the
former is still using it after dropping the locks.
This can lead to a situation where an already freed kirqfd instance may
be accessed and cause kernel oops.
Use SRCU locking to prevent the same, as is done for the KVM
implementation for irqfds.
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
drivers/xen/privcmd.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 5ceb6c56cf3e..041774750e52 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -16,6 +16,7 @@
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/srcu.h>
#include <linux/string.h>
#include <linux/workqueue.h>
#include <linux/errno.h>
@@ -845,6 +846,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
/* Irqfd support */
static struct workqueue_struct *irqfd_cleanup_wq;
static DEFINE_SPINLOCK(irqfds_lock);
+DEFINE_STATIC_SRCU(irqfds_srcu);
static LIST_HEAD(irqfds_list);
struct privcmd_kernel_irqfd {
@@ -872,6 +874,9 @@ static void irqfd_shutdown(struct work_struct *work)
container_of(work, struct privcmd_kernel_irqfd, shutdown);
u64 cnt;
+ /* Make sure irqfd has been initialized in assign path */
+ synchronize_srcu(&irqfds_srcu);
+
eventfd_ctx_remove_wait_queue(kirqfd->eventfd, &kirqfd->wait, &cnt);
eventfd_ctx_put(kirqfd->eventfd);
kfree(kirqfd);
@@ -934,7 +939,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
__poll_t events;
struct fd f;
void *dm_op;
- int ret;
+ int ret, idx;
kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);
if (!kirqfd)
@@ -980,6 +985,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
}
}
+ idx = srcu_read_lock(&irqfds_srcu);
list_add_tail(&kirqfd->list, &irqfds_list);
spin_unlock_irqrestore(&irqfds_lock, flags);
@@ -991,6 +997,8 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
if (events & EPOLLIN)
irqfd_inject(kirqfd);
+ srcu_read_unlock(&irqfds_srcu, idx);
+
/*
* Do not drop the file until the kirqfd is fully initialized, otherwise
* we might race against the EPOLLHUP.
--
2.31.1.272.g89b43f80a514
next prev parent reply other threads:[~2024-06-18 9:42 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-18 9:42 [PATCH 1/2] xen: privcmd: Switch from mutex to spinlock for irqfds Viresh Kumar
2024-06-18 9:42 ` Viresh Kumar [this message]
2024-07-02 10:15 ` [PATCH 2/2] xen: privcmd: Fix possible access to a freed kirqfd instance Juergen Gross
2024-07-02 10:12 ` [PATCH 1/2] xen: privcmd: Switch from mutex to spinlock for irqfds Juergen Gross
2024-07-02 10:17 ` Viresh Kumar
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=9e884af1f1f842eacbb7afc5672c8feb4dea7f3f.1718703669.git.viresh.kumar@linaro.org \
--to=viresh.kumar@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=manos.pitsidianakis@linaro.org \
--cc=oleksandr_tyshchenko@epam.com \
--cc=pbonzini@redhat.com \
--cc=sstabellini@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=viro@zeniv.linux.org.uk \
--cc=xen-devel@lists.xenproject.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
all inboxes | Powered by JetHome®