Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 07 Sep 2006 23:55:26 +1000
From:      Mark Andrews <Mark_Andrews@isc.org>
To:        freebsd-stable@freebsd.org
Subject:   Re: large system date skew on RELENG_6 changes causes select() failures 
Message-ID:  <200609071355.k87DtQNW047776@drugs.dv.isc.org>
In-Reply-To: Your message of "Thu, 07 Sep 2006 09:26:22 %2B0200." <20060907072622.GA28784@localhost.localdomain> 

next in thread | previous in thread | raw e-mail | index | archive | help

> On Tue, Sep 05, 2006, Mark Andrews wrote:
> 
> >>> A while ago, by accident, I've changed the system date back to the '98
> >>> using date(1). To my astonishment, screen(1) barfed about EINVAL in
> >>> select() and died. Programs, including opera (native FreeBSD-6 binary)
> >>> kept spinning the CPU until I killed them.
> 
> >>> I have no means for debugging it.
> 
> >>> Is this somehow expected? If not (i.e. it's a bug), is it known?
> 
> >> Probably, they calculated timeout's which magicly became negative, which
> >> isn't a valid timeout, and none of the programs are programmed well enough
> >> to handle the case and exhibited the behavior that you saw...
> 
> > 	Nope.  Just a simple limit in itimerfix.
> 
> > int
> > itimerfix(struct timeval *tv)
> > {
> 
> > if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
> > tv->tv_usec < 0 || tv->tv_usec >= 1000000)
> > return (EINVAL);
> > if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
> > tv->tv_usec = tick;
> > return (0);
> > }
> 
> > 	date -j 9809051630 +%s -> 904977000
> > 	date +%s -> 1157438219
> > 	1157438219 - 904977000 -> 252461219 which is greater that 100000000
> 
> The loop in GNU screen, which invokes select() looks like this:
> 
> {
>   struct timeval t;
> 
>   t.tv_sec = (long) (msec / 1000);
>   t.tv_usec = (long) ((msec % 1000) * 1000);
>   select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
> }
> 
> There's no time_t substraction at all.
> 
> I dare to say that it's a bug.
> /me ducks
> _______________________________________________
> freebsd-stable@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-stable
> To unsubscribe, send any mail to "freebsd-stable-unsubscribe@freebsd.org"

	"man select" gives:

     [EINVAL]           The specified time limit is invalid.  One of its com-
                        ponents is negative or too large.

	"too large" is > 100000000 seconds which can be found by
	inspecting the kernel source.  In particular itimerfix().

	A simple fix for screen would be to put a upper bound on
	tv_sec which is <= 100000000.

	Mark
--
ISC Training!  October 16-20, 2006, in the San Francisco Bay Area,
covering topics from DNS to DHCP.  Email training@isc.org.
-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: Mark_Andrews@isc.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609071355.k87DtQNW047776>