In cryptodev_lkcf_cleanup(), close(lkcf->eventfd) is called before
joining worker threads via qemu_thread_join(), and the eventfd read
handler registered with qemu_set_fd_handler() is never unregistered.
If an LKCF async crypto task or a main-loop fd callback remains active
during backend cleanup:
1. In-flight worker threads calling eventfd_write() may access a closed
or already reused file descriptor.
2. The main-loop fd handler may fire on a reused descriptor or
reference freed LKCF backend objects, resulting in use-after-free
(UAF) or crash.
Fix this by unregistering the eventfd handler with qemu_set_fd_handler()
prior to joining worker threads, and delaying close(lkcf->eventfd) until
all worker threads have terminated.
Fixes: 39fff6f3e8b3 ("cryptodev: Add a lkcf-backend for cryptodev")
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
---
backends/cryptodev-lkcf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/backends/cryptodev-lkcf.c b/backends/cryptodev-lkcf.c
index 3fe29d3104c..2f85c382b21 100644
--- a/backends/cryptodev-lkcf.c
+++ b/backends/cryptodev-lkcf.c
@@ -264,10 +264,11 @@ static void cryptodev_lkcf_cleanup(CryptoDevBackend *backend, Error **errp)
qemu_mutex_unlock(&lkcf->mutex);
qemu_cond_broadcast(&lkcf->cond);
- close(lkcf->eventfd);
+ qemu_set_fd_handler(lkcf->eventfd, NULL, NULL, NULL);
for (i = 0; i < NR_WORKER_THREAD; i++) {
qemu_thread_join(&lkcf->worker_threads[i]);
}
+ close(lkcf->eventfd);
QSIMPLEQ_FOREACH_SAFE(task, &lkcf->requests, queue, next) {
if (task->cb) {
--
2.43.0