diff options
| author | Zhihong Chen <[email protected]> | 2026-08-19 12:51:05 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2026-08-19 13:52:13 +0800 |
| commit | 89a1610636845a77deec3c3e70c565f20ddb3341 (patch) | |
| tree | 5a943d9e70913cf340da72e4822ac10762d3d6e0 | |
| parent | 60911ffd9ed6aaacf768dfd557508d0b40170664 (diff) | |
[fix] osal: defer Zephyr thread memory release
- The system workqueue may preempt a self-deleting thread after the
release work is submitted. Waiting for the thread with k_thread_join()
before freeing its TCB and stack prevents use-after-free corruption.
- Also handle release work allocation failure before aborting the thread.
Signed-off-by: Zhihong Chen <[email protected]>
| -rw-r--r-- | osal/usb_osal_zephyr.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/osal/usb_osal_zephyr.c b/osal/usb_osal_zephyr.c index fe2dc641..6b2a0fa4 100644 --- a/osal/usb_osal_zephyr.c +++ b/osal/usb_osal_zephyr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, sakumisu + * Copyright (c) 2025-2026 sakumisu * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,8 +48,12 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, static void release_thread_handler(struct k_work *work) { struct release_thread_work *release_work = (struct release_thread_work *)work; - k_free(release_work->thread); - k_work_cancel(work); + + /* The workqueue may preempt the thread that queued this work. Wait until + * k_thread_abort() has completed before freeing its TCB and stack. */ + if (k_thread_join(release_work->thread, K_FOREVER) == 0) { + k_free(release_work->thread); + } k_free(release_work); } @@ -63,6 +67,10 @@ void usb_osal_thread_delete(usb_osal_thread_t thread) thread = z_current_get(); #endif release_work = k_malloc(sizeof(struct release_thread_work)); + if (release_work == NULL) { + k_thread_abort(thread); + return; + } release_work->thread = thread; k_work_init(&release_work->work, release_thread_handler); k_work_submit(&release_work->work); @@ -309,4 +317,4 @@ void *usb_osal_malloc(size_t size) void usb_osal_free(void *ptr) { k_free(ptr); -}
\ No newline at end of file +} |
