Date: Mon, 12 Jun 2000 22:11:37 +0100 From: David Malone <dwmalone@maths.tcd.ie> To: Bruce Evans <bde@zeta.org.au> Cc: freebsd-bugs@FreeBSD.org, archie@whistle.com Subject: Re: kern/18909: select(2) timeout limited to 100000000 seconds Message-ID: <20000612221136.A18521@walton.maths.tcd.ie> In-Reply-To: <200006080840.BAA25083@freefall.freebsd.org>; from bde@zeta.org.au on Thu, Jun 08, 2000 at 01:40:03AM -0700 References: <200006080840.BAA25083@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
I had a think about how to check for wraparound and negative times, and (if you assume current time is positive anyway) I think you can do both quite simply. You can just add the current time to the select timeout passed in and then compare to check you got a time in the future. If wraparound occured or if the timeout was negative you'll get a time in the past. The only other things itimerfix does I checked with a timevalvalid macro, which probably belongs in sys/time.h? (I don't think the min timeout thing needs to be done 'cos the callout stuff does that for you). I've just compiled a kernel with the following patch as a test and it seems to be working. If it looks reasonable I can extend it to similar bits of the kernel. (Almost identical code shows up in several places, the patch below just covers select and poll). [BTW - I just noticed that Archie's "How To Repeat" started with "void main(". Bad Bad Bad ;-)] David. Index: sys_generic.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/kern/sys_generic.c,v retrieving revision 1.56 diff -u -r1.56 sys_generic.c --- sys_generic.c 2000/05/09 17:43:20 1.56 +++ sys_generic.c 2000/06/12 20:49:46 @@ -663,17 +663,24 @@ if (nbufbytes != 0) bzero(selbits, nbufbytes / 2); +#define timevalvalid(tvp) \ + ( (tvp)->tv_usec >= 0 && (tvp)->tv_usec < 100000000 ) + if (uap->tv) { error = copyin((caddr_t)uap->tv, (caddr_t)&atv, sizeof (atv)); if (error) goto done; - if (itimerfix(&atv)) { + if (!timevalvalid(&atv)) { error = EINVAL; goto done; } getmicrouptime(&rtv); timevaladd(&atv, &rtv); + if (timevalcmp(&atv, &rtv, <)) { /* negative timeout/overflow */ + error = EINVAL; + goto done; + } } else atv.tv_sec = 0; timo = 0; @@ -801,12 +808,16 @@ if (SCARG(uap, timeout) != INFTIM) { atv.tv_sec = SCARG(uap, timeout) / 1000; atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; - if (itimerfix(&atv)) { + if (!timevalvalid(&atv)) { error = EINVAL; goto done; } getmicrouptime(&rtv); timevaladd(&atv, &rtv); + if (timevalcmp(&atv, &rtv, <)) { /* negative timeout/overflow */ + error = EINVAL; + goto done; + } } else atv.tv_sec = 0; timo = 0; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000612221136.A18521>