Date: Thu, 29 Aug 2002 14:20:53 -0700 (PDT) From: Archie Cobbs <archie@packetdesign.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/42175: libc_r: possible for select(2) to return ok with no bit set Message-ID: <200208292120.g7TLKrZ85466@bubba.packetdesign.com>
next in thread | raw e-mail | index | archive | help
>Number: 42175
>Category: bin
>Synopsis: libc_r: possible for select(2) to return ok with no bit set
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Aug 29 14:30:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Archie Cobbs
>Release: FreeBSD 4.5-RELEASE i386
>Organization:
Packet Design
>Environment:
System: FreeBSD bubba.packetdesign.com 4.5-RELEASE FreeBSD 4.5-RELEASE #0: Mon Jul 1 10:25:06 PDT 2002 root@bubba.packetdesign.com:/usr/src/sys/compile/BUBBA i386
>Description:
The libc_r version of select(2) doesn't check for error conditions
on the file descriptor for readability or writability. So it's possible
for select() to return zero, yet no file descriptor bits are set.
>How-To-Repeat:
Compile and run this program first linking with libc, then with
libc_r:
$ cc -Wall -o xx xx.c
$ cc -Wall -o xxp xx.c -D_THREAD_SAFE -pthread
$ ./xx
press ctrl-c...
^Cxx: select: Bad file descriptor
$ ./xxp
press ctrl-c...
^Cstdin readable=0
Notice in the second case, select() returned OK but stdin
was not marked readable.
============================== CUT HERE ================================
#ifdef __linux__
#define _XOPEN_SOURCE 600
#define _GNU_SOURCE 1
#define _BSD_SOURCE 1
#define _ISOC99_SOURCE 1
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <err.h>
static void handler(int sig);
int
main(int ac, char **av)
{
fd_set fds;
printf("press ctrl-c...\n");
signal(SIGINT, handler);
FD_ZERO(&fds);
FD_SET(0, &fds);
while (1) {
if (select(1, &fds, NULL, NULL, NULL) == -1) {
if (errno != EINTR)
err(1, "select");
continue;
}
break;
}
printf("stdin readable=%d\n", FD_ISSET(0, &fds) != 0);
/* Done */
return (0);
}
static void
handler(int sig)
{
if (close(0) == -1)
err(1, "close");
}
============================== CUT HERE ================================
>Fix:
Index: uthread_select.c
===================================================================
RCS file: /home/ncvs/src/lib/libc_r/uthread/uthread_select.c,v
retrieving revision 1.20
diff -u -r1.20 uthread_select.c
--- uthread_select.c 2 May 2002 19:58:43 -0000 1.20
+++ uthread_select.c 29 Aug 2002 21:06:21 -0000
@@ -179,8 +179,9 @@
got_events = 0;
if (readfds != NULL) {
if (FD_ISSET(data.fds[i].fd, readfds)) {
- if (data.fds[i].revents & (POLLIN |
- POLLRDNORM))
+ if ((data.fds[i].revents & (POLLIN
+ | POLLRDNORM | POLLERR
+ | POLLHUP | POLLNVAL)) != 0)
got_events++;
else
FD_CLR(data.fds[i].fd, readfds);
@@ -188,8 +189,9 @@
}
if (writefds != NULL) {
if (FD_ISSET(data.fds[i].fd, writefds)) {
- if (data.fds[i].revents & (POLLOUT |
- POLLWRNORM | POLLWRBAND))
+ if ((data.fds[i].revents & (POLLOUT
+ | POLLWRNORM | POLLWRBAND | POLLERR
+ | POLLHUP | POLLNVAL)) != 0)
got_events++;
else
FD_CLR(data.fds[i].fd,
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208292120.g7TLKrZ85466>
