Restore original EPIPE and ENOTCONN errors priority in the uipc_send()
authormvs <mvs@openbsd.org>
Fri, 28 Jun 2024 21:30:24 +0000 (21:30 +0000)
committermvs <mvs@openbsd.org>
Fri, 28 Jun 2024 21:30:24 +0000 (21:30 +0000)
path changed in rev 1.206. At least acme-client(1) is not happy with
this change.

Reported by claudio. Tests and ok by bluhm.

sys/kern/uipc_socket2.c
sys/kern/uipc_usrreq.c
sys/miscfs/fifofs/fifo_vnops.c

index df5086c..27edd54 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_socket2.c,v 1.155 2024/05/17 19:11:14 mvs Exp $  */
+/*     $OpenBSD: uipc_socket2.c,v 1.156 2024/06/28 21:30:24 mvs Exp $  */
 /*     $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $       */
 
 /*
@@ -160,8 +160,6 @@ void
 soisdisconnected(struct socket *so)
 {
        soassertlocked(so);
-       so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
-       so->so_state |= SS_ISDISCONNECTED;
 
        mtx_enter(&so->so_rcv.sb_mtx);
        so->so_rcv.sb_state |= SS_CANTRCVMORE;
@@ -171,6 +169,9 @@ soisdisconnected(struct socket *so)
        so->so_snd.sb_state |= SS_CANTSENDMORE;
        mtx_leave(&so->so_snd.sb_mtx);
 
+       so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
+       so->so_state |= SS_ISDISCONNECTED;
+
        wakeup(&so->so_timeo);
        sowwakeup(so);
        sorwakeup(so);
index bbedc65..1dbe0e7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_usrreq.c,v 1.207 2024/06/26 12:23:36 mvs Exp $   */
+/*     $OpenBSD: uipc_usrreq.c,v 1.208 2024/06/28 21:30:24 mvs Exp $   */
 /*     $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $        */
 
 /*
@@ -513,6 +513,14 @@ uipc_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
                        goto out;
        }
 
+       /*
+        * We hold both solock() and `sb_mtx' mutex while modifying
+        * SS_CANTSENDMORE flag. solock() is enough to check it.
+        */
+       if (so->so_snd.sb_state & SS_CANTSENDMORE) {
+               error = EPIPE;
+               goto dispose;
+       }
        if (unp->unp_conn == NULL) {
                error = ENOTCONN;
                goto dispose;
@@ -531,12 +539,6 @@ uipc_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
         */
        mtx_enter(&so2->so_rcv.sb_mtx);
        mtx_enter(&so->so_snd.sb_mtx);
-       if (so->so_snd.sb_state & SS_CANTSENDMORE) {
-               mtx_leave(&so->so_snd.sb_mtx);
-               mtx_leave(&so2->so_rcv.sb_mtx);
-               error = EPIPE;
-               goto dispose;
-       }
        if (control) {
                if (sbappendcontrol(so2, &so2->so_rcv, m, control)) {
                        control = NULL;
index 97b14c1..aa04381 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fifo_vnops.c,v 1.105 2024/05/03 17:43:09 mvs Exp $    */
+/*     $OpenBSD: fifo_vnops.c,v 1.106 2024/06/28 21:30:24 mvs Exp $    */
 /*     $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
 
 /*
@@ -174,10 +174,16 @@ fifo_open(void *v)
                        return (error);
                }
                fip->fi_readers = fip->fi_writers = 0;
+               /*
+                * Should take both solock() and `sb_mtx' mutex for
+                * SS_CANTSENDMORE flag modifications.
+                */
+               solock(wso);
                mtx_enter(&wso->so_snd.sb_mtx);
                wso->so_snd.sb_state |= SS_CANTSENDMORE;
                wso->so_snd.sb_lowat = PIPE_BUF;
                mtx_leave(&wso->so_snd.sb_mtx);
+               sounlock(wso);
        } else {
                rso = fip->fi_readsock;
                wso = fip->fi_writesock;
@@ -185,9 +191,11 @@ fifo_open(void *v)
        if (ap->a_mode & FREAD) {
                fip->fi_readers++;
                if (fip->fi_readers == 1) {
+                       solock(wso);
                        mtx_enter(&wso->so_snd.sb_mtx);
                        wso->so_snd.sb_state &= ~SS_CANTSENDMORE;
                        mtx_leave(&wso->so_snd.sb_mtx);
+                       sounlock(wso);
                        if (fip->fi_writers > 0)
                                wakeup(&fip->fi_writers);
                }