Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115486123
D42635.id130279.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
32 KB
Referenced Files
None
Subscribers
None
D42635.id130279.diff
View Options
diff --git a/sys/cam/ctl/ctl_ha.c b/sys/cam/ctl/ctl_ha.c
--- a/sys/cam/ctl/ctl_ha.c
+++ b/sys/cam/ctl/ctl_ha.c
@@ -397,7 +397,7 @@
ctl_ha_accept(struct ha_softc *softc)
{
struct socket *lso, *so;
- struct sockaddr *sap;
+ struct sockaddr_in sin = { .sin_len = sizeof(sin) };
int error;
lso = softc->ha_lso;
@@ -410,16 +410,11 @@
goto out;
}
- sap = NULL;
- error = soaccept(so, &sap);
+ error = soaccept(so, (struct sockaddr *)&sin);
if (error != 0) {
printf("%s: soaccept() error %d\n", __func__, error);
- if (sap != NULL)
- free(sap, M_SONAME);
goto out;
}
- if (sap != NULL)
- free(sap, M_SONAME);
softc->ha_so = so;
ctl_ha_sock_setup(softc);
return (0);
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1017,31 +1017,29 @@
linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
l_uintptr_t namelen, int flags)
{
- struct sockaddr *sa;
+ struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
struct file *fp, *fp1;
- int bflags, len;
struct socket *so;
- int error, error1;
+ socklen_t len;
+ int bflags, error, error1;
bflags = 0;
fp = NULL;
- sa = NULL;
error = linux_set_socket_flags(flags, &bflags);
if (error != 0)
return (error);
- if (PTRIN(addr) == NULL) {
- len = 0;
- error = kern_accept4(td, s, NULL, NULL, bflags, NULL);
- } else {
+ if (PTRIN(addr) != NULL) {
error = copyin(PTRIN(namelen), &len, sizeof(len));
if (error != 0)
return (error);
if (len < 0)
return (EINVAL);
- error = kern_accept4(td, s, &sa, &len, bflags, &fp);
- }
+ } else
+ len = 0;
+
+ error = kern_accept4(td, s, (struct sockaddr *)&ss, bflags, &fp);
/*
* Translate errno values into ones used by Linux.
@@ -1071,11 +1069,14 @@
return (error);
}
- if (len != 0) {
- error = linux_copyout_sockaddr(sa, PTRIN(addr), len);
- if (error == 0)
- error = copyout(&len, PTRIN(namelen),
- sizeof(len));
+ if (PTRIN(addr) != NULL) {
+ len = min(ss.ss_len, len);
+ error = linux_copyout_sockaddr((struct sockaddr *)&ss,
+ PTRIN(addr), len);
+ if (error == 0) {
+ len = ss.ss_len;
+ error = copyout(&len, PTRIN(namelen), sizeof(len));
+ }
if (error != 0) {
fdclose(td, fp, td->td_retval[0]);
td->td_retval[0] = 0;
@@ -1083,7 +1084,6 @@
}
if (fp != NULL)
fdrop(fp, td);
- free(sa, M_SONAME);
return (error);
}
diff --git a/sys/dev/cxgbe/iw_cxgbe/cm.c b/sys/dev/cxgbe/iw_cxgbe/cm.c
--- a/sys/dev/cxgbe/iw_cxgbe/cm.c
+++ b/sys/dev/cxgbe/iw_cxgbe/cm.c
@@ -974,7 +974,7 @@
{
struct c4iw_listen_ep *real_lep = NULL;
struct c4iw_ep *new_ep = NULL;
- struct sockaddr_in *remote = NULL;
+ struct sockaddr_storage remote = { .ss_len = sizeof(remote) };
int ret = 0;
MPASS(new_so != NULL);
@@ -1019,19 +1019,16 @@
new_ep->com.state = MPA_REQ_WAIT;
setiwsockopt(new_so);
- ret = soaccept(new_so, (struct sockaddr **)&remote);
+ ret = soaccept(new_so, (struct sockaddr *)&remote);
if (ret != 0) {
CTR4(KTR_IW_CXGBE,
"%s:listen sock:%p, new sock:%p, ret:%d",
__func__, master_lep->com.so, new_so, ret);
- if (remote != NULL)
- free(remote, M_SONAME);
soclose(new_so);
c4iw_put_ep(&new_ep->com);
c4iw_put_ep(&real_lep->com);
return;
}
- free(remote, M_SONAME);
START_EP_TIMER(new_ep);
diff --git a/sys/dev/hyperv/hvsock/hv_sock.h b/sys/dev/hyperv/hvsock/hv_sock.h
--- a/sys/dev/hyperv/hvsock/hv_sock.h
+++ b/sys/dev/hyperv/hvsock/hv_sock.h
@@ -100,7 +100,7 @@
int hvs_trans_attach(struct socket *, int, struct thread *);
int hvs_trans_bind(struct socket *, struct sockaddr *, struct thread *);
int hvs_trans_listen(struct socket *, int, struct thread *);
-int hvs_trans_accept(struct socket *, struct sockaddr **);
+int hvs_trans_accept(struct socket *, struct sockaddr *);
int hvs_trans_connect(struct socket *,
struct sockaddr *, struct thread *);
int hvs_trans_peeraddr(struct socket *, struct sockaddr **);
diff --git a/sys/dev/hyperv/hvsock/hv_sock.c b/sys/dev/hyperv/hvsock/hv_sock.c
--- a/sys/dev/hyperv/hvsock/hv_sock.c
+++ b/sys/dev/hyperv/hvsock/hv_sock.c
@@ -479,7 +479,7 @@
}
int
-hvs_trans_accept(struct socket *so, struct sockaddr **nam)
+hvs_trans_accept(struct socket *so, struct sockaddr *sa)
{
struct hvs_pcb *pcb = so2hvspcb(so);
@@ -489,10 +489,9 @@
if (pcb == NULL)
return (EINVAL);
- *nam = sodupsockaddr((struct sockaddr *) &pcb->remote_addr,
- M_NOWAIT);
+ memcpy(sa, &pcb->remote_addr, pcb->remote_addr.sa_len);
- return ((*nam == NULL) ? ENOMEM : 0);
+ return (0);
}
int
diff --git a/sys/dev/iscsi/icl_soft_proxy.c b/sys/dev/iscsi/icl_soft_proxy.c
--- a/sys/dev/iscsi/icl_soft_proxy.c
+++ b/sys/dev/iscsi/icl_soft_proxy.c
@@ -208,7 +208,7 @@
{
struct icl_listen_sock *ils;
struct socket *head, *so;
- struct sockaddr *sa;
+ struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
int error;
ils = arg;
@@ -234,17 +234,15 @@
continue;
}
- sa = NULL;
- error = soaccept(so, &sa);
+ error = soaccept(so, (struct sockaddr *)&ss);
if (error != 0) {
ICL_WARN("soaccept error %d", error);
- if (sa != NULL)
- free(sa, M_SONAME);
soclose(so);
continue;
}
- (ils->ils_listen->il_accept)(so, sa, ils->ils_id);
+ (ils->ils_listen->il_accept)(so, (struct sockaddr *)&ss,
+ ils->ils_id);
}
}
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -56,7 +56,7 @@
MTX_SYSINIT(domain, &dom_mtx, "domain list", MTX_DEF);
static int
-pr_accept_notsupp(struct socket *so, struct sockaddr **nam)
+pr_accept_notsupp(struct socket *so, struct sockaddr *sa)
{
return (EOPNOTSUPP);
}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1350,12 +1350,17 @@
}
int
-soaccept(struct socket *so, struct sockaddr **nam)
+soaccept(struct socket *so, struct sockaddr *sa)
{
+#ifdef INVARIANTS
+ u_char len = sa->sa_len;
+#endif
int error;
CURVNET_SET(so->so_vnet);
- error = so->so_proto->pr_accept(so, nam);
+ error = so->so_proto->pr_accept(so, sa);
+ KASSERT(sa->sa_len <= len,
+ ("%s: protocol %p sockaddr overflow", __func__, so->so_proto));
CURVNET_RESTORE();
return (error);
}
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -279,19 +279,18 @@
accept1(struct thread *td, int s, struct sockaddr *uname, socklen_t *anamelen,
int flags)
{
- struct sockaddr *name;
- socklen_t namelen;
+ struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
+ socklen_t addrlen;
struct file *fp;
int error;
- if (uname == NULL)
- return (kern_accept4(td, s, NULL, NULL, flags, NULL));
-
- error = copyin(anamelen, &namelen, sizeof (namelen));
- if (error != 0)
- return (error);
+ if (uname != NULL) {
+ error = copyin(anamelen, &addrlen, sizeof(addrlen));
+ if (error != 0)
+ return (error);
+ }
- error = kern_accept4(td, s, &name, &namelen, flags, &fp);
+ error = kern_accept4(td, s, (struct sockaddr *)&ss, flags, &fp);
if (error != 0)
return (error);
@@ -299,42 +298,40 @@
#ifdef COMPAT_OLDSOCK
if (SV_PROC_FLAG(td->td_proc, SV_AOUT) &&
(flags & ACCEPT4_COMPAT) != 0)
- ((struct osockaddr *)name)->sa_family =
- name->sa_family;
+ ((struct osockaddr *)&ss)->sa_family = ss.ss_family;
#endif
- error = copyout(name, uname, namelen);
- if (error == 0)
- error = copyout(&namelen, anamelen,
- sizeof(namelen));
+ if (uname != NULL) {
+ addrlen = min(ss.ss_len, addrlen);
+ error = copyout(&ss, uname, addrlen);
+ if (error == 0) {
+ addrlen = ss.ss_len;
+ error = copyout(&addrlen, anamelen, sizeof(addrlen));
+ }
+ }
if (error != 0)
fdclose(td, fp, td->td_retval[0]);
fdrop(fp, td);
- free(name, M_SONAME);
+
return (error);
}
int
-kern_accept(struct thread *td, int s, struct sockaddr **name,
- socklen_t *namelen, struct file **fp)
+kern_accept(struct thread *td, int s, struct sockaddr *sa, struct file **fp)
{
- return (kern_accept4(td, s, name, namelen, ACCEPT4_INHERIT, fp));
+ return (kern_accept4(td, s, sa, ACCEPT4_INHERIT, fp));
}
int
-kern_accept4(struct thread *td, int s, struct sockaddr **name,
- socklen_t *namelen, int flags, struct file **fp)
+kern_accept4(struct thread *td, int s, struct sockaddr *sa, int flags,
+ struct file **fp)
{
struct file *headfp, *nfp = NULL;
- struct sockaddr *sa = NULL;
struct socket *head, *so;
struct filecaps fcaps;
u_int fflag;
pid_t pgid;
int error, fd, tmp;
- if (name != NULL)
- *name = NULL;
-
AUDIT_ARG_FD(s);
error = getsock_cap(td, s, &cap_accept_rights,
&headfp, &fcaps);
@@ -388,29 +385,15 @@
(void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
tmp = fflag & FASYNC;
(void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
- error = soaccept(so, &sa);
- if (error != 0)
- goto noconnection;
- if (sa == NULL) {
- if (name)
- *namelen = 0;
- goto done;
- }
- AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
- if (name) {
- /* check sa_len before it is destroyed */
- if (*namelen > sa->sa_len)
- *namelen = sa->sa_len;
+
+ if ((error = soaccept(so, sa)) == 0) {
+ AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
#ifdef KTRACE
if (KTRPOINT(td, KTR_STRUCT))
ktrsockaddr(sa);
#endif
- *name = sa;
- sa = NULL;
}
noconnection:
- free(sa, M_SONAME);
-
/*
* close the new descriptor, assuming someone hasn't ripped it
* out from under us.
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
@@ -122,7 +122,10 @@
static SLIST_HEAD(, unp_defer) unp_defers;
static int unp_defers_count;
-static const struct sockaddr sun_noname = { sizeof(sun_noname), AF_LOCAL };
+static const struct sockaddr sun_noname = {
+ .sa_len = sizeof(sun_noname),
+ .sa_family = AF_LOCAL,
+};
/*
* Garbage collection of cyclic file descriptor/socket references occurs
@@ -436,7 +439,7 @@
}
static int
-uipc_accept(struct socket *so, struct sockaddr **nam)
+uipc_accept(struct socket *so, struct sockaddr *ret)
{
struct unpcb *unp, *unp2;
const struct sockaddr *sa;
@@ -448,14 +451,13 @@
unp = sotounpcb(so);
KASSERT(unp != NULL, ("uipc_accept: unp == NULL"));
- *nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
UNP_PCB_LOCK(unp);
unp2 = unp_pcb_lock_peer(unp);
if (unp2 != NULL && unp2->unp_addr != NULL)
sa = (struct sockaddr *)unp2->unp_addr;
else
sa = &sun_noname;
- bcopy(sa, *nam, sa->sa_len);
+ bcopy(sa, ret, sa->sa_len);
if (unp2 != NULL)
unp_pcb_unlock_pair(unp, unp2);
else
diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h
--- a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h
+++ b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h
@@ -191,7 +191,7 @@
void ng_btsocket_l2cap_abort (struct socket *);
void ng_btsocket_l2cap_close (struct socket *);
-int ng_btsocket_l2cap_accept (struct socket *, struct sockaddr **);
+int ng_btsocket_l2cap_accept (struct socket *, struct sockaddr *);
int ng_btsocket_l2cap_attach (struct socket *, int, struct thread *);
int ng_btsocket_l2cap_bind (struct socket *, struct sockaddr *,
struct thread *);
diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h
--- a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h
+++ b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h
@@ -316,7 +316,7 @@
void ng_btsocket_rfcomm_abort (struct socket *);
void ng_btsocket_rfcomm_close (struct socket *);
-int ng_btsocket_rfcomm_accept (struct socket *, struct sockaddr **);
+int ng_btsocket_rfcomm_accept (struct socket *, struct sockaddr *);
int ng_btsocket_rfcomm_attach (struct socket *, int, struct thread *);
int ng_btsocket_rfcomm_bind (struct socket *, struct sockaddr *,
struct thread *);
diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h
--- a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h
+++ b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h
@@ -106,7 +106,7 @@
void ng_btsocket_sco_abort (struct socket *);
void ng_btsocket_sco_close (struct socket *);
-int ng_btsocket_sco_accept (struct socket *, struct sockaddr **);
+int ng_btsocket_sco_accept (struct socket *, struct sockaddr *);
int ng_btsocket_sco_attach (struct socket *, int, struct thread *);
int ng_btsocket_sco_bind (struct socket *, struct sockaddr *,
struct thread *);
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c
@@ -1967,20 +1967,6 @@
(void)ng_btsocket_l2cap_disconnect(so);
} /* ng_btsocket_l2cap_close */
-/*
- * Accept connection on socket. Nothing to do here, socket must be connected
- * and ready, so just return peer address and be done with it.
- */
-
-int
-ng_btsocket_l2cap_accept(struct socket *so, struct sockaddr **nam)
-{
- if (ng_btsocket_l2cap_node == NULL)
- return (EINVAL);
-
- return (ng_btsocket_l2cap_peeraddr(so, nam));
-} /* ng_btsocket_l2cap_accept */
-
/*
* Create and attach new socket
*/
@@ -2523,41 +2509,67 @@
return (error);
} /* ng_btsocket_listen */
-/*
- * Get peer address
- */
-
-int
-ng_btsocket_l2cap_peeraddr(struct socket *so, struct sockaddr **nam)
+static int
+ng_btsocket_l2cap_peeraddr1(struct socket *so, struct sockaddr_l2cap *sa)
{
ng_btsocket_l2cap_pcb_p pcb = so2l2cap_pcb(so);
- struct sockaddr_l2cap sa;
if (pcb == NULL)
return (EINVAL);
if (ng_btsocket_l2cap_node == NULL)
return (EINVAL);
- bcopy(&pcb->dst, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
- sa.l2cap_psm = htole16(pcb->psm);
- sa.l2cap_len = sizeof(sa);
- sa.l2cap_family = AF_BLUETOOTH;
+ *sa = (struct sockaddr_l2cap ){
+ .l2cap_len = sizeof(struct sockaddr_l2cap),
+ .l2cap_family = AF_BLUETOOTH,
+ .l2cap_psm = htole16(pcb->psm),
+ };
+ bcopy(&pcb->dst, &sa->l2cap_bdaddr, sizeof(sa->l2cap_bdaddr));
switch(pcb->idtype){
case NG_L2CAP_L2CA_IDTYPE_ATT:
- sa.l2cap_cid = NG_L2CAP_ATT_CID;
+ sa->l2cap_cid = NG_L2CAP_ATT_CID;
break;
case NG_L2CAP_L2CA_IDTYPE_SMP:
- sa.l2cap_cid = NG_L2CAP_SMP_CID;
+ sa->l2cap_cid = NG_L2CAP_SMP_CID;
break;
default:
- sa.l2cap_cid = 0;
+ sa->l2cap_cid = 0;
break;
}
- sa.l2cap_bdaddr_type = pcb->dsttype;
+ sa->l2cap_bdaddr_type = pcb->dsttype;
+
+ return (0);
+}
+
+/*
+ * Get peer address
+ */
+int
+ng_btsocket_l2cap_peeraddr(struct socket *so, struct sockaddr **nam)
+{
+ struct sockaddr_l2cap sa;
+ int error;
+
+ error = ng_btsocket_l2cap_peeraddr1(so, &sa);
+ if (error != 0)
+ return (error);
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
return ((*nam == NULL)? ENOMEM : 0);
-} /* ng_btsocket_l2cap_peeraddr */
+}
+
+/*
+ * Accept connection on socket. Nothing to do here, socket must be connected
+ * and ready, so just return peer address and be done with it.
+ */
+int
+ng_btsocket_l2cap_accept(struct socket *so, struct sockaddr *sa)
+{
+ if (ng_btsocket_l2cap_node == NULL)
+ return (EINVAL);
+
+ return (ng_btsocket_l2cap_peeraddr1(so, (struct sockaddr_l2cap *)sa));
+}
/*
* Send data to socket
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
@@ -370,17 +370,6 @@
(void)ng_btsocket_rfcomm_disconnect(so);
} /* ng_btsocket_rfcomm_close */
-/*
- * Accept connection on socket. Nothing to do here, socket must be connected
- * and ready, so just return peer address and be done with it.
- */
-
-int
-ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam)
-{
- return (ng_btsocket_rfcomm_peeraddr(so, nam));
-} /* ng_btsocket_rfcomm_accept */
-
/*
* Create and attach new socket
*/
@@ -925,28 +914,51 @@
return (error);
} /* ng_btsocket_listen */
-/*
- * Get peer address
- */
-
-int
-ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam)
+static int
+ng_btsocket_rfcomm_peeraddr1(struct socket *so, struct sockaddr_rfcomm *sa)
{
ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so);
- struct sockaddr_rfcomm sa;
if (pcb == NULL)
return (EINVAL);
- bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
- sa.rfcomm_channel = pcb->channel;
- sa.rfcomm_len = sizeof(sa);
- sa.rfcomm_family = AF_BLUETOOTH;
+ *sa = (struct sockaddr_rfcomm ){
+ .rfcomm_len = sizeof(struct sockaddr_rfcomm),
+ .rfcomm_family = AF_BLUETOOTH,
+ .rfcomm_channel = pcb->channel,
+ };
+ bcopy(&pcb->dst, &sa->rfcomm_bdaddr, sizeof(sa->rfcomm_bdaddr));
+ return (0);
+}
+
+/*
+ * Get peer address
+ */
+int
+ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam)
+{
+ struct sockaddr_rfcomm sa;
+ int error;
+
+ error = ng_btsocket_rfcomm_peeraddr1(so, &sa);
+ if (error != 0)
+ return (error);
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
return ((*nam == NULL)? ENOMEM : 0);
-} /* ng_btsocket_rfcomm_peeraddr */
+}
+
+/*
+ * Accept connection on socket. Nothing to do here, socket must be connected
+ * and ready, so just return peer address and be done with it.
+ */
+int
+ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr *sa)
+{
+
+ return (ng_btsocket_rfcomm_peeraddr1(so, (struct sockaddr_rfcomm *)sa));
+}
/*
* Send data to socket
@@ -1407,7 +1419,7 @@
ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0)
{
struct socket *l2so;
- struct sockaddr_l2cap *l2sa = NULL;
+ struct sockaddr_l2cap l2sa = { .l2cap_len = sizeof(l2sa) };
ng_btsocket_l2cap_pcb_t *l2pcb = NULL;
ng_btsocket_rfcomm_session_p s = NULL;
int error;
@@ -1425,7 +1437,7 @@
return (error);
}
- error = soaccept(l2so, (struct sockaddr **) &l2sa);
+ error = soaccept(l2so, (struct sockaddr *)&l2sa);
if (error != 0) {
NG_BTSOCKET_RFCOMM_ERR(
"%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error);
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c
@@ -1176,20 +1176,6 @@
(void) ng_btsocket_sco_disconnect(so);
} /* ng_btsocket_sco_close */
-/*
- * Accept connection on socket. Nothing to do here, socket must be connected
- * and ready, so just return peer address and be done with it.
- */
-
-int
-ng_btsocket_sco_accept(struct socket *so, struct sockaddr **nam)
-{
- if (ng_btsocket_sco_node == NULL)
- return (EINVAL);
-
- return (ng_btsocket_sco_peeraddr(so, nam));
-} /* ng_btsocket_sco_accept */
-
/*
* Create and attach new socket
*/
@@ -1623,32 +1609,56 @@
return (error);
} /* ng_btsocket_listen */
-/*
- * Get peer address
- */
-
-int
-ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr **nam)
+static int
+ng_btsocket_sco_peeraddr1(struct socket *so, struct sockaddr_sco *sa)
{
ng_btsocket_sco_pcb_p pcb = so2sco_pcb(so);
- struct sockaddr_sco sa;
if (pcb == NULL)
return (EINVAL);
if (ng_btsocket_sco_node == NULL)
return (EINVAL);
+ *sa = (struct sockaddr_sco ){
+ .sco_len = sizeof(struct sockaddr_sco),
+ .sco_family = AF_BLUETOOTH,
+ };
mtx_lock(&pcb->pcb_mtx);
- bcopy(&pcb->dst, &sa.sco_bdaddr, sizeof(sa.sco_bdaddr));
+ bcopy(&pcb->dst, &sa->sco_bdaddr, sizeof(sa->sco_bdaddr));
mtx_unlock(&pcb->pcb_mtx);
- sa.sco_len = sizeof(sa);
- sa.sco_family = AF_BLUETOOTH;
+ return (0);
+}
+
+/*
+ * Get peer address
+ */
+int
+ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr **nam)
+{
+ struct sockaddr_sco sa;
+ int error;
+ error = ng_btsocket_sco_peeraddr1(so, &sa);
+ if (error != 0)
+ return (error);
*nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
return ((*nam == NULL)? ENOMEM : 0);
-} /* ng_btsocket_sco_peeraddr */
+}
+
+/*
+ * Accept connection on socket. Nothing to do here, socket must be connected
+ * and ready, so just return peer address and be done with it.
+ */
+int
+ng_btsocket_sco_accept(struct socket *so, struct sockaddr *sa)
+{
+ if (ng_btsocket_sco_node == NULL)
+ return (EINVAL);
+
+ return (ng_btsocket_sco_peeraddr1(so, (struct sockaddr_sco *)sa));
+}
/*
* Send data to socket
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -1178,7 +1178,7 @@
{
struct socket *const head = priv->so;
struct socket *so;
- struct sockaddr *sa = NULL;
+ struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
struct ng_mesg *resp;
struct ng_ksocket_accept *resp_data;
node_p node;
@@ -1196,12 +1196,11 @@
if (error)
return (error);
- if ((error = soaccept(so, &sa)) != 0)
+ if ((error = soaccept(so, (struct sockaddr *)&ss)) != 0)
return (error);
len = OFFSETOF(struct ng_ksocket_accept, addr);
- if (sa != NULL)
- len += sa->sa_len;
+ len += ss.ss_len;
NG_MKMESSAGE(resp, NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT, len,
M_NOWAIT);
@@ -1249,13 +1248,10 @@
/* Fill in the response data and send it or return it to the caller */
resp_data = (struct ng_ksocket_accept *)resp->data;
resp_data->nodeid = NG_NODE_ID(node);
- if (sa != NULL)
- bcopy(sa, &resp_data->addr, sa->sa_len);
+ bcopy(&ss, &resp_data->addr, ss.ss_len);
NG_SEND_MSG_ID(error, node, resp, priv->response_addr, 0);
out:
- if (sa != NULL)
- free(sa, M_SONAME);
return (0);
}
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -7271,7 +7271,7 @@
static int sctp_defered_wakeup_cnt = 0;
int
-sctp_accept(struct socket *so, struct sockaddr **addr)
+sctp_accept(struct socket *so, struct sockaddr *sa)
{
struct sctp_tcb *stcb;
struct sctp_inpcb *inp;
@@ -7338,39 +7338,25 @@
switch (store.sa.sa_family) {
#ifdef INET
case AF_INET:
- {
- struct sockaddr_in *sin;
-
- SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
- if (sin == NULL)
- return (ENOMEM);
- sin->sin_family = AF_INET;
- sin->sin_len = sizeof(*sin);
- sin->sin_port = store.sin.sin_port;
- sin->sin_addr = store.sin.sin_addr;
- *addr = (struct sockaddr *)sin;
- break;
- }
+ *(struct sockaddr_in *)sa = (struct sockaddr_in ){
+ .sin_family = AF_INET,
+ .sin_len = sizeof(struct sockaddr_in),
+ .sin_port = store.sin.sin_port,
+ .sin_addr = store.sin.sin_addr,
+ };
+ break;
#endif
#ifdef INET6
case AF_INET6:
- {
- struct sockaddr_in6 *sin6;
-
- SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
- if (sin6 == NULL)
- return (ENOMEM);
- sin6->sin6_family = AF_INET6;
- sin6->sin6_len = sizeof(*sin6);
- sin6->sin6_port = store.sin6.sin6_port;
- sin6->sin6_addr = store.sin6.sin6_addr;
- if ((error = sa6_recoverscope(sin6)) != 0) {
- SCTP_FREE_SONAME(sin6);
- return (error);
- }
- *addr = (struct sockaddr *)sin6;
- break;
- }
+ *(struct sockaddr_in6 *)sa = (struct sockaddr_in6 ){
+ .sin6_family = AF_INET6,
+ .sin6_len = sizeof(struct sockaddr_in6),
+ .sin6_port = store.sin6.sin6_port,
+ .sin6_addr = store.sin6.sin6_addr,
+ };
+ if ((error = sa6_recoverscope((struct sockaddr_in6 *)sa)) != 0)
+ return (error);
+ break;
#endif
default:
/* TSNH */
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -341,7 +341,7 @@
int sctp_ingetaddr(struct socket *, struct sockaddr **);
int sctp_peeraddr(struct socket *, struct sockaddr **);
int sctp_listen(struct socket *, int, struct thread *);
-int sctp_accept(struct socket *, struct sockaddr **);
+int sctp_accept(struct socket *, struct sockaddr *);
#endif /* _KERNEL */
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -719,13 +719,11 @@
* just return the address of the peer, storing through addr.
*/
static int
-tcp_usr_accept(struct socket *so, struct sockaddr **nam)
+tcp_usr_accept(struct socket *so, struct sockaddr *sa)
{
- int error = 0;
struct inpcb *inp;
struct tcpcb *tp;
- struct in_addr addr;
- in_port_t port = 0;
+ int error = 0;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp_usr_accept: inp == NULL"));
@@ -736,39 +734,30 @@
}
tp = intotcpcb(inp);
- if (so->so_state & SS_ISDISCONNECTED) {
+ if (so->so_state & SS_ISDISCONNECTED)
error = ECONNABORTED;
- goto out;
- }
- /*
- * We inline in_getpeeraddr and COMMON_END here, so that we can
- * copy the data of interest and defer the malloc until after we
- * release the lock.
- */
- port = inp->inp_fport;
- addr = inp->inp_faddr;
-
-out:
+ else
+ *(struct sockaddr_in *)sa = (struct sockaddr_in ){
+ .sin_family = AF_INET,
+ .sin_len = sizeof(struct sockaddr_in),
+ .sin_port = inp->inp_fport,
+ .sin_addr = inp->inp_faddr,
+ };
tcp_bblog_pru(tp, PRU_ACCEPT, error);
TCP_PROBE2(debug__user, tp, PRU_ACCEPT);
INP_WUNLOCK(inp);
- if (error == 0)
- *nam = in_sockaddr(port, &addr);
- return error;
+
+ return (error);
}
#endif /* INET */
#ifdef INET6
static int
-tcp6_usr_accept(struct socket *so, struct sockaddr **nam)
+tcp6_usr_accept(struct socket *so, struct sockaddr *sa)
{
struct inpcb *inp;
- int error = 0;
struct tcpcb *tp;
- struct in_addr addr;
- struct in6_addr addr6;
- in_port_t port = 0;
- int v4 = 0;
+ int error = 0;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("tcp6_usr_accept: inp == NULL"));
@@ -781,33 +770,32 @@
if (so->so_state & SS_ISDISCONNECTED) {
error = ECONNABORTED;
- goto out;
- }
- /*
- * We inline in6_mapped_peeraddr and COMMON_END here, so that we can
- * copy the data of interest and defer the malloc until after we
- * release the lock.
- */
- if (inp->inp_vflag & INP_IPV4) {
- v4 = 1;
- port = inp->inp_fport;
- addr = inp->inp_faddr;
} else {
- port = inp->inp_fport;
- addr6 = inp->in6p_faddr;
+ if (inp->inp_vflag & INP_IPV4) {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_len = sizeof(struct sockaddr_in),
+ .sin_port = inp->inp_fport,
+ .sin_addr = inp->inp_faddr,
+ };
+ in6_sin_2_v4mapsin6(&sin, (struct sockaddr_in6 *)sa);
+ } else {
+ *(struct sockaddr_in6 *)sa = (struct sockaddr_in6 ){
+ .sin6_family = AF_INET6,
+ .sin6_len = sizeof(struct sockaddr_in6),
+ .sin6_port = inp->inp_fport,
+ .sin6_addr = inp->in6p_faddr,
+ };
+ /* XXX: should catch errors */
+ (void)sa6_recoverscope((struct sockaddr_in6 *)sa);
+ }
}
-out:
tcp_bblog_pru(tp, PRU_ACCEPT, error);
TCP_PROBE2(debug__user, tp, PRU_ACCEPT);
INP_WUNLOCK(inp);
- if (error == 0) {
- if (v4)
- *nam = in6_v4mapsin6_sockaddr(port, &addr);
- else
- *nam = in6_sockaddr(port, &addr6);
- }
- return error;
+
+ return (error);
}
#endif /* INET6 */
diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h
--- a/sys/netinet6/in6_pcb.h
+++ b/sys/netinet6/in6_pcb.h
@@ -100,8 +100,6 @@
in6_rtchange(struct inpcb *, int);
struct sockaddr *
in6_sockaddr(in_port_t port, struct in6_addr *addr_p);
-struct sockaddr *
- in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p);
int in6_getpeeraddr(struct socket *so, struct sockaddr **nam);
int in6_getsockaddr(struct socket *so, struct sockaddr **nam);
int in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam);
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -519,25 +519,6 @@
return (struct sockaddr *)sin6;
}
-struct sockaddr *
-in6_v4mapsin6_sockaddr(in_port_t port, struct in_addr *addr_p)
-{
- struct sockaddr_in sin;
- struct sockaddr_in6 *sin6_p;
-
- bzero(&sin, sizeof sin);
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- sin.sin_port = port;
- sin.sin_addr = *addr_p;
-
- sin6_p = malloc(sizeof *sin6_p, M_SONAME,
- M_WAITOK);
- in6_sin_2_v4mapsin6(&sin, sin6_p);
-
- return (struct sockaddr *)sin6_p;
-}
-
int
in6_getsockaddr(struct socket *so, struct sockaddr **nam)
{
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
@@ -776,32 +776,29 @@
* are fully initialized.
*/
static int
-sdp_accept(struct socket *so, struct sockaddr **nam)
+sdp_accept(struct socket *so, struct sockaddr *sa)
{
struct sdp_sock *ssk = NULL;
- struct in_addr addr;
- in_port_t port;
int error;
if (so->so_state & SS_ISDISCONNECTED)
return (ECONNABORTED);
- port = 0;
- addr.s_addr = 0;
error = 0;
ssk = sdp_sk(so);
SDP_WLOCK(ssk);
- if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED)) {
+ if (ssk->flags & (SDP_TIMEWAIT | SDP_DROPPED))
error = ECONNABORTED;
- goto out;
- }
- port = ssk->fport;
- addr.s_addr = ssk->faddr;
-out:
+ else
+ *(struct sockaddr_in *)sa = (struct sockaddr_in ){
+ .sin_family = AF_INET,
+ .sin_len = sizeof(struct sockaddr_in),
+ .sin_addr.s_addr = ssk->faddr,
+ .sin_port = ssk->fport,
+ };
SDP_WUNLOCK(ssk);
- if (error == 0)
- *nam = sdp_sockaddr(port, &addr);
- return error;
+
+ return (error);
}
/*
diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c
--- a/sys/rpc/svc_vc.c
+++ b/sys/rpc/svc_vc.c
@@ -424,7 +424,7 @@
struct sockaddr **addrp, struct mbuf **mp)
{
struct socket *so = NULL;
- struct sockaddr *sa = NULL;
+ struct sockaddr_storage ss = { .ss_len = sizeof(ss) };
int error;
SVCXPRT *new_xprt;
@@ -468,15 +468,12 @@
sx_xunlock(&xprt->xp_lock);
- sa = NULL;
- error = soaccept(so, &sa);
+ error = soaccept(so, (struct sockaddr *)&ss);
if (error) {
/*
* XXX not sure if I need to call sofree or soclose here.
*/
- if (sa)
- free(sa, M_SONAME);
return (FALSE);
}
@@ -484,15 +481,14 @@
* svc_vc_create_conn will call xprt_register - we don't need
* to do anything with the new connection except derefence it.
*/
- new_xprt = svc_vc_create_conn(xprt->xp_pool, so, sa);
+ new_xprt = svc_vc_create_conn(xprt->xp_pool, so,
+ (struct sockaddr *)&ss);
if (!new_xprt) {
soclose(so);
} else {
SVC_RELEASE(new_xprt);
}
- free(sa, M_SONAME);
-
return (FALSE); /* there is never an rpc msg to be processed */
}
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -63,7 +63,7 @@
typedef int pr_ctloutput_t(struct socket *, struct sockopt *);
typedef int pr_setsbopt_t(struct socket *, struct sockopt *);
typedef void pr_abort_t(struct socket *);
-typedef int pr_accept_t(struct socket *, struct sockaddr **);
+typedef int pr_accept_t(struct socket *, struct sockaddr *);
typedef int pr_attach_t(struct socket *, int, struct thread *);
typedef int pr_bind_t(struct socket *, struct sockaddr *, struct thread *);
typedef int pr_connect_t(struct socket *, struct sockaddr *,
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -451,7 +451,7 @@
int getsock(struct thread *td, int fd, cap_rights_t *rightsp,
struct file **fpp);
void soabort(struct socket *so);
-int soaccept(struct socket *so, struct sockaddr **nam);
+int soaccept(struct socket *so, struct sockaddr *sa);
void soaio_enqueue(struct task *task);
void soaio_rcv(void *context, int pending);
void soaio_snd(void *context, int pending);
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -84,10 +84,10 @@
size_t buflen, size_t path_max);
int kern_abort2(struct thread *td, const char *why, int nargs,
void **uargs);
-int kern_accept(struct thread *td, int s, struct sockaddr **name,
- socklen_t *namelen, struct file **fp);
-int kern_accept4(struct thread *td, int s, struct sockaddr **name,
- socklen_t *namelen, int flags, struct file **fp);
+int kern_accept(struct thread *td, int s, struct sockaddr *sa,
+ struct file **fp);
+int kern_accept4(struct thread *td, int s, struct sockaddr *sa,
+ int flags, struct file **fp);
int kern_accessat(struct thread *td, int fd, const char *path,
enum uio_seg pathseg, int flags, int mode);
int kern_adjtime(struct thread *td, struct timeval *delta,
diff --git a/tests/sys/kern/socket_accept.c b/tests/sys/kern/socket_accept.c
--- a/tests/sys/kern/socket_accept.c
+++ b/tests/sys/kern/socket_accept.c
@@ -81,10 +81,7 @@
salen = 0;
ATF_REQUIRE(accept(l, (struct sockaddr *)&ret, &salen) > 0);
ATF_REQUIRE(memcmp(&ret, &canary, sizeof(ret)) == 0);
-#if 0
- /* Linux behavior. Matches my reading of accept(2) and POSIX. */
ATF_REQUIRE(salen == sizeof(struct sockaddr_in));
-#endif
/* Note: Linux will block for connection here, we fail immediately. */
ATF_REQUIRE(accept(l, (struct sockaddr *)&ret, NULL) == -1);
ATF_REQUIRE(errno == EFAULT);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 25, 9:03 AM (16 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17780992
Default Alt Text
D42635.id130279.diff (32 KB)
Attached To
Mode
D42635: sockets: don't malloc/free sockaddr memory on accept(2)
Attached
Detach File
Event Timeline
Log In to Comment