Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167317848
D58769.id183825.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D58769.id183825.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D58769: unix: let unp_connect_peer() own the listener address buffer
Attached
Detach File
Event Timeline
Log In to Comment