* [PATCH] hrtimer: check hrtimer with a NULL function
@ 2024-06-05 8:41 Phil Chang
2024-06-05 10:15 ` Anna-Maria Behnsen
0 siblings, 1 reply; 8+ messages in thread
From: Phil Chang @ 2024-06-05 8:41 UTC (permalink / raw)
To: phil.chang
Cc: anna-maria, frederic, tglx, matthias.bgg,
angelogioacchino.delregno, linux-kernel, linux-arm-kernel, jy.ho,
alix.wu
simillar with timers, check for timer->function == NULL.
If the pointer is NULL, discard the request silently.
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---
kernel/time/hrtimer.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 492c14aac642..72d6e7bc9cd9 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1297,9 +1297,13 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
base = lock_hrtimer_base(timer, &flags);
+ if (!timer->function)
+ goto out;
+
if (__hrtimer_start_range_ns(timer, tim, delta_ns, mode, base))
hrtimer_reprogram(timer, true);
+out:
unlock_hrtimer_base(timer, &flags);
}
EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
@@ -1667,6 +1671,11 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
__remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0);
fn = timer->function;
+ if (WARN_ON_ONCE(!fn)) {
+ /* Should never happen. */
+ goto out;
+ }
+
/*
* Clear the 'is relative' flag for the TIME_LOW_RES case. If the
* timer is restarted with a period then it becomes an absolute
@@ -1710,6 +1719,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
* hrtimer_active() cannot observe base->running.timer == NULL &&
* timer->state == INACTIVE.
*/
+out:
raw_write_seqcount_barrier(&base->seq);
WARN_ON_ONCE(base->running != timer);
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] hrtimer: check hrtimer with a NULL function
2024-06-05 8:41 [PATCH] hrtimer: check hrtimer with a NULL function Phil Chang
@ 2024-06-05 10:15 ` Anna-Maria Behnsen
2024-06-05 13:51 ` Phil Chang
0 siblings, 1 reply; 8+ messages in thread
From: Anna-Maria Behnsen @ 2024-06-05 10:15 UTC (permalink / raw)
To: Phil Chang, phil.chang
Cc: frederic, tglx, matthias.bgg, angelogioacchino.delregno,
linux-kernel, linux-arm-kernel, jy.ho, alix.wu
Hi,
Phil Chang <phil.chang@mediatek.com> writes:
> simillar with timers, check for timer->function == NULL.
> If the pointer is NULL, discard the request silently.
Can you please explain, why this change is required?
The statement "similar to timers" is not a valid explaination as timer
list timers and hrtimers are two different things. The function pointer
for timer list timers is explicitly set to NULL in shutdown path to
prevent unwanted rearming of the timer. For hrtimers there is no
shutdown function implemented and function is never set to NULL by
hrtimer code.
> Signed-off-by: Phil Chang <phil.chang@mediatek.com>
> ---
> kernel/time/hrtimer.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
> index 492c14aac642..72d6e7bc9cd9 100644
> --- a/kernel/time/hrtimer.c
> +++ b/kernel/time/hrtimer.c
> @@ -1297,9 +1297,13 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
>
> base = lock_hrtimer_base(timer, &flags);
>
> + if (!timer->function)
> + goto out;
When this happens, user of hrtimers do not follow the semantics of
hrtimers which means this is a bug.
> +
> if (__hrtimer_start_range_ns(timer, tim, delta_ns, mode, base))
> hrtimer_reprogram(timer, true);
>
> +out:
> unlock_hrtimer_base(timer, &flags);
> }
> EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
> @@ -1667,6 +1671,11 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
> __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0);
> fn = timer->function;
>
> + if (WARN_ON_ONCE(!fn)) {
> + /* Should never happen. */
...same as above...
> + goto out;
> + }
> +
> /*
> * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
> * timer is restarted with a period then it becomes an absolute
> @@ -1710,6 +1719,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
> * hrtimer_active() cannot observe base->running.timer == NULL &&
> * timer->state == INACTIVE.
> */
> +out:
> raw_write_seqcount_barrier(&base->seq);
>
> WARN_ON_ONCE(base->running != timer);
Thanks,
Anna-Maria
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] hrtimer: check hrtimer with a NULL function
2024-06-05 10:15 ` Anna-Maria Behnsen
@ 2024-06-05 13:51 ` Phil Chang
2024-06-06 13:14 ` Anna-Maria Behnsen
0 siblings, 1 reply; 8+ messages in thread
From: Phil Chang @ 2024-06-05 13:51 UTC (permalink / raw)
To: anna-maria
Cc: alix.wu, angelogioacchino.delregno, frederic, jy.ho,
linux-arm-kernel, linux-kernel, matthias.bgg, phil.chang, tglx
>> simillar with timers, check for timer->function == NULL.
>> If the pointer is NULL, discard the request silently.
> Can you please explain, why this change is required?
> The statement "similar to timers" is not a valid explaination as timer
> list timers and hrtimers are two different things. The function pointer
> for timer list timers is explicitly set to NULL in shutdown path to
> prevent unwanted rearming of the timer. For hrtimers there is no
> shutdown function implemented and function is never set to NULL by
> hrtimer code.
>
The timer->function is provided by caller, which is invaild if fuction is NULL,
and currently, the hrtime code does not perform any checks to validate this.
Passing a NULL function can lead to a system panic, with a backtrace likes:
```
__hrtimer_run_queues+0x1d8/0x3b8
hrtimer_interrupt+0xdc/0x3a0
arch_timer_handler_phys+0x54/0x94
handle_percpu_devid_irq+0xb8/0x308
handle_domain_irq+0x78/0xec
gic_handle_irq+0x50/0x10c
call_on_irq_stack+0x38/0x54
do_interrupt_handler+0x40/0x98
```
This backtrace does not clearly indicate the source of the invalid usage of hrtimer.
>> Signed-off-by: Phil Chang <phil.chang@mediatek.com>
>> ---
>> kernel/time/hrtimer.c | 10 ++++++++++
>> 1 file changed, 10 insertions(+)
>>
>> diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
>> index 492c14aac642..72d6e7bc9cd9 100644
>> --- a/kernel/time/hrtimer.c
>> +++ b/kernel/time/hrtimer.c
>> @@ -1297,9 +1297,13 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
>>
>> base = lock_hrtimer_base(timer, &flags);
>>
>> + if (!timer->function)
>> + goto out;
>
> When this happens, user of hrtimers do not follow the semantics of
> hrtimers which means this is a bug.
>
Agree, how about BUG_ON here ?
>> +
>> if (__hrtimer_start_range_ns(timer, tim, delta_ns, mode, base))
>> hrtimer_reprogram(timer, true);
>>
>> +out:
>> unlock_hrtimer_base(timer, &flags);
>> }
>> EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);
>> @@ -1667,6 +1671,11 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
>> __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0);
>> fn = timer->function;
>>
>> + if (WARN_ON_ONCE(!fn)) {
>> + /* Should never happen. */
>
> ...same as above...
>
>> + goto out;
>> + }
>> +
>> /*
>> * Clear the 'is relative' flag for the TIME_LOW_RES case. If the
>> * timer is restarted with a period then it becomes an absolute
>> @@ -1710,6 +1719,7 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
>> * hrtimer_active() cannot observe base->running.timer == NULL &&
>> * timer->state == INACTIVE.
>> */
>> +out:
>> raw_write_seqcount_barrier(&base->seq);
>>
>> WARN_ON_ONCE(base->running != timer);
>
>
> Thanks,
>
> Anna-Maria
Thank You
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] hrtimer: check hrtimer with a NULL function
2024-06-05 13:51 ` Phil Chang
@ 2024-06-06 13:14 ` Anna-Maria Behnsen
2024-06-07 2:26 ` [PATCH v2] " Phil Chang
0 siblings, 1 reply; 8+ messages in thread
From: Anna-Maria Behnsen @ 2024-06-06 13:14 UTC (permalink / raw)
To: Phil Chang
Cc: alix.wu, angelogioacchino.delregno, frederic, jy.ho,
linux-arm-kernel, linux-kernel, matthias.bgg, phil.chang, tglx
Phil Chang <phil.chang@mediatek.com> writes:
>>> simillar with timers, check for timer->function == NULL.
>>> If the pointer is NULL, discard the request silently.
>
>> Can you please explain, why this change is required?
>
>> The statement "similar to timers" is not a valid explaination as timer
>> list timers and hrtimers are two different things. The function pointer
>> for timer list timers is explicitly set to NULL in shutdown path to
>> prevent unwanted rearming of the timer. For hrtimers there is no
>> shutdown function implemented and function is never set to NULL by
>> hrtimer code.
>>
> The timer->function is provided by caller, which is invaild if fuction is NULL,
> and currently, the hrtime code does not perform any checks to validate this.
> Passing a NULL function can lead to a system panic, with a backtrace likes:
> ```
> __hrtimer_run_queues+0x1d8/0x3b8
> hrtimer_interrupt+0xdc/0x3a0
> arch_timer_handler_phys+0x54/0x94
> handle_percpu_devid_irq+0xb8/0x308
> handle_domain_irq+0x78/0xec
> gic_handle_irq+0x50/0x10c
> call_on_irq_stack+0x38/0x54
> do_interrupt_handler+0x40/0x98
> ```
> This backtrace does not clearly indicate the source of the invalid usage of hrtimer.
To make it more clear to the inexperienced hrtimer user that it is
mandatory to initialize timer->function to be able to use hrtimers, but
to prevent the kernel to crash, please add a warning in
hrtimer_start_range_ns(). The check can be done without locking the
hrtimer base. When the function pointer is not set, return directly
without doing anything. So this above mentioned backtrace will no longer
appear, as the timer is not added to a queue.
Thanks,
Anna-Maria
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] hrtimer: check hrtimer with a NULL function
2024-06-06 13:14 ` Anna-Maria Behnsen
@ 2024-06-07 2:26 ` Phil Chang
2024-06-10 9:47 ` Anna-Maria Behnsen
0 siblings, 1 reply; 8+ messages in thread
From: Phil Chang @ 2024-06-07 2:26 UTC (permalink / raw)
To: anna-maria
Cc: alix.wu, angelogioacchino.delregno, frederic, jy.ho,
linux-arm-kernel, linux-kernel, matthias.bgg, phil.chang, tglx
Since hrtimers do not allow a NULL function to be passed,
to prevent a kernel crash, return before adding the timer to a queue.
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---
kernel/time/hrtimer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 492c14aac642..d32c1afe59b3 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1285,6 +1285,9 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
struct hrtimer_clock_base *base;
unsigned long flags;
+ if (WARN_ON(!timer->function))
+ return;
+
/*
* Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft
* match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] hrtimer: check hrtimer with a NULL function
2024-06-07 2:26 ` [PATCH v2] " Phil Chang
@ 2024-06-10 9:47 ` Anna-Maria Behnsen
2024-06-10 13:31 ` [PATCH v3] " Phil Chang
0 siblings, 1 reply; 8+ messages in thread
From: Anna-Maria Behnsen @ 2024-06-10 9:47 UTC (permalink / raw)
To: Phil Chang
Cc: alix.wu, angelogioacchino.delregno, frederic, jy.ho,
linux-arm-kernel, linux-kernel, matthias.bgg, phil.chang, tglx
Phil Chang <phil.chang@mediatek.com> writes:
> Since hrtimers do not allow a NULL function to be passed,
> to prevent a kernel crash, return before adding the timer to a queue.
You could point out in the commit message, where the kernel would crash
when using a hrtimer with a NULL pointer as function pointer. And it
shouldn't be a problem to use more than a single sentence for a commit
message :)
> Signed-off-by: Phil Chang <phil.chang@mediatek.com>
> ---
> kernel/time/hrtimer.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
> index 492c14aac642..d32c1afe59b3 100644
> --- a/kernel/time/hrtimer.c
> +++ b/kernel/time/hrtimer.c
> @@ -1285,6 +1285,9 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
> struct hrtimer_clock_base *base;
> unsigned long flags;
>
> + if (WARN_ON(!timer->function))
> + return;
> +
Please use a WARN_ON_ONCE() (as documented in
Documentation/process/coding-style.rst)
> /*
> * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft
> * match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard
Thanks,
Anna-Maria
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3] hrtimer: check hrtimer with a NULL function
2024-06-10 9:47 ` Anna-Maria Behnsen
@ 2024-06-10 13:31 ` Phil Chang
2024-06-17 16:19 ` Anna-Maria Behnsen
0 siblings, 1 reply; 8+ messages in thread
From: Phil Chang @ 2024-06-10 13:31 UTC (permalink / raw)
To: anna-maria
Cc: alix.wu, angelogioacchino.delregno, frederic, jy.ho,
linux-arm-kernel, linux-kernel, matthias.bgg, phil.chang, tglx
To prevent improper usage of hrtimers and avoid potential kernel crashes,
this commit introduces a validation check for hrtimers with a valid function callback,
discard the hrtimers that have a NULL callback.
The `run_hrtimer` executes callbacks for every hrtimer,
and these callbacks must not be NULL. A NULL callback can lead to a kernel crash.
This update ensures that all hrtimers have properly initialized callbacks
before execution.
Signed-off-by: Phil Chang <phil.chang@mediatek.com>
---
kernel/time/hrtimer.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 492c14aac642..b8ee320208d4 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1285,6 +1285,8 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
struct hrtimer_clock_base *base;
unsigned long flags;
+ if (WARN_ON_ONCE(!timer->function))
+ return;
/*
* Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft
* match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3] hrtimer: check hrtimer with a NULL function
2024-06-10 13:31 ` [PATCH v3] " Phil Chang
@ 2024-06-17 16:19 ` Anna-Maria Behnsen
0 siblings, 0 replies; 8+ messages in thread
From: Anna-Maria Behnsen @ 2024-06-17 16:19 UTC (permalink / raw)
To: Phil Chang
Cc: alix.wu, angelogioacchino.delregno, frederic, jy.ho,
linux-arm-kernel, linux-kernel, matthias.bgg, phil.chang, tglx
Phil Chang <phil.chang@mediatek.com> writes:
> To prevent improper usage of hrtimers and avoid potential kernel crashes,
> this commit introduces a validation check for hrtimers with a valid function callback,
> discard the hrtimers that have a NULL callback.
>
> The `run_hrtimer` executes callbacks for every hrtimer,
> and these callbacks must not be NULL. A NULL callback can lead to a kernel crash.
> This update ensures that all hrtimers have properly initialized callbacks
> before execution.
Definitely better! You could sort it, first problem description and then
solution:
The hrtimer function callback must not be NULL. It has to be specified
by the callsite but it is not validated by hrtimer code. When a hrtimer
is queued with a NULL pointer instead of a valid function, the kernel
crashes with a null pointer dereference when trying to execute the
callback in __run_hrtimer().
Introduce a validation before queueing the hrtimer in
hrtimer_start_range_ns().
>
> Signed-off-by: Phil Chang <phil.chang@mediatek.com>
Reviewed-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
> ---
> kernel/time/hrtimer.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
> index 492c14aac642..b8ee320208d4 100644
> --- a/kernel/time/hrtimer.c
> +++ b/kernel/time/hrtimer.c
> @@ -1285,6 +1285,8 @@ void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
> struct hrtimer_clock_base *base;
> unsigned long flags;
>
> + if (WARN_ON_ONCE(!timer->function))
> + return;
> /*
> * Check whether the HRTIMER_MODE_SOFT bit and hrtimer.is_soft
> * match on CONFIG_PREEMPT_RT = n. With PREEMPT_RT check the hard
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-06-17 16:19 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-05 8:41 [PATCH] hrtimer: check hrtimer with a NULL function Phil Chang
2024-06-05 10:15 ` Anna-Maria Behnsen
2024-06-05 13:51 ` Phil Chang
2024-06-06 13:14 ` Anna-Maria Behnsen
2024-06-07 2:26 ` [PATCH v2] " Phil Chang
2024-06-10 9:47 ` Anna-Maria Behnsen
2024-06-10 13:31 ` [PATCH v3] " Phil Chang
2024-06-17 16:19 ` Anna-Maria Behnsen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).