Poor kernel handling of invalid select() timeout

Dan Egnor (egnor@ofb.net)
6 Dec 1998 01:12:13 GMT


Hi,

Consider the following program:

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = -100000;
printf("select => %d\n",select(0,NULL,NULL,NULL,&tv));
return 0;
}

This program, when executed, prints:

select => 0

and causes the kernel to printk a message something like the following:

schedule_timeout: wrong timeout value fffffff7 from c0130a98

This happens because the code in "fs/select.c" carefully makes sure not to
overrun the _maximum_ timeout value, but performs no checking against negative
timeout values. So the negative value is passed directly through to the
timeout scheduler, which isn't so lax; it prints the warning message quoted
above and wakes up the process.

This is trivially fixed, but I'm not sure what the correct behavior is with
a negative timeout value. Presumably one of the following should happen:

1. select() fails with EINVAL
2. select() succeeds, returning immediately (as with a 0 timeout)

The Linux select() man page says nothing about this case, but only documents
EINVAL for a negative FD count. The Unix98 spec documents EINVAL in case of
"invalid timeout value" but doesn't specify what that means. The wording for
timeout behavior could be interpreted as allowing negative timeouts (they
would just expire immediately).

(Pragmatically, I'd say that given the ambiguity of the spec, any user-land
program which generates a negative timeout is broken, and we should fail the
call to select().)

This is an issue because some broken program (yet to be tracked down) somehow
ended up with a negative timeout; select() kept "succeeding" despite this,
and the syslogs started filling up with confusing "wrong timeout value" errors.
If the kernel returned EINVAL, the program would have an opportunity to
discover the error of its ways; if the kernel silently accepted it, at least
the syslogs wouldn't fill with spooge.

Dan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/