Do not truncate MSG_EOR in recvmsg().
authorbluhm <bluhm@openbsd.org>
Mon, 30 Oct 2023 13:27:53 +0000 (13:27 +0000)
committerbluhm <bluhm@openbsd.org>
Mon, 30 Oct 2023 13:27:53 +0000 (13:27 +0000)
The soreceive() code depends on the fact that MSG_EOR is set on the
last mbuf of the chain.  In sbappendcontrol() move MSG_EOR to the
end like sbcompress() does it.  This fixes MSG_EOR handling for
SOCK_SEQPACKET sockets with control message.

bug reported by Eric Wong
analysed, tested and OK claudio@

sys/kern/uipc_socket2.c

index e6cc57f..f21e0e2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_socket2.c,v 1.137 2023/07/04 22:28:24 mvs Exp $  */
+/*     $OpenBSD: uipc_socket2.c,v 1.138 2023/10/30 13:27:53 bluhm Exp $        */
 /*     $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $       */
 
 /*
@@ -920,7 +920,7 @@ sbappendcontrol(struct socket *so, struct sockbuf *sb, struct mbuf *m0,
     struct mbuf *control)
 {
        struct mbuf *m, *mlast, *n;
-       int space = 0;
+       int eor = 0, space = 0;
 
        if (control == NULL)
                panic("sbappendcontrol");
@@ -930,8 +930,16 @@ sbappendcontrol(struct socket *so, struct sockbuf *sb, struct mbuf *m0,
                        break;
        }
        n = m;                  /* save pointer to last control buffer */
-       for (m = m0; m; m = m->m_next)
+       for (m = m0; m; m = m->m_next) {
                space += m->m_len;
+               eor |= m->m_flags & M_EOR;
+               if (eor) {
+                       if (m->m_next == NULL)
+                               m->m_flags |= M_EOR;
+                       else
+                               m->m_flags &= ~M_EOR;
+               }
+       }
        if (space > sbspace(so, sb))
                return (0);
        n->m_next = m0;                 /* concatenate data to control */