Page MenuHomeFreeBSD

D42635.id130279.diff
No OneTemporary

D42635.id130279.diff

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

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)

Event Timeline