From archie@packetdesign.com  Thu Aug 29 14:20:55 2002
Return-Path: <archie@packetdesign.com>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 271DE37B400
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 29 Aug 2002 14:20:55 -0700 (PDT)
Received: from mailman.packetdesign.com (dns.packetdesign.com [65.192.41.10])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 6D71443E42
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 29 Aug 2002 14:20:54 -0700 (PDT)
	(envelope-from archie@packetdesign.com)
Received: from bubba.packetdesign.com (bubba.packetdesign.com [192.168.0.223])
	by mailman.packetdesign.com (8.11.6/8.11.6) with ESMTP id g7TLKsx16078
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 29 Aug 2002 14:20:54 -0700 (PDT)
	(envelope-from archie@packetdesign.com)
Received: (from archie@localhost)
	by bubba.packetdesign.com (8.11.6/8.11.6) id g7TLKrZ85466;
	Thu, 29 Aug 2002 14:20:53 -0700 (PDT)
	(envelope-from archie)
Message-Id: <200208292120.g7TLKrZ85466@bubba.packetdesign.com>
Date: Thu, 29 Aug 2002 14:20:53 -0700 (PDT)
From: Archie Cobbs <archie@packetdesign.com>
Reply-To: Archie Cobbs <archie@packetdesign.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: libc_r: possible for select(2) to return ok with no bit set
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>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:    archie
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 29 14:30:01 PDT 2002
>Closed-Date:    Sat Aug 31 15:18:36 PDT 2002
>Last-Modified:  Sat Aug 31 15:18:36 PDT 2002
>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:
Responsible-Changed-From-To: freebsd-bugs->archie 
Responsible-Changed-By: archie 
Responsible-Changed-When: Thu Aug 29 14:33:56 PDT 2002 
Responsible-Changed-Why:  
I'm working on this bug. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=42175 
State-Changed-From-To: open->closed 
State-Changed-By: archie 
State-Changed-When: Sat Aug 31 15:17:30 PDT 2002 
State-Changed-Why:  
Fixed in -current and -stable by revisions 1.21 and 1.16.2.2 of 
src/lib/libc_r/uthread/uthread_select.c. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=42175 
>Unformatted:
