Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Aug 2010 05:50:05 GMT
From:      Garrett Cooper <gcooper@FreeBSD.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/149980: [PATCH] negative value integer to nanosleep(2) should fail with EINVAL
Message-ID:  <201008260550.o7Q5o5hf065099@www.freebsd.org>
Resent-Message-ID: <201008260600.o7Q60Hcs093370@freefall.freebsd.org>

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

>Number:         149980
>Category:       kern
>Synopsis:       [PATCH] negative value integer to nanosleep(2) should fail with EINVAL
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          doc-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 26 06:00:16 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Garrett Cooper
>Release:        9-CURRENT
>Organization:
Cisco Systems, Inc.
>Environment:
FreeBSD bayonetta.local 9.0-CURRENT FreeBSD 9.0-CURRENT #9 r211309M: Thu Aug 19 22:50:36 PDT 2010     root@bayonetta.local:/usr/obj/usr/src/sys/BAYONETTA  amd64
>Description:
After some discussion with the POSIX folks, the spec doesn't discuss the tv_sec quantity, partly because the time_t value that gets plugged in for tv_sec can be positive or negative, depending on the implementation in the operating system. In FreeBSD time_t is signed, and in Linux it's unsigned.

Signedness values aside, it doesn't make sense to sleep negative time, because PCs shouldn't be traveling to the past :).

The patch clearly notes the positive real number requirement and addresses the < 0 quantity issue at the kernel level.

# BEFORE
$ ./test_nanosleep_negative_time
passed unexpectedly
# AFTER
$ ./test_nanosleep_negative_time
failed as expected
$ echo $?
0
>How-To-Repeat:
1. Compile the following program:

#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>

int
main(void)
{

	struct timespec rqtp;

	rqtp.tv_sec = -1;
	rqtp.tv_nsec = 0;

	if (nanosleep(&rqtp, NULL) == -1) {
		if (errno == EINVAL) {
			printf("failed as expected\n");
			return (0);
		} else
			warn("failed unexpectedly");
	} else
		printf("passed unexpectedly\n");

	return (1);
}

2. Execute the compiled binary.
>Fix:


Patch attached with submission follows:

Index: lib/libc/sys/nanosleep.2
===================================================================
--- lib/libc/sys/nanosleep.2	(revision 211794)
+++ lib/libc/sys/nanosleep.2	(working copy)
@@ -93,6 +93,11 @@
 The
 .Fa rqtp
 argument
+specified a second value less than zero.
+.It Bq Er EINVAL
+The
+.Fa rqtp
+argument
 specified a nanosecond value less than zero
 or greater than or equal to 1000 million.
 .It Bq Er ENOSYS
Index: sys/kern/kern_time.c
===================================================================
--- sys/kern/kern_time.c	(revision 211794)
+++ sys/kern/kern_time.c	(working copy)
@@ -358,7 +358,9 @@
 
 	if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
 		return (EINVAL);
-	if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
+	if (rqt->tv_sec < 0)
+		return (EINVAL);
+	if (rqt->tv_sec == 0 && rqt->tv_nsec == 0)
 		return (0);
 	getnanouptime(&ts);
 	timespecadd(&ts, rqt);


>Release-Note:
>Audit-Trail:
>Unformatted:



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