Author: markj
Date: Fri Apr 10 20:42:11 2020
New Revision: 359779
URL: https://svnweb.freebsd.org/changeset/base/359779

Log:
  sbappendcontrol() needs to avoid clearing M_NOTREADY on data mbufs.
  
  If LOCAL_CREDS is set on a unix socket and sendfile() is called,
  sendfile will call uipc_send(PRUS_NOTREADY), prepending a control
  message to the M_NOTREADY mbufs.  uipc_send() then calls
  sbappendcontrol() instead of sbappend(), and sbappendcontrol() would
  erroneously clear M_NOTREADY.
  
  Pass send flags to sbappendcontrol(), like we do for sbappend(), to
  preserve M_READY when necessary.
  
  Reported by:  syzkaller
  MFC after:    2 weeks
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D24333

Modified:
  head/sys/kern/uipc_sockbuf.c
  head/sys/kern/uipc_usrreq.c
  head/sys/sys/sockbuf.h

Modified: head/sys/kern/uipc_sockbuf.c
==============================================================================
--- head/sys/kern/uipc_sockbuf.c        Fri Apr 10 20:41:59 2020        
(r359778)
+++ head/sys/kern/uipc_sockbuf.c        Fri Apr 10 20:42:11 2020        
(r359779)
@@ -1101,11 +1101,11 @@ sbappendaddr(struct sockbuf *sb, const struct sockaddr
 
 void
 sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
-    struct mbuf *control)
+    struct mbuf *control, int flags)
 {
        struct mbuf *m, *mlast;
 
-       m_clrprotoflags(m0);
+       sbm_clrprotoflags(m0, flags);
        m_last(control)->m_next = m0;
 
        SBLASTRECORDCHK(sb);
@@ -1123,11 +1123,12 @@ sbappendcontrol_locked(struct sockbuf *sb, struct mbuf
 }
 
 void
-sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
+sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control,
+    int flags)
 {
 
        SOCKBUF_LOCK(sb);
-       sbappendcontrol_locked(sb, m0, control);
+       sbappendcontrol_locked(sb, m0, control, flags);
        SOCKBUF_UNLOCK(sb);
 }
 

Modified: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c Fri Apr 10 20:41:59 2020        (r359778)
+++ head/sys/kern/uipc_usrreq.c Fri Apr 10 20:42:11 2020        (r359779)
@@ -1192,7 +1192,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m
                case SOCK_STREAM:
                        if (control != NULL) {
                                sbappendcontrol_locked(&so2->so_rcv, m,
-                                   control);
+                                   control, flags);
                                control = NULL;
                        } else
                                sbappend_locked(&so2->so_rcv, m, flags);

Modified: head/sys/sys/sockbuf.h
==============================================================================
--- head/sys/sys/sockbuf.h      Fri Apr 10 20:41:59 2020        (r359778)
+++ head/sys/sys/sockbuf.h      Fri Apr 10 20:42:11 2020        (r359779)
@@ -145,9 +145,9 @@ int sbappendaddr_locked(struct sockbuf *sb, const stru
 int    sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
            const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
 void   sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
-           struct mbuf *control);
+           struct mbuf *control, int flags);
 void   sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
-           struct mbuf *control);
+           struct mbuf *control, int flags);
 void   sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
 void   sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
 void   sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to