From 989cc61f48486034abd925d83cae1fbe8b680947 Mon Sep 17 00:00:00 2001 From: Shell Date: Sat, 11 May 2024 08:53:42 +0800 Subject: [PATCH] [hrtimer] fixup use-after-free (#8928) Signed-off-by: Shell --- components/drivers/ipc/completion_mp.c | 2 +- components/drivers/ktime/src/hrtimer.c | 29 +++++++++----------------- src/cpu_mp.c | 1 + 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/components/drivers/ipc/completion_mp.c b/components/drivers/ipc/completion_mp.c index 9f7402fd23..21627e073b 100644 --- a/components/drivers/ipc/completion_mp.c +++ b/components/drivers/ipc/completion_mp.c @@ -326,11 +326,11 @@ rt_err_t rt_completion_wakeup_by_errno(struct rt_completion *completion, } /* safe to assume publication done even on resume failure */ - rt_thread_resume(suspend_thread); RT_ASSERT(rt_atomic_load(&completion->susp_thread_n_flag) == RT_WAKING); IPC_STORE(&completion->susp_thread_n_flag, RT_UNCOMPLETED, memory_order_release); + rt_thread_resume(suspend_thread); error = RT_EOK; break; } diff --git a/components/drivers/ktime/src/hrtimer.c b/components/drivers/ktime/src/hrtimer.c index b26bd27975..091584c836 100644 --- a/components/drivers/ktime/src/hrtimer.c +++ b/components/drivers/ktime/src/hrtimer.c @@ -111,32 +111,29 @@ static void _sleep_timeout(void *parameter) rt_completion_done(&timer->completion); } -static void _set_next_timeout(void); +static void _set_next_timeout_n_unlock(rt_base_t level); static void _timeout_callback(void *parameter) { rt_ktime_hrtimer_t timer; timer = (rt_ktime_hrtimer_t)parameter; rt_base_t level; + level = rt_spin_lock_irqsave(&_spinlock); + _nowtimer = RT_NULL; + rt_list_remove(&(timer->row)); + if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) { timer->timeout_func(timer->parameter); } - level = rt_spin_lock_irqsave(&_spinlock); - _nowtimer = RT_NULL; - rt_list_remove(&(timer->row)); - rt_spin_unlock_irqrestore(&_spinlock, level); - - _set_next_timeout(); + _set_next_timeout_n_unlock(level); } -static void _set_next_timeout(void) +static void _set_next_timeout_n_unlock(rt_base_t level) { rt_ktime_hrtimer_t t; - rt_base_t level; - level = rt_spin_lock_irqsave(&_spinlock); if (&_timer_list != _timer_list.prev) { t = rt_list_entry((&_timer_list)->next, struct rt_ktime_hrtimer, row); @@ -202,9 +199,6 @@ rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer) /* parameter check */ RT_ASSERT(timer != RT_NULL); - /* notify the timer stop event */ - rt_completion_wakeup_by_errno(&timer->completion, RT_ERROR); - level = rt_spin_lock_irqsave(&_spinlock); rt_list_remove(&timer->row); /* remove timer from list */ /* change status of timer */ @@ -228,9 +222,8 @@ rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer) } rt_list_insert_after(timer_list, &(timer->row)); timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED; - rt_spin_unlock_irqrestore(&_spinlock, level); - _set_next_timeout(); + _set_next_timeout_n_unlock(level); return RT_EOK; } @@ -250,9 +243,8 @@ rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer) _nowtimer = RT_NULL; rt_list_remove(&timer->row); timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* change status */ - rt_spin_unlock_irqrestore(&_spinlock, level); - _set_next_timeout(); + _set_next_timeout_n_unlock(level); return RT_EOK; } @@ -344,8 +336,7 @@ rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer) { _nowtimer = RT_NULL; rt_list_remove(&timer->row); - rt_spin_unlock_irqrestore(&_spinlock, level); - _set_next_timeout(); + _set_next_timeout_n_unlock(level); } else { diff --git a/src/cpu_mp.c b/src/cpu_mp.c index 8da4c3e180..238ddb420b 100644 --- a/src/cpu_mp.c +++ b/src/cpu_mp.c @@ -219,6 +219,7 @@ RTM_EXPORT(rt_cpus_lock_status_restore); /* A safe API with debugging feature to be called in most codes */ +#undef rt_cpu_get_id /** * @brief Get logical CPU ID *