From: Yehor Malikov <malikovyehor@gmail.com>
To: dev@dpdk.org
Cc: maxime.coquelin@redhat.com, chenbox@nvidia.com,
stephen@networkplumber.org,
Yehor Malikov <Yehor.Malikov@solidigm.com>
Subject: [PATCH v6] vhost: fix use-after-free in fdset during shutdown
Date: Thu, 5 Feb 2026 00:05:02 +0100 [thread overview]
Message-ID: <20260204230502.24983-1-malikovyehor@gmail.com> (raw)
In-Reply-To: <20260204220037.23760-1-malikovyehor@gmail.com>
From: Yehor Malikov <Yehor.Malikov@solidigm.com>
The fdset_event_dispatch thread runs in a loop checking the destroy
flag after each epoll_wait iteration. During process exit,
rte_eal_cleanup() frees hugepages memory while the fdset thread is
still running, causing use-after-free when accessing the fdset
structure.
Add fdset_deinit() function to stop the dispatch thread by setting
the destroy flag and waiting for thread completion. Resource cleanup
(epoll fd, fdsets array, memory) is intentionally skipped since the
function is only called during process exit when the OS will reclaim
all resources anyway, avoiding potential deadlocks from mutex
operations in destructor context.
Use symmetric RTE_FINI destructors for both vhost-user and VDUSE fdsets
to ensure proper cleanup before EAL teardown.
Fixes: e68a6feaa3b3 ("vhost: improve fdset initialization")
Signed-off-by: Yehor Malikov <Yehor.Malikov@solidigm.com>
---
.mailmap | 1 +
lib/vhost/fd_man.c | 16 ++++++++++++++++
lib/vhost/fd_man.h | 1 +
lib/vhost/socket.c | 12 +++++++++++-
lib/vhost/vduse.c | 11 ++++++++++-
5 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/.mailmap b/.mailmap
index fc53ed2a55..998185a66e 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1839,6 +1839,7 @@ Yaron Illouz <yaroni@radcom.com>
Yaroslav Brustinov <ybrustin@cisco.com>
Yash Sharma <ysharma@marvell.com>
Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp> <yasufum.o@gmail.com>
+Yehor Malikov <Yehor.Malikov@solidigm.com>
Yelena Krivosheev <yelena@marvell.com>
Yerden Zhumabekov <e_zhumabekov@sts.kz> <yerden.zhumabekov@sts.kz>
Yevgeny Kliteynik <kliteyn@nvidia.com>
diff --git a/lib/vhost/fd_man.c b/lib/vhost/fd_man.c
index f9147edee7..9790c8a586 100644
--- a/lib/vhost/fd_man.c
+++ b/lib/vhost/fd_man.c
@@ -149,6 +149,22 @@ fdset_init(const char *name)
return NULL;
}
+void
+fdset_deinit(struct fdset *pfdset)
+{
+ unsigned int val;
+
+ if (pfdset == NULL)
+ return;
+
+ /* Signal the dispatch thread to stop */
+ pfdset->destroy = true;
+
+ /* Wait for the dispatch thread to exit */
+ if (rte_thread_join(pfdset->tid, &val) != 0)
+ VHOST_FDMAN_LOG(ERR, "Failed to join %s event dispatch thread", pfdset->name);
+}
+
static int
fdset_insert_entry(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat)
{
diff --git a/lib/vhost/fd_man.h b/lib/vhost/fd_man.h
index eadcc6fb42..c9e51badaa 100644
--- a/lib/vhost/fd_man.h
+++ b/lib/vhost/fd_man.h
@@ -15,6 +15,7 @@ struct fdset;
typedef void (*fd_cb)(int fd, void *dat, int *close);
struct fdset *fdset_init(const char *name);
+void fdset_deinit(struct fdset *pfdset);
int fdset_add(struct fdset *pfdset, int fd,
fd_cb rcb, fd_cb wcb, void *dat);
diff --git a/lib/vhost/socket.c b/lib/vhost/socket.c
index ae95e7e6b0..91680fbbaa 100644
--- a/lib/vhost/socket.c
+++ b/lib/vhost/socket.c
@@ -76,6 +76,8 @@ struct vhost_user_connection {
};
#define MAX_VHOST_SOCKET 1024
+#define VHOST_USER_FDSET_NAME "vhost-evt"
+
struct vhost_user {
struct vhost_user_socket *vsockets[MAX_VHOST_SOCKET];
struct fdset *fdset;
@@ -1198,7 +1200,7 @@ rte_vhost_driver_start(const char *path)
vsocket->extbuf, vsocket->linearbuf);
if (vhost_user.fdset == NULL) {
- vhost_user.fdset = fdset_init("vhost-evt");
+ vhost_user.fdset = fdset_init(VHOST_USER_FDSET_NAME);
if (vhost_user.fdset == NULL) {
VHOST_CONFIG_LOG(path, ERR, "failed to init Vhost-user fdset");
return -1;
@@ -1210,3 +1212,11 @@ rte_vhost_driver_start(const char *path)
else
return vhost_user_start_client(vsocket);
}
+
+RTE_FINI(vhost_user_fdset_fini)
+{
+ if (vhost_user.fdset != NULL) {
+ fdset_deinit(vhost_user.fdset);
+ vhost_user.fdset = NULL;
+ }
+}
diff --git a/lib/vhost/vduse.c b/lib/vhost/vduse.c
index 0b5d158fee..8d1846b491 100644
--- a/lib/vhost/vduse.c
+++ b/lib/vhost/vduse.c
@@ -27,6 +27,7 @@
#define VHOST_VDUSE_API_VERSION 0
#define VDUSE_CTRL_PATH "/dev/vduse/control"
+#define VDUSE_FDSET_NAME "vduse-evt"
struct vduse {
struct fdset *fdset;
@@ -685,7 +686,7 @@ vduse_device_create(const char *path, bool compliant_ol_flags, bool extbuf, bool
bool reconnect = false;
if (vduse.fdset == NULL) {
- vduse.fdset = fdset_init("vduse-evt");
+ vduse.fdset = fdset_init(VDUSE_FDSET_NAME);
if (vduse.fdset == NULL) {
VHOST_CONFIG_LOG(path, ERR, "failed to init VDUSE fdset");
return -1;
@@ -942,3 +943,11 @@ vduse_device_destroy(const char *path)
return 0;
}
+
+RTE_FINI(vduse_fdset_fini)
+{
+ if (vduse.fdset != NULL) {
+ fdset_deinit(vduse.fdset);
+ vduse.fdset = NULL;
+ }
+}
--
2.52.0
next prev parent reply other threads:[~2026-02-04 23:05 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-04 18:03 [PATCH] vhost: fix use-after-free in fdset during shutdown Yehor Malikov
2026-02-04 18:48 ` [PATCH v2] " malikovyehor
2026-02-04 18:58 ` [PATCH v3] " Yehor Malikov
2026-02-04 20:34 ` Stephen Hemminger
2026-02-04 21:32 ` Yehor Malikov
2026-02-04 21:35 ` [PATCH v4] " Yehor Malikov
2026-02-04 22:00 ` [PATCH v5] " Yehor Malikov
2026-02-04 23:05 ` Yehor Malikov [this message]
2026-02-05 1:17 ` [PATCH v6] " Stephen Hemminger
2026-02-05 11:16 ` [PATCH v7] " Yehor Malikov
2026-02-05 11:20 ` Yehor Malikov
2026-02-05 18:30 ` [PATCH v8] " Yehor Malikov
2026-02-05 18:35 ` [PATCH v9] " Yehor Malikov
2026-02-16 10:17 ` Yehor Malikov
2026-02-17 14:31 ` David Marchand
2026-02-18 7:50 ` [PATCH v10] " Yehor Malikov
2026-02-18 8:01 ` [PATCH v11] " Yehor Malikov
2026-02-18 8:52 ` David Marchand
2026-02-18 9:05 ` [PATCH v12] " Yehor Malikov
2026-02-18 10:27 ` David Marchand
2026-02-27 9:00 ` fengchengwen
2026-03-05 10:50 ` Maxime Coquelin
2026-03-05 13:52 ` Maxime Coquelin
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=20260204230502.24983-1-malikovyehor@gmail.com \
--to=malikovyehor@gmail.com \
--cc=Yehor.Malikov@solidigm.com \
--cc=chenbox@nvidia.com \
--cc=dev@dpdk.org \
--cc=maxime.coquelin@redhat.com \
--cc=stephen@networkplumber.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