2021-10-27 20:45:19

by Jiasheng Jiang

[permalink] [raw]
Subject: [PATCH] clocksource: Fix implicit type conversion

As the type of 'next_cpu' is int, its value is range from (-2^31)
to (2^31 - 1).
But the return type of cpumask_next() is unsigned int, whose value
is range from 0 to (2^32 - 1).
Suppose that the return value of cpumask_next() is (2^31), as it is
impicitly casted to int, the actual value of 'next_cpu' is (-2^31).
Also since the type of 'nr_cpu_ids' is unsigned int, we suppose the
value of 'nr_cpu_ids' is (2^32 - 1).
Therefore, the restriction 'next_cpu >= nr_cpu_ids' isn't statisfied
because 'next_cpu' is impicitly casted to unsigned int, whose value
is (2^31).
As a result, the value of 'next_cpu' in add_timer_on() is (-2^31)
that is obviouly illegal and dangerous.
To avoid the risk, it might be better to add the check which can
prevent the illegal input for add_timer_on().

Fixes: 5db0e1e ("cpumask: replace for_each_cpu_mask_nr with for_each_cpu in kernel/time/")
Signed-off-by: Jiasheng Jiang <[email protected]>
---
kernel/time/clocksource.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 2cd9025..6237f18 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -291,7 +291,7 @@ static void clocksource_watchdog(struct timer_list *unused)
* to each other.
*/
next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
- if (next_cpu >= nr_cpu_ids)
+ if (next_cpu < 0 || next_cpu >= nr_cpu_ids)
next_cpu = cpumask_first(cpu_online_mask);

/*
--
2.7.4