Date: Thu, 2 Aug 2012 13:50:09 GMT From: Andrey Zonov <andrey@zonov.org> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/76972: 64-bit integer overflow computing user cpu time in calcru() in kern_resource.c Message-ID: <201208021350.q72Do9qa056777@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/76972; it has been noted by GNATS. From: Andrey Zonov <andrey@zonov.org> To: bug-followup@FreeBSD.org, cal@aero.org Cc: Subject: Re: kern/76972: 64-bit integer overflow computing user cpu time in calcru() in kern_resource.c Date: Thu, 02 Aug 2012 17:42:21 +0400 This is a multi-part message in MIME format. --------------080901070902080400040909 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, I stepped on this sometime ago. I suggest simple patch that fixed problem for me. $ ps -o lstart,time,systime,usertime -p 63292 STARTED TIME SYSTIME USERTIME Sat Jun 16 13:49:20 2012 1017686:25.32 67:05.75 1017619:19.56 -- Andrey Zonov --------------080901070902080400040909 Content-Type: text/plain; charset=UTF-8; name="kern_resource.c.patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kern_resource.c.patch.txt" commit 97dcdfe872b83ece41e61c434937f924ea3ef2f5 Author: Andrey Zonov <andrey@zonov.org> Date: Thu Jun 14 00:29:33 2012 +0400 - Prevent overflow for usertime/systime in caclru1(). diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index b09e031..cb3d854 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -880,6 +880,8 @@ rufetchtd(struct thread *td, struct rusage *ru) calcru1(p, &td->td_rux, &ru->ru_utime, &ru->ru_stime); } +#define mul_div(a, b, c) (a/c)*b + (a%c)*(b/c) + (a%c)*(b%c)/c + static void calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up, struct timeval *sp) @@ -909,10 +911,10 @@ calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up, * The normal case, time increased. * Enforce monotonicity of bucketed numbers. */ - uu = (tu * ut) / tt; + uu = mul_div(tu, ut, tt); if (uu < ruxp->rux_uu) uu = ruxp->rux_uu; - su = (tu * st) / tt; + su = mul_div(tu, st, tt); if (su < ruxp->rux_su) su = ruxp->rux_su; } else if (tu + 3 > ruxp->rux_tu || 101 * tu > 100 * ruxp->rux_tu) { @@ -941,8 +943,8 @@ calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up, "to %ju usec for pid %d (%s)\n", (uintmax_t)ruxp->rux_tu, (uintmax_t)tu, p->p_pid, p->p_comm); - uu = (tu * ut) / tt; - su = (tu * st) / tt; + uu = mul_div(tu, ut, tt); + su = mul_div(tu, st, tt); } ruxp->rux_uu = uu; --------------080901070902080400040909--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208021350.q72Do9qa056777>