kernel: fix a checkloop panic caused by EOPNOTSUPP not being passed down correctly
authorMarkus Pfeiffer <markus.pfeiffer@morphism.de>
Wed, 20 Jun 2012 21:59:48 +0000 (21:59 +0000)
committerMarkus Pfeiffer <markus.pfeiffer@morphism.de>
Wed, 20 Jun 2012 22:07:50 +0000 (22:07 +0000)
* When poll(2)ing /dev/tty dev_dkqfilter gets called twice,
  on the inner call, since EOPNOTSUPP is returned the outer
  call returns ENODEV leading to a checkloop panic.

* A new testcase in test/testcases/io/poll_1 will panic
  the system if started without this patch applied.

sys/kern/kern_device.c
test/testcases/io/Makefile
test/testcases/io/poll_1/Makefile [new file with mode: 0644]
test/testcases/io/poll_1/poll_1.c [new file with mode: 0644]

index 5de7ecb..cfa7146 100644 (file)
@@ -442,8 +442,10 @@ dev_dkqfilter(cdev_t dev, struct knote *kn)
        if (needmplock)
                rel_mplock();
 
-       if (error == 0)
+       if (error == 0) 
                return(ap.a_result);
+       else if (error == EOPNOTSUPP)
+               return(EOPNOTSUPP);
        return(ENODEV);
 }
 
index aeba81e..a7a259e 100644 (file)
@@ -2,5 +2,6 @@ SUBDIR+= pselect_1
 SUBDIR+= select_1 select_2 select_3 select_4
 SUBDIR+= sendfd_1
 SUBDIR+= kqueue_1 kqueue_2
+SUBDIT+= poll_1
 
 .include <bsd.subdir.mk>
diff --git a/test/testcases/io/poll_1/Makefile b/test/testcases/io/poll_1/Makefile
new file mode 100644 (file)
index 0000000..1cd1818
--- /dev/null
@@ -0,0 +1,4 @@
+PROG=          poll_1
+NOMAN=
+
+.include <bsd.prog.mk>
diff --git a/test/testcases/io/poll_1/poll_1.c b/test/testcases/io/poll_1/poll_1.c
new file mode 100644 (file)
index 0000000..a395e1a
--- /dev/null
@@ -0,0 +1,20 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <poll.h>
+
+int main()
+{
+       struct pollfd fds[1];
+
+       int p = open("/dev/tty", O_RDWR);
+       
+       printf("tty: %d\n", p);
+
+       fds[0].fd = p;
+       fds[0].events = 3;
+       fds[0].revents = 0;
+
+       poll(fds, 1, -1);
+
+       printf("polled\n");
+}