Przeglądaj źródła

Fix integer overflow vulnerabilities in time calculations

Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
copilot-swe-agent[bot] 2 tygodni temu
rodzic
commit
58046d0367

+ 2 - 2
components/drivers/clock_time/src/clock_time.c

@@ -63,8 +63,8 @@ rt_err_t rt_clock_time_device_register(struct rt_clock_time_device *dev,
             }
             else
             {
-                /* For very low frequencies, calculate more carefully */
-                dev->res_scale = (1000000ULL * RT_CLOCK_TIME_RESMUL) / freq * 1000;
+                /* For very low frequencies, calculate more carefully to avoid precision loss */
+                dev->res_scale = ((1000000ULL * RT_CLOCK_TIME_RESMUL * 1000) / freq);
             }
         }
         else

+ 18 - 8
components/drivers/clock_time/src/clock_time_boottime.c

@@ -17,10 +17,13 @@ rt_weak rt_err_t rt_clock_boottime_get_us(struct timeval *tv)
 {
     RT_ASSERT(tv != RT_NULL);
 
-    rt_uint64_t ns = (rt_clock_cputimer_getcnt() * rt_clock_cputimer_getres()) / RT_CLOCK_TIME_RESMUL;
+    /* Use 64-bit intermediate values to prevent overflow */
+    rt_uint64_t cnt = rt_clock_cputimer_getcnt();
+    rt_uint64_t res = rt_clock_cputimer_getres();
+    rt_uint64_t ns = (cnt * res) / RT_CLOCK_TIME_RESMUL;
 
-    tv->tv_sec  = ns / (1000ULL * 1000 * 1000);
-    tv->tv_usec = (ns % (1000ULL * 1000 * 1000)) / 1000;
+    tv->tv_sec  = (long)(ns / (1000ULL * 1000 * 1000));
+    tv->tv_usec = (long)((ns % (1000ULL * 1000 * 1000)) / 1000);
 
     return RT_EOK;
 }
@@ -29,9 +32,12 @@ rt_weak rt_err_t rt_clock_boottime_get_s(time_t *t)
 {
     RT_ASSERT(t != RT_NULL);
 
-    rt_uint64_t ns = (rt_clock_cputimer_getcnt() * rt_clock_cputimer_getres()) / RT_CLOCK_TIME_RESMUL;
+    /* Use 64-bit intermediate values to prevent overflow */
+    rt_uint64_t cnt = rt_clock_cputimer_getcnt();
+    rt_uint64_t res = rt_clock_cputimer_getres();
+    rt_uint64_t ns = (cnt * res) / RT_CLOCK_TIME_RESMUL;
 
-    *t = ns / (1000ULL * 1000 * 1000);
+    *t = (time_t)(ns / (1000ULL * 1000 * 1000));
 
     return RT_EOK;
 }
@@ -40,10 +46,14 @@ rt_weak rt_err_t rt_clock_boottime_get_ns(struct timespec *ts)
 {
     RT_ASSERT(ts != RT_NULL);
 
-    rt_uint64_t ns = (rt_clock_cputimer_getcnt() * rt_clock_cputimer_getres()) / RT_CLOCK_TIME_RESMUL;
+    /* Use 64-bit intermediate values to prevent overflow */
+    rt_uint64_t cnt = rt_clock_cputimer_getcnt();
+    rt_uint64_t res = rt_clock_cputimer_getres();
+    rt_uint64_t ns = (cnt * res) / RT_CLOCK_TIME_RESMUL;
 
-    ts->tv_sec  = ns / (1000ULL * 1000 * 1000);
-    ts->tv_nsec = ns % (1000ULL * 1000 * 1000);
+    ts->tv_sec  = (time_t)(ns / (1000ULL * 1000 * 1000));
+    ts->tv_nsec = (long)(ns % (1000ULL * 1000 * 1000));
 
     return RT_EOK;
 }
+

+ 8 - 3
components/drivers/clock_time/src/hrtimer.c

@@ -74,8 +74,8 @@ rt_weak rt_err_t rt_clock_hrtimer_settimeout(unsigned long cnt)
 /**
  * @brief convert cnt from cputimer cnt to hrtimer cnt
  *
- * @param cnt
- * @return unsigned long
+ * @param cnt Target count value
+ * @return Converted count for hrtimer
  */
 static unsigned long _cnt_convert(unsigned long cnt)
 {
@@ -94,7 +94,12 @@ static unsigned long _cnt_convert(unsigned long cnt)
     if (count > (_HRTIMER_MAX_CNT / 2))
         return 0;
 
-    rtn = (count * rt_clock_cputimer_getres()) / rt_clock_hrtimer_getres();
+    /* Use 64-bit intermediate to prevent overflow in multiplication */
+    rt_uint64_t count_64 = (rt_uint64_t)count;
+    rt_uint64_t res_cpu = rt_clock_cputimer_getres();
+    rt_uint64_t res_hr = rt_clock_hrtimer_getres();
+    
+    rtn = (unsigned long)((count_64 * res_cpu) / res_hr);
     return rtn == 0 ? 1 : rtn; /* at least 1 */
 }