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>
