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>