On Tue, Sep 20, 2016 at 08:21:55AM -0400, David Hill wrote:
> With bluhm's r1.160 uipc_socket.c.
> Here are the first ones that were detected.

Thanks for the fast report.

So fifo works around the socket layer.  Better call soconnect2()
instead of unp_connect2().  This adds the missing splsoftnet().

I think we should demand that socantsendmore() and socantrcvmore()
in uipc_socket2.c should be called with splsoftnet().

ok?

bluhm

Index: miscfs/fifofs/fifo_vnops.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v
retrieving revision 1.51
diff -u -p -r1.51 fifo_vnops.c
--- miscfs/fifofs/fifo_vnops.c  7 Jun 2016 06:12:37 -0000       1.51
+++ miscfs/fifofs/fifo_vnops.c  20 Sep 2016 13:04:56 -0000
@@ -48,7 +48,6 @@
 #include <sys/errno.h>
 #include <sys/malloc.h>
 #include <sys/poll.h>
-#include <sys/unpcb.h>
 #include <sys/unistd.h>
 
 #include <miscfs/fifofs/fifo.h>
@@ -143,7 +142,7 @@ fifo_open(void *v)
                        return (error);
                }
                fip->fi_writesock = wso;
-               if ((error = unp_connect2(wso, rso)) != 0) {
+               if ((error = soconnect2(wso, rso)) != 0) {
                        (void)soclose(wso);
                        (void)soclose(rso);
                        free(fip, M_VNODE, sizeof *fip);
@@ -350,20 +349,25 @@ fifo_close(void *v)
        struct vop_close_args *ap = v;
        struct vnode *vp = ap->a_vp;
        struct fifoinfo *fip = vp->v_fifoinfo;
-       int error1 = 0, error2 = 0;
+       int s, error1 = 0, error2 = 0;
 
        if (fip == NULL)
                return (0);
 
        if (ap->a_fflag & FREAD) {
-               if (--fip->fi_readers == 0)
+               if (--fip->fi_readers == 0) {
+                       s = splsoftnet();
                        socantsendmore(fip->fi_writesock);
+                       splx(s);
+               }
        }
        if (ap->a_fflag & FWRITE) {
                if (--fip->fi_writers == 0) {
+                       s = splsoftnet();
                        /* SS_ISDISCONNECTED will result in POLLHUP */
                        fip->fi_readsock->so_state |= SS_ISDISCONNECTED;
                        socantrcvmore(fip->fi_readsock);
+                       splx(s);
                }
        }
        if (fip->fi_readers == 0 && fip->fi_writers == 0) {

Reply via email to