Fix integer overflow vulnerabilities in time calculations

Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-29 00:46:28 +00:00
parent e6d0738dd9
commit 58046d0367
3 changed files with 28 additions and 13 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */
}