From owner-freebsd-bugs Tue Oct 17 15:33:53 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by hub.freebsd.org (Postfix) with SMTP id A758B37B479; Tue, 17 Oct 2000 15:33:46 -0700 (PDT) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id <aa65883@salmon>; 17 Oct 2000 23:33:45 +0100 (BST) Date: Tue, 17 Oct 2000 23:33:44 +0100 From: David Malone <dwmalone@maths.tcd.ie> To: Bruce Evans <bde@zeta.org.au> Cc: freebsd-bugs@FreeBSD.org, jlemon@FreeBSD.org, bp@FreeBSD.org, marcel@FreeBSD.org Subject: Re: kern/18909: select(2) timeout limited to 100000000 seconds Message-ID: <20001017233344.A88671@walton.maths.tcd.ie> References: <200006080840.BAA25083@freefall.freebsd.org> <20000612221136.A18521@walton.maths.tcd.ie> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20000612221136.A18521@walton.maths.tcd.ie>; from dwmalone@maths.tcd.ie on Mon, Jun 12, 2000 at 10:11:37PM +0100 Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org I'd like to commit something along the lines of the following patch. It removes calls to "itimerfix" for select, poll and other code which has been copied from them. Itimerfix limits the duration you can wait to 100000000 seconds, which isn't needed in the cases I've looked at 'cos they know how to sleep for a shorter amount of time and then go back to sleep again if they have to wait for longer. The crux of the change is a function timevaladdcheck which adds two timevals but checks the sum won't overflow or underflow. I think it avoids doing any calculations which might cause problems. David. Index: compat/linux/linux_misc.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.85 diff -u -r1.85 linux_misc.c --- compat/linux/linux_misc.c 2000/08/26 05:08:10 1.85 +++ compat/linux/linux_misc.c 2000/10/17 14:41:04 @@ -457,7 +457,7 @@ printf("Linux-emul(%ld): incoming timeout (%ld/%ld)\n", (long)p->p_pid, utv.tv_sec, utv.tv_usec); #endif - if (itimerfix(&utv)) { + if (utv.tv_sec < 0 || utv.tv_usec < 0 || utv.tv_sec >= 1000000) { /* * The timeval was invalid. Convert it to something * valid that will act as it does under Linux. Index: kern/kern_event.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/kern/kern_event.c,v retrieving revision 1.16 diff -u -r1.16 kern_event.c --- kern/kern_event.c 2000/08/30 04:49:07 1.16 +++ kern/kern_event.c 2000/10/17 14:51:34 @@ -525,17 +525,15 @@ if (tsp != NULL) { TIMESPEC_TO_TIMEVAL(&atv, tsp); - if (itimerfix(&atv)) { - error = EINVAL; - goto done; - } if (tsp->tv_sec == 0 && tsp->tv_nsec == 0) timeout = -1; else timeout = atv.tv_sec > 24 * 60 * 60 ? 24 * 60 * 60 * hz : tvtohz(&atv); getmicrouptime(&rtv); - timevaladd(&atv, &rtv); + error = timevaladdcheck(&atv, &rtv); + if (error) + goto done; } else { atv.tv_sec = 0; atv.tv_usec = 0; Index: kern/kern_time.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/kern/kern_time.c,v retrieving revision 1.70 diff -u -r1.70 kern_time.c --- kern/kern_time.c 2000/04/18 15:15:20 1.70 +++ kern/kern_time.c 2000/10/17 14:03:32 @@ -49,6 +49,8 @@ #include <vm/vm.h> #include <vm/vm_extern.h> +#include <machine/limits.h> + struct timezone tz; /* @@ -656,6 +658,35 @@ t1->tv_sec -= t2->tv_sec; t1->tv_usec -= t2->tv_usec; timevalfix(t1); +} + +int +timevaladdcheck(t1, t2) + struct timeval *t1, *t2; +{ + struct timeval xtv; + + if (t1->tv_usec < 0 || t1->tv_usec >= 1000000 || + t2->tv_usec < 0 || t2->tv_usec >= 1000000) + return EINVAL; + + /* Check for underflow or overflow if result is not between t1 & t2 */ + if (t1->tv_sec >= 0 && t2->tv_sec >= 0) { + xtv.tv_sec = LONG_MAX; + xtv.tv_usec = 999999; + timevalsub(&xtv, t1); + if (timevalcmp(t2, &xtv, >)) + return EINVAL; + } else if (t1->tv_sec < 0 && t2->tv_sec < 0) { + xtv.tv_sec = LONG_MIN; + xtv.tv_usec = 0; + timevalsub(&xtv, t1); + if (timevalcmp(t2, &xtv, <)) + return EINVAL; + } + + timevaladd(t1, t2); + return 0; } static void Index: kern/sys_generic.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/kern/sys_generic.c,v retrieving revision 1.63 diff -u -r1.63 sys_generic.c --- kern/sys_generic.c 2000/07/28 22:17:42 1.63 +++ kern/sys_generic.c 2000/10/17 14:18:09 @@ -692,12 +692,14 @@ sizeof (atv)); if (error) goto done; - if (itimerfix(&atv)) { + getmicrouptime(&rtv); + error = timevaladdcheck(&atv, &rtv); + if (error) + goto done; + if (timevalcmp(&atv, &rtv, <)) { error = EINVAL; goto done; } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); } else { atv.tv_sec = 0; atv.tv_usec = 0; @@ -827,12 +829,14 @@ if (SCARG(uap, timeout) != INFTIM) { atv.tv_sec = SCARG(uap, timeout) / 1000; atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; - if (itimerfix(&atv)) { + getmicrouptime(&rtv); + error = timevaladdcheck(&atv, &rtv); + if (error) + goto done; + if (timevalcmp(&atv, &rtv, <)) { error = EINVAL; goto done; } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); } else { atv.tv_sec = 0; atv.tv_usec = 0; Index: netncp/ncp_sock.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/netncp/ncp_sock.c,v retrieving revision 1.2 diff -u -r1.2 ncp_sock.c --- netncp/ncp_sock.c 1999/10/12 10:36:59 1.2 +++ netncp/ncp_sock.c 2000/10/17 14:30:34 @@ -203,12 +203,10 @@ if (tv) { atv=*tv; - if (itimerfix(&atv)) { - error = EINVAL; - goto done; - } getmicrouptime(&rtv); - timevaladd(&atv, &rtv); + error = timevaladdcheck(&atv, &rtv); + if (error) + goto done; } timo = 0; retry: @@ -224,7 +222,8 @@ goto done; ttv=atv; timevalsub(&ttv, &rtv); - timo = tvtohz(&ttv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); } s = splhigh(); if ((p->p_flag & P_SELECT) == 0) { Index: sys/time.h =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/sys/time.h,v retrieving revision 1.43 diff -u -r1.43 time.h --- sys/time.h 2000/03/20 14:09:05 1.43 +++ sys/time.h 2000/10/17 13:47:49 @@ -199,6 +199,7 @@ void nanouptime __P((struct timespec *ts)); void nanotime __P((struct timespec *ts)); void timevaladd __P((struct timeval *, struct timeval *)); +int timevaladdcheck __P((struct timeval *, struct timeval *)); void timevalsub __P((struct timeval *, struct timeval *)); int tvtohz __P((struct timeval *)); #else /* !_KERNEL */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message