From owner-freebsd-standards@FreeBSD.ORG Wed Feb 23 23:07:13 2011 Return-Path: Delivered-To: freebsd-standards@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 39086106566C; Wed, 23 Feb 2011 23:07:13 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail01.syd.optusnet.com.au (mail01.syd.optusnet.com.au [211.29.132.182]) by mx1.freebsd.org (Postfix) with ESMTP id CAEA38FC1A; Wed, 23 Feb 2011 23:07:12 +0000 (UTC) Received: from c122-107-114-89.carlnfd1.nsw.optusnet.com.au (c122-107-114-89.carlnfd1.nsw.optusnet.com.au [122.107.114.89]) by mail01.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id p1NN78fr001006 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 24 Feb 2011 10:07:10 +1100 Date: Thu, 24 Feb 2011 10:07:08 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Alexander Best In-Reply-To: <201102232140.p1NLe84o010841@freefall.freebsd.org> Message-ID: <20110224091827.K1658@besplex.bde.org> References: <201102232140.p1NLe84o010841@freefall.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-standards@freebsd.org Subject: Re: standards/149980: [libc] [patch] negative value integer to nanosleep(2) should fail with EINVAL X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Feb 2011 23:07:13 -0000 On Wed, 23 Feb 2011, Alexander Best wrote: > The following reply was made to PR standards/149980; it has been noted by GNATS. > > From: Alexander Best > To: bug-followup@freebsd.org > Cc: > Subject: Re: standards/149980: [libc] [patch] negative value integer to nanosleep(2) should fail with EINVAL > Date: Wed, 23 Feb 2011 21:38:02 +0000 > > since this might break some ports or 3rd party applications, how about adding > something like kern.allow_negative_sleep? It shouldn't fail. POSIX doesn't require it to fail, at least in the old 2001 draft7: % 26886 ERRORS % 26887 The nanosleep( ) function shall fail if: % 26888 [EINTR] The nanosleep( ) function was interrupted by a signal. % 26889 [EINVAL] The rqtp argument specified a nanosecond value less than zero or greater than % 26890 or equal to 1000 million. It just specifies EINVAL for out-of-bounds nanoseconds values because those give an invalid timeval. Negative values for the seconds field are valid if they are representable. A negative sleep time is equally physically impossible as a sleep time of 0, but I haven't seen any proposals to break the latter. But if you want full breakage, be sure to disallow both negative timevals and ones longer than the lifetime of the universe ;-). In private or maybe public old mail about this, I pointed out bugs in itimerfix() and itimespecfix(). These functions do generate EINVAL for negative times and are very broken for large positive values considerably shorter than the lifetime of the universe for 32-bit time_t's but considerably longer than the lifetime of the universe for 64-bit time_t's. Callers depend on the time_t's being considerably less than the time until the time_t's wrap around. This used ti be avoided (until 2035 for 32-bit signed time_t's) by restricting the time_t's to 1000 million seconds (3+ years) in itimerfix(). This has been broken, so anyone who can make syscalls that use itimers can cause overflows in the kernel. Limiting the maximum itimer to 100 million seconds or even the lifetime of the univers is not supported by POSIX, but it is what BSD always did until FreeBSD broke it. itimerfix() and itimespecfix() also do bogus rounding up to a multiple of the timer granularity. This is mostly cosmetic, but breaks syscalls that return residual times. itimespecfix() also has a namespace error. It corresponds to itimerfix(). There is no itimevalfix(), but there is a confusingly similar timevalfix(). These bugs don't directly affect nanosleep(), since it doesn't use itimespecfix(), perhaps intentionally to avoid breaking it for negative times. Its overflow bugs bugs are smaller in nanosleep(), since it loops internally to handle large times and its algorithm of comparing the current time with the end time in case it wakes up early is fairly robust. However, it blindly adds timespecs using timespecadd(&ts, rqt), where ts is initially the current time (spec) and *rqt is the arg, and ts is finally the end time. *rqt must be limited to prevent overflow of this. The usual (but broken) limit of 100 million seconds would work (until 2035) as elsewhere. When overflow occurs, the result is undefined. The actual behaviour is normally a garbage negative end time in ts, and although there are lots of compensating overflows (adding and subtracting the current time), I think the logic isn't all accidentally correct throughout. Bruce