kern/76972: 64-bit integer overflow computing user cpu time in
calcru() in kern_resource.c
Andrey Zonov
andrey at zonov.org
Thu Aug 2 13:50:09 UTC 2012
The following reply was made to PR kern/76972; it has been noted by GNATS.
From: Andrey Zonov <andrey at zonov.org>
To: bug-followup at FreeBSD.org, cal at 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 at 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--
More information about the freebsd-bugs
mailing list