mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-05 15:23:03 +08:00
Fix integer overflow vulnerabilities in time calculations
Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user