<div dir="ltr"><u></u>

  
    
  
  <div>
    <p><br>
    </p>
    <div>On 3/18/2026 12:03 PM, Nithurshen
      wrote:<br>
    </div>
    <blockquote type="cite">
      <pre>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 <a href="mailto:nithurshen.dev@gmail.com" target="_blank"><nithurshen.dev@gmail.com></a>
---
 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)</pre>
    </blockquote>
    <p>I think just a erofs_err() here is enough.., as joining other
      workers brings very little benefit here.</p>
    <p>Yifan</p>
    <blockquote type="cite">
      <pre>-                      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);
</pre>
    </blockquote>
  </div>

</div>