From nobody@FreeBSD.ORG Fri Jun 11 11:55:04 1999
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 478F114F01; Fri, 11 Jun 1999 11:55:04 -0700 (PDT)
Message-Id: <19990611185504.478F114F01@hub.freebsd.org>
Date: Fri, 11 Jun 1999 11:55:04 -0700 (PDT)
From: davids@webmaster.com
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@freebsd.org
Subject: libc_r passes negative tv_usec values to setitimer -- crash
X-Send-Pr-Version: www-1.0

>Number:         12141
>Category:       kern
>Synopsis:       libc_r passes negative tv_usec values to setitimer -- crash
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 11 12:00:01 PDT 1999
>Closed-Date:    Thu Aug 19 17:48:17 PDT 1999
>Last-Modified:  Thu Aug 19 17:50:13 PDT 1999
>Originator:     David Schwartz
>Release:        3.2-STABLE
>Organization:
WebMaster, Incorporated
>Environment:
FreeBSD vermithrax.youwant.to 3.2-STABLE FreeBSD 3.2-STABLE #9: Mon Jun  7 10:15:02 PDT 1999     davids@vermithrax.youwant.to:/usr/src/sys/compile/DAVIDS  i386

>Description:
It seems that under some circumstances, the pthreads (libc_r) library computes a negative tv_usec value which it passes to setitimer. setitimer returns EINVAL, causing the threaded program to crash.



>How-To-Repeat:
I'm not sure what it is specifically that's causing it. But it is happening to three of my pthreads-based programs.
>Fix:

This is the *wrong* fix, but it does make the problem go away.

in uthread_kern.c:
                                /*
                                 * Start the interval timer for the
                                 * calculated time interval: 
                                 */
                                if(itimer.it_value.tv_usec<=0)
                                 itimer.it_value.tv_usec=1000;
                                if (setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL
) != 0) {


The 'if' has been added to remove the problem. But the real problem is why it's computing negative values in the first place.

>Release-Note:
>Audit-Trail:

From: Chris Costello <chris@calldei.com>
To: davids@webmaster.com
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/12141: libc_r passes negative tv_usec values to setitimer -- crash
Date: Fri, 11 Jun 1999 14:56:57 -0500

 On Fri, Jun 11, 1999, davids@webmaster.com wrote:
 > This is the *wrong* fix, but it does make the problem go away.
 > 
 > in uthread_kern.c:
 >                                 /*
 >                                  * Start the interval timer for the
 >                                  * calculated time interval: 
 >                                  */
 >                                 if(itimer.it_value.tv_usec<=0)
 >                                  itimer.it_value.tv_usec=1000;
 >                                 if (setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL
 > ) != 0) {
 > 
 > 
 > The 'if' has been added to remove the problem. But the real problem is why it's computing negative values in the first place.
 
    Actually, that's even wrong for your wrong fix.  The hack you
 probably want is more along the lines of
 
 if (itimer.it_value.tv_usec < 0)
 	itimer.it_value.tv_usec = 1000;
 
    It's perfectly ok for tv_usec to be 0.
 
 -- 
 Chris Costello                                <chris@calldei.com>
 As far as we know, our computer has never had an undetected error.  - Weisert
 

From: "David Schwartz" <davids@webmaster.com>
To: <freebsd-gnats-submit@freebsd.org>,
	"David Schwartz" <davids@webmaster.com>
Cc:  
Subject: Re: kern/12141: libc_r passes negative tv_usec values to setitimer -- crash
Date: Fri, 11 Jun 1999 13:50:44 -0700

 	Even that is not enough. Apparently tv_sec can be <0 too:
 
 Cannot set scheduling timer, errno=22, v.s=-1, v.us=1000
 
 	Presumable, usec was set to 1,000 by my hack. But the seconds were negative
 too! This crash is rarer than the one where just the usec value is negative.
 Here's my new hacked fix:
 
                                 if ( (itimer.it_value.tv_usec<0) ||
                                      (itimer.it_value.tv_sec<0) )
                                 {
                                  itimer.it_value.tv_usec=1000;
                                  itimer.it_value.tv_sec=0;
                                 }
 
 	David Schwartz
 
 

From: "David Schwartz" <davids@webmaster.com>
To: <freebsd-gnats-submit@freebsd.org>,
	"David Schwartz" <davids@webmaster.com>
Cc:  
Subject: Re: kern/12141: libc_r passes negative tv_usec values to setitimer -- crash
Date: Fri, 11 Jun 1999 20:06:07 -0700

 	The thread that causes the problem is always waiting for a condition
 variable, if that helps. I'm working very hard on a program to replicate the
 bug.
 
 	DS
 
 

From: "David Schwartz" <davids@webmaster.com>
To: <freebsd-gnats-submit@freebsd.org>,
	"David Schwartz" <davids@webmaster.com>
Cc:  
Subject: Re: kern/12141: libc_r passes negative tv_usec values to setitimer -- crash
Date: Fri, 11 Jun 1999 21:04:53 -0700

 	Wow, it was an overflow in my code causing me to call pthread_cond_timewait
 with an out-of-range number of nanoseconds. One billion is awfully close to
 the maximum an unsigned int/long can hold, so overflows are easy.
 
 	So the problem really is that pthread_cond_timedwait doesn't return an
 EINVAL when the input timespec is out of range. Instead it lets the
 scheduler fault later. The fix is either to document this unusual behavior
 or put sanity checks in pthread_cond_timedwait.
 
 	DS
 
 
State-Changed-From-To: open->closed 
State-Changed-By: chris 
State-Changed-When: Thu Aug 19 17:48:17 PDT 1999 
State-Changed-Why:  
Alfred Perlstein fixed this in -CURRENT and -STABLE. 
>Unformatted:
