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
This commit is contained in:
Mark Johnston 2020-04-13 19:22:05 +00:00
parent c7841c6b8e
commit b36871af6d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=359893

View File

@ -1138,25 +1138,29 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
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, struct sockaddr *nam,
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;