Page MenuHomeFreeBSD

D58769.id183825.diff
No OneTemporary

D58769.id183825.diff

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -293,7 +293,7 @@
static int unp_connectat(int, struct socket *, const char *, int,
struct thread *, struct socket **);
static int unp_connect_peer(struct socket *, struct unpcb *,
- struct sockaddr **, struct thread *, bool);
+ struct thread *, bool);
static int unp_resolve_peer(struct thread *, int, const char *,
struct socket **);
static int unp_vnode_peer(struct vnode *, struct thread *,
@@ -2954,9 +2954,7 @@
struct socket *so2;
struct unpcb *unp;
char buf[SOCK_MAXADDRLEN];
- struct sockaddr *sa;
int error;
- bool connreq;
CURVNET_ASSERT_SET();
@@ -3000,16 +2998,10 @@
unp->unp_flags |= UNP_CONNECTING;
UNP_PCB_UNLOCK(unp);
- connreq = (so->so_proto->pr_flags & PR_CONNREQUIRED) != 0;
- if (connreq)
- sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
- else
- sa = NULL;
-
error = unp_resolve_peer(td, fd, buf, &so2);
if (error != 0)
goto out;
- error = unp_connect_peer(so, sotounpcb(so2), &sa, td,
+ error = unp_connect_peer(so, sotounpcb(so2), td,
referenced_peerp != NULL);
/* Transfer the reference; the caller releases it after unlocking. */
if (error == 0 && referenced_peerp != NULL)
@@ -3017,7 +3009,6 @@
else
sorele(so2);
out:
- free(sa, M_SONAME);
if (__predict_false(error)) {
UNP_PCB_LOCK(unp);
KASSERT((unp->unp_flags & UNP_CONNECTING) != 0,
@@ -3203,21 +3194,21 @@
* peer socket, or the vnode lock plus unp_vp_mtxpool lock for a peer found
* via VOP_UNP_CONNECT()).
*
- * For connection-oriented sockets '*sap' points to a buffer to hold the
- * listener's address; it is consumed (set to NULL) if used. On success
- * UNP_CONNECTING is cleared; on error the caller must clear it.
+ * On success UNP_CONNECTING is cleared; on error the caller must clear it.
*/
static int
-unp_connect_peer(struct socket *so, struct unpcb *unp2, struct sockaddr **sap,
- struct thread *td, bool return_locked)
+unp_connect_peer(struct socket *so, struct unpcb *unp2, struct thread *td,
+ bool return_locked)
{
struct socket *so2;
+ struct sockaddr *sa;
struct unpcb *unp, *unp3;
int error;
bool connreq;
unp = sotounpcb(so);
KASSERT(unp != NULL, ("%s: unp == NULL", __func__));
+ sa = NULL;
connreq = (so->so_proto->pr_flags & PR_CONNREQUIRED) != 0;
so2 = unp2->unp_socket;
@@ -3235,11 +3226,17 @@
return (error);
}
unp3 = sotounpcb(so2);
+
+ /*
+ * The listener's address is copied to the new socket under the
+ * PCB locks below, so its storage has to be in hand first.
+ */
+ sa = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
unp_pcb_lock_pair(unp2, unp3);
if (unp2->unp_addr != NULL) {
- bcopy(unp2->unp_addr, *sap, unp2->unp_addr->sun_len);
- unp3->unp_addr = (struct sockaddr_un *)*sap;
- *sap = NULL;
+ bcopy(unp2->unp_addr, sa, unp2->unp_addr->sun_len);
+ unp3->unp_addr = (struct sockaddr_un *)sa;
+ sa = NULL;
}
unp_copy_peercred(td, unp3, unp, unp2);
@@ -3270,6 +3267,7 @@
unp->unp_flags &= ~UNP_CONNECTING;
if (!return_locked)
unp_pcb_unlock_pair(unp, unp2);
+ free(sa, M_SONAME);
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 21, 9:06 PM (12 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36529189
Default Alt Text
D58769.id183825.diff (3 KB)

Event Timeline