Skip site navigation (1)Skip section navigation (2)
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>