Subject: pkg/17745: aterm may be locked up in select()
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ChristianBiere@gmx.de>
List: netbsd-bugs
Date: 07/28/2002 13:28:52
>Number:         17745
>Category:       pkg
>Synopsis:       aterm may be locked up in select()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 28 13:29:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Christian Biere
>Release:        NetBSD 1.6D
>Organization:
>Environment:
System: NetBSD localhost 1.6D NetBSD 1.6D (DURON2) #0: Sat Jul 27 08:52:59 CEST
2002 root@localhost:/usr/src/sys/arch/i386/compile/DURON2 i386
Architecture: i386 
Machine: i386

>Description:
This is what I've just submitted to the developers of aterm:

Hi,

there's a problem in command.c. First you should not
do FD_ISSET if select() returned -1. The critical
problem is (it's not your fault) that FD_SETSIZE
and syconf(_SC_OPEN_MAX) may tell you different values.
Unfortunately (at least with NetBSD) FD_ZERO, FD_SET,
FD_ISSET are macros which use the constant value of
FD_SETSIZE. This means if the admin/user has set the max. 
open-file-limit to a value above FD_SETSIZE FD_ZERO does
not clear any bits above FD_SETSIZE and select() may 
return -1 with errno=EBADF because the value of bits 
above FD_SETSIZE is undeterminated.

Regards,
Christian

I don't know whether aterm is still maintained or if this
problem is really just a problem on NetBSD. Therefore this
patch should be added to pkgsrc.
>How-To-Repeat:
Make sure your shell limit for open files is above 256:

$ ulimit -n
1024
$ aterm

ktrace/kdump report the following until the end of time:

21155 aterm    CALL  read(0x4,0x805ce00,0x400)
21155 aterm    RET   read -1 errno 35 Resource temporarily unavailable
21155 aterm    CALL  ioctl(0x3,FIONREAD,0xbfbfd028)
21155 aterm    RET   ioctl 0
21155 aterm    CALL  select(0x400,0xbfbfd8c8,0,0,0xbfbfd8c0)
21155 aterm    RET   select -1 errno 9 Bad file descriptor
21155 aterm    CALL  read(0x4,0x805ce00,0x400)
21155 aterm    RET   read -1 errno 35 Resource temporarily unavailable
21155 aterm    CALL  ioctl(0x3,FIONREAD,0xbfbfd028)
21155 aterm    RET   ioctl 0

As I said they use FD_ISSET even if select() returns -1 or 0. That's
why we see the calls read() here.

>Fix:
Here's the patch. As I wrote the problem originates from the macro
FD_ZERO in /usr/include/sys/types.h.

--- src/command.c       Thu Sep  6 09:38:07 2001
+++ src/command.c       Sun Jul 28 12:45:07 2002
@@ -1146,6 +1146,11 @@
     num_fds = getdtablesize();
 #endif
 
+#if defined(__NetBSD__)
+    if (num_fds > FD_SETSIZE)
+      num_fds = FD_SETSIZE;
+#endif
+    
 #ifdef META8_OPTION
     meta_char = (Options & Opt_meta8 ? 0x80 : 033);
     if (rs_modifier
@@ -2024,7 +2029,7 @@
 #endif
 
     /* See if we can read from the application */
-       if (FD_ISSET(cmd_fd, &readfds)) {
+       if (retval > 0 && FD_ISSET(cmd_fd, &readfds)) {
            unsigned int    count = BUFSIZ;
 
            cmdbuf_ptr = cmdbuf_endp = cmdbuf_base;

>Release-Note:
>Audit-Trail:
>Unformatted: