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)

Reply via email to