This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 9ab05ec3f554598eb681366e59640bb757a01364 Author: ouyangxiangzhen <[email protected]> AuthorDate: Mon Sep 7 10:16:50 2026 +0800 drivers/timers: fix UB and mask width in up_timer_getmask The mask computation introduced by "fix infinite loop in up_timer_getmask when maxticks == CLOCK_MAX" has two problems: 1. If maxticks == 0, flsx(0) expands to __builtin_clz(0), which is undefined behavior, and the shift count becomes 8 * sizeof(clock_t) = 64 for a 64-bit clock_t, which is undefined behavior as well. The loop-based code that was replaced kept *mask = 0 in this case. 2. CLOCK_MAX is INT64_MAX, i.e. 63 one bits, not a full-width bit pattern. The resulting mask is always one bit narrower than the one produced by the original loop; e.g. a 32-bit timer got 0x7fffffff instead of 0xffffffff, so counter deltas >= 2^31 were truncated in the clock timekeeping code. Fix this by keeping *mask = 0 when maxticks == 0 and by deriving the mask from the full-width unsigned constant (uint64_t)-1, which restores the all-ones semantics of the original loop and still covers the maxticks == CLOCK_MAX case. Also initialize maxticks in arch_timer.c: if the lower half does not implement the maxtimeout ops, the value is left untouched and would otherwise be read uninitialized. Assisted-by: Zhipu GLM-5.3 Signed-off-by: ouyangxiangzhen <[email protected]> --- drivers/timers/arch_alarm.c | 3 ++- drivers/timers/arch_timer.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/timers/arch_alarm.c b/drivers/timers/arch_alarm.c index 686930c8c91..270f7d221ef 100644 --- a/drivers/timers/arch_alarm.c +++ b/drivers/timers/arch_alarm.c @@ -289,7 +289,8 @@ void weak_function up_timer_getmask(FAR clock_t *mask) ONESHOT_TICK_MAX_DELAY(g_oneshot_lower, &maxticks); - *mask = CLOCK_MAX >> (sizeof(clock_t) * 8u - flsx(maxticks)); + *mask = maxticks == 0 ? 0 : + UINT64_MAX >> (sizeof(clock_t) * 8u - flsx(maxticks)); } } diff --git a/drivers/timers/arch_timer.c b/drivers/timers/arch_timer.c index 7893bc8c85b..67107e2ad3c 100644 --- a/drivers/timers/arch_timer.c +++ b/drivers/timers/arch_timer.c @@ -277,11 +277,12 @@ void up_timer_set_lowerhalf(FAR struct timer_lowerhalf_s *lower) void weak_function up_timer_getmask(FAR clock_t *mask) { - uint32_t maxticks; + uint32_t maxticks = 0u; TIMER_TICK_MAXTIMEOUT(g_timer.lower, &maxticks); - *mask = CLOCK_MAX >> (sizeof(clock_t) * 8u - flsx(maxticks)); + *mask = maxticks == 0u ? 0 : + UINT64_MAX >> (sizeof(clock_t) * 8u - flsx(maxticks)); } int weak_function up_timer_gettick(FAR clock_t *ticks)
