[PATCH v2] erofs-utils: fix thread join loop in erofs_destroy_workqueue
Nithurshen
nithurshen.dev at gmail.com
Wed Mar 18 15:03:49 AEDT 2026
Currently, `erofs_destroy_workqueue` returns immediately if a single
`pthread_join` fails. This halts the teardown process, potentially
leaving orphanedd threads and leaking the workqueue's mutexes and
worker array.
Refactor the joining logic to unconditionally join all worker
threads. If a thread fails to join, print an error message with
the return code. Crucially, if any join fails, skip cleaning up
the synchronization primitives and worker array to prevent a severe
UAF vulnerability caused by still-living threads.
Signed-off-by: Nithurshen <nithurshen.dev at gmail.com>
---
lib/workqueue.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 18ee0f9..98c181b 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
#include <pthread.h>
#include <stdlib.h>
+#include "erofs/print.h"
#include "erofs/workqueue.h"
static void *worker_thread(void *arg)
@@ -42,6 +43,8 @@ static void *worker_thread(void *arg)
int erofs_destroy_workqueue(struct erofs_workqueue *wq)
{
+ int err = 0;
+
if (!wq)
return -EINVAL;
@@ -51,12 +54,20 @@ int erofs_destroy_workqueue(struct erofs_workqueue *wq)
pthread_mutex_unlock(&wq->lock);
while (wq->nworker) {
- int ret = -pthread_join(wq->workers[wq->nworker - 1], NULL);
+ int ret = pthread_join(wq->workers[wq->nworker - 1], NULL);
- if (ret)
- return ret;
+ if (ret) {
+ erofs_err("failed to join worker thread %u: %d",
+ wq->nworker - 1, ret);
+ if (!err)
+ err = -ret;
+ }
--wq->nworker;
}
+
+ if (err)
+ return err;
+
free(wq->workers);
pthread_mutex_destroy(&wq->lock);
pthread_cond_destroy(&wq->cond_empty);
--
2.43.0
More information about the Linux-erofs
mailing list