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