Bug 232914 - Integer overflow in function calcru1
Summary: Integer overflow in function calcru1
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-02 17:51 UTC by WHR
Modified: 2018-11-02 17:52 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description WHR 2018-11-02 17:51:30 UTC
The issue is from following code in function calcru1:
su = (tu * st) / tt;
the 'tu * st' is overflowed in my system, causing the 'p_rux.rux_su' is no longer growing for that process.

For example, running ps(1) shows that 'systime' is no longer growing, but 'time' is not yet overflowed and keep growing
$ ps -p 17087 -o comm,time,systime
COMMAND            TIME    SYSTIME
VBoxHeadless 8951:24.70 6339:45.52
$ ps -p 17087 -o comm,time,systime
COMMAND            TIME    SYSTIME
VBoxHeadless 8951:25.72 6339:45.52
$ ps -p 17087 -o comm,time,systime
COMMAND            TIME    SYSTIME
VBoxHeadless 8951:26.54 6339:45.52
$ ps -p 17087 -o comm,time,systime
COMMAND            TIME    SYSTIME
VBoxHeadless 8951:27.60 6339:45.52

Running kgdb(1) shows an overflow is occurred when 'cputick2usec(ruxp->rux_runtime)' multiplying '$p->p_rux.rux_sticks'
(kgdb) p $p
$3949 = (struct proc *) 0xfffff800464f5000
(kgdb) p $p->p_pid
$3950 = 17087
(kgdb) p $p->p_comm
$3951 = "VBoxHeadless\000\000\000\000\000\000\000"
(kgdb) p $p->p_rux
$3952 = {rux_runtime = 1888763265150967, rux_uticks = 866405, rux_sticks = 66653750, rux_iticks = 0, rux_uu = 6893394017, 
  rux_su = 380385524075, rux_tu = 537211849594}
(kgdb) p $p->p_rux
$3953 = {rux_runtime = 1888767209058083, rux_uticks = 866408, rux_sticks = 66653898, rux_iticks = 0, rux_uu = 6893416864, 
  rux_su = 380385524075, rux_tu = 537212971341}
(kgdb) p $p->p_rux
$3954 = {rux_runtime = 1888773035929970, rux_uticks = 866411, rux_sticks = 66654106, rux_iticks = 0, rux_uu = 6893440457, 
  rux_su = 380385524075, rux_tu = 537214628650}
(kgdb) p ((uint64_t)$p->p_rux.rux_runtime * 1000ll / ((cpu_ticks == tc_cpu_ticks ? timehands->th_counter->tc_frequency : cpu_tick_frequency) / 1000ll))
$3955 = 537220825631
(kgdb) p ((uint64_t)$p->p_rux.rux_runtime * 1000ll / ((cpu_ticks == tc_cpu_ticks ? timehands->th_counter->tc_frequency : cpu_tick_frequency) / 1000ll)) * $p->p_rux.rux_sticks / ($p->p_rux.rux_uticks + $p->p_rux.rux_sticks + $p->p_rux.rux_iticks)
$3956 = 257136383464
(kgdb) p ((uint64_t)$p->p_rux.rux_runtime * 1000ll / ((cpu_ticks == tc_cpu_ticks ? timehands->th_counter->tc_frequency : cpu_tick_frequency) / 1000ll))
$3959 = 537288008712
(kgdb) p $p->p_rux.rux_sticks 
$3960 = 66663850
(kgdb) p ((uint64_t)$p->p_rux.rux_runtime * 1000ll / ((cpu_ticks == tc_cpu_ticks ? timehands->th_counter->tc_frequency : cpu_tick_frequency) / 1000ll)) * $p->p_rux.rux_sticks
$3961 = 17371417884613589424

Showing the correct result of 'tu * st' in python(1):
>>> 537288008712*66663850
35817687219575461200L

This result is actually greater than ULLONG_MAX.

Tested on kernel version 10.3-RELEASE-p20 and 11.1-RELEASE.