Author: markj
Date: Mon Apr 13 19:22:05 2020
New Revision: 359893
URL: https://svnweb.freebsd.org/changeset/base/359893

Log:
  Fix sendto() on unconnected SOCK_STREAM/SEQPACKET unix sockets.
  
  Previously the unpcb pointer of the newly connected remote socket was
  not initialized correctly, so attempting to lock it would result in a
  null pointer dereference.
  
  Reported by:  syzkaller
  MFC after:    1 week
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/kern/uipc_usrreq.c

Modified: head/sys/kern/uipc_usrreq.c
==============================================================================
--- head/sys/kern/uipc_usrreq.c Mon Apr 13 19:20:39 2020        (r359892)
+++ head/sys/kern/uipc_usrreq.c Mon Apr 13 19:22:05 2020        (r359893)
@@ -1138,25 +1138,29 @@ uipc_send(struct socket *so, int flags, struct mbuf *m
        case SOCK_STREAM:
                if ((so->so_state & SS_ISCONNECTED) == 0) {
                        if (nam != NULL) {
-                               if ((error = connect_internal(so, nam, td)))
+                               error = connect_internal(so, nam, td);
+                               if (error != 0)
                                        break;
-                       } else  {
+                       } else {
                                error = ENOTCONN;
                                break;
                        }
-               } else if ((unp2 = unp->unp_conn) == NULL) {
+               } else {
+                       UNP_PCB_LOCK(unp);
+               }
+
+               if ((unp2 = unp->unp_conn) == NULL) {
+                       UNP_PCB_UNLOCK(unp);
                        error = ENOTCONN;
                        break;
                } else if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
+                       UNP_PCB_UNLOCK(unp);
                        error = EPIPE;
                        break;
-               } else {
-                       UNP_PCB_LOCK(unp);
-                       if ((unp2 = unp->unp_conn) == NULL) {
-                               UNP_PCB_UNLOCK(unp);
-                               error = ENOTCONN;
-                               break;
-                       }
+               } else if ((unp2 = unp->unp_conn) == NULL) {
+                       UNP_PCB_UNLOCK(unp);
+                       error = ENOTCONN;
+                       break;
                }
                unp_pcb_owned_lock2(unp, unp2, freed);
                UNP_PCB_UNLOCK(unp);
@@ -1198,15 +1202,11 @@ uipc_send(struct socket *so, int flags, struct mbuf *m
                                sbappend_locked(&so2->so_rcv, m, flags);
                        break;
 
-               case SOCK_SEQPACKET: {
-                       const struct sockaddr *from;
-
-                       from = &sun_noname;
+               case SOCK_SEQPACKET:
                        if (sbappendaddr_nospacecheck_locked(&so2->so_rcv,
-                           from, m, control))
+                           &sun_noname, m, control))
                                control = NULL;
                        break;
-                       }
                }
 
                mbcnt = so2->so_rcv.sb_mbcnt;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to