Re: git: cfb1e92912b4 - main - sockets: don't malloc/free sockaddr memory on accept(2)
Date: Thu, 30 Nov 2023 16:56:23 UTC
On 30 Nov 2023, at 10:34, Gleb Smirnoff wrote: > The branch main has been updated by glebius: > > URL: https://cgit.FreeBSD.org/src/commit/?id=cfb1e92912b4cf75360b7fbe86197cc29bc212c1 > > commit cfb1e92912b4cf75360b7fbe86197cc29bc212c1 > Author: Gleb Smirnoff <glebius@FreeBSD.org> > AuthorDate: 2023-11-30 16:30:55 +0000 > Commit: Gleb Smirnoff <glebius@FreeBSD.org> > CommitDate: 2023-11-30 16:30:55 +0000 > > sockets: don't malloc/free sockaddr memory on accept(2) > > Let the accept functions provide stack memory for protocols to fill it in. > Generic code should provide sockaddr_storage, specialized code may provide > smaller structure. Does this mean that families cannot support sockaddrs bigger than sockaddr_storage? In particular, does local domain (aka unix domain)? Did it before? Mike > While rewriting accept(2) make 'addrlen' a true in/out parameter, reporting > required length in case if provided length was insufficient. Our manual > page accept(2) and POSIX don't explicitly require that, but one can read > the text as they do. Linux also does that. Update tests accordingly. > > Reviewed by: rscheff, tuexen, zlei, dchagin > Differential Revision: https://reviews.freebsd.org/D42635 > --- > sys/cam/ctl/ctl_ha.c | 9 +-- > sys/compat/linux/linux_socket.c | 32 ++++----- > sys/dev/cxgbe/iw_cxgbe/cm.c | 7 +- > sys/dev/hyperv/hvsock/hv_sock.c | 7 +- > sys/dev/hyperv/hvsock/hv_sock.h | 2 +- > sys/dev/iscsi/icl_soft_proxy.c | 10 ++- > sys/kern/uipc_domain.c | 2 +- > sys/kern/uipc_socket.c | 9 ++- > sys/kern/uipc_syscalls.c | 67 +++++++----------- > sys/kern/uipc_usrreq.c | 10 +-- > sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h | 2 +- > .../bluetooth/include/ng_btsocket_rfcomm.h | 2 +- > sys/netgraph/bluetooth/include/ng_btsocket_sco.h | 2 +- > sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c | 72 +++++++++++-------- > sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c | 62 ++++++++++------- > sys/netgraph/bluetooth/socket/ng_btsocket_sco.c | 60 +++++++++------- > sys/netgraph/ng_ksocket.c | 12 ++-- > sys/netinet/sctp_usrreq.c | 48 +++++-------- > sys/netinet/sctp_var.h | 2 +- > sys/netinet/tcp_usrreq.c | 80 +++++++++------------- > sys/netinet6/in6_pcb.c | 19 ----- > sys/netinet6/in6_pcb.h | 2 - > sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c | 25 +++---- > sys/rpc/svc_vc.c | 12 ++-- > sys/sys/protosw.h | 2 +- > sys/sys/socketvar.h | 2 +- > sys/sys/syscallsubr.h | 8 +-- > tests/sys/kern/socket_accept.c | 3 - > 28 files changed, 261 insertions(+), 309 deletions(-) > > diff --git a/sys/cam/ctl/ctl_ha.c b/sys/cam/ctl/ctl_ha.c > index 0828c46c8863..695006ed99e1 100644 > --- a/sys/cam/ctl/ctl_ha.c > +++ b/sys/cam/ctl/ctl_ha.c > @@ -397,7 +397,7 @@ static int > 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 @@ ctl_ha_accept(struct ha_softc *softc) > 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 > index a5ed5c5c62db..2893e93bbcd7 100644 > --- a/sys/compat/linux/linux_socket.c > +++ b/sys/compat/linux/linux_socket.c > @@ -1017,31 +1017,29 @@ static int > 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 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, > 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 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t addr, > } > 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 > index 77158eb855df..84d6df3f2832 100644 > --- a/sys/dev/cxgbe/iw_cxgbe/cm.c > +++ b/sys/dev/cxgbe/iw_cxgbe/cm.c > @@ -974,7 +974,7 @@ process_newconn(struct c4iw_listen_ep *master_lep, struct socket *new_so) > { > 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 @@ process_newconn(struct c4iw_listen_ep *master_lep, struct socket *new_so) > 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.c b/sys/dev/hyperv/hvsock/hv_sock.c > index 60cdfecf3bee..655cc990876e 100644 > --- a/sys/dev/hyperv/hvsock/hv_sock.c > +++ b/sys/dev/hyperv/hvsock/hv_sock.c > @@ -478,7 +478,7 @@ hvs_trans_listen(struct socket *so, int backlog, struct thread *td) > } > > 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); > > @@ -488,10 +488,9 @@ hvs_trans_accept(struct socket *so, struct sockaddr **nam) > 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/hyperv/hvsock/hv_sock.h b/sys/dev/hyperv/hvsock/hv_sock.h > index 98a9afb747bf..ee6416a29662 100644 > --- a/sys/dev/hyperv/hvsock/hv_sock.h > +++ b/sys/dev/hyperv/hvsock/hv_sock.h > @@ -100,7 +100,7 @@ void hvs_trans_abort(struct socket *); > 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/iscsi/icl_soft_proxy.c b/sys/dev/iscsi/icl_soft_proxy.c > index ee448116b0e9..db9bf12a688c 100644 > --- a/sys/dev/iscsi/icl_soft_proxy.c > +++ b/sys/dev/iscsi/icl_soft_proxy.c > @@ -205,7 +205,7 @@ icl_accept_thread(void *arg) > { > struct icl_listen_sock *ils; > struct socket *head, *so; > - struct sockaddr *sa; > + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; > int error; > > ils = arg; > @@ -231,17 +231,15 @@ icl_accept_thread(void *arg) > 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 > index 03e6856b7750..cf9b91511574 100644 > --- a/sys/kern/uipc_domain.c > +++ b/sys/kern/uipc_domain.c > @@ -53,7 +53,7 @@ static struct mtx dom_mtx; /* domain list lock */ > 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 > index b59051ae3350..d16c0049dc43 100644 > --- a/sys/kern/uipc_socket.c > +++ b/sys/kern/uipc_socket.c > @@ -1348,12 +1348,17 @@ soabort(struct socket *so) > } > > 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 > index a7ffb6ef3254..0361144f2763 100644 > --- a/sys/kern/uipc_syscalls.c > +++ b/sys/kern/uipc_syscalls.c > @@ -277,19 +277,18 @@ static int > 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); > @@ -297,42 +296,40 @@ accept1(struct thread *td, int s, struct sockaddr *uname, socklen_t *anamelen, > #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); > @@ -386,29 +383,15 @@ kern_accept4(struct thread *td, int s, struct sockaddr **name, > (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 > index 53a7c2b2915a..3071a5169b72 100644 > --- a/sys/kern/uipc_usrreq.c > +++ b/sys/kern/uipc_usrreq.c > @@ -120,7 +120,10 @@ struct unp_defer { > 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 > @@ -434,7 +437,7 @@ uipc_abort(struct socket *so) > } > > 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; > @@ -446,14 +449,13 @@ uipc_accept(struct socket *so, struct sockaddr **nam) > 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 > index baaef9abb736..b512112f8b7d 100644 > --- a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h > +++ b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h > @@ -191,7 +191,7 @@ typedef struct ng_btsocket_l2cap_pcb * ng_btsocket_l2cap_pcb_p; > > 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 > index 88c0f8988587..d40b694ece14 100644 > --- a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h > +++ b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h > @@ -316,7 +316,7 @@ typedef struct ng_btsocket_rfcomm_pcb * ng_btsocket_rfcomm_pcb_p; > > 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 > index 071ddb8d80ef..282980cce881 100644 > --- a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h > +++ b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h > @@ -106,7 +106,7 @@ typedef struct ng_btsocket_sco_pcb * ng_btsocket_sco_pcb_p; > > 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 > index 8fc64bb70929..d221cc34d36a 100644 > --- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c > +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c > @@ -1967,20 +1967,6 @@ ng_btsocket_l2cap_close(struct socket *so) > (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 @@ out: > 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 > index 00225f8240e9..af542f3c258b 100644 > --- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c > +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c > @@ -370,17 +370,6 @@ ng_btsocket_rfcomm_close(struct socket *so) > (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 @@ out: > 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 @@ static int > 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 @@ ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) > 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 > index 5e198956a829..d9700f91c132 100644 > --- a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c > +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c > @@ -1176,20 +1176,6 @@ ng_btsocket_sco_close(struct socket *so) > (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 @@ out: > 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 > index 777f3261356d..23a53528833f 100644 > --- a/sys/netgraph/ng_ksocket.c > +++ b/sys/netgraph/ng_ksocket.c > @@ -1178,7 +1178,7 @@ ng_ksocket_accept(priv_p priv) > { > 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 @@ ng_ksocket_accept(priv_p priv) > 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 @@ ng_ksocket_accept(priv_p priv) > /* 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 > index 29d63f989e79..8fb96db84f95 100644 > --- a/sys/netinet/sctp_usrreq.c > +++ b/sys/netinet/sctp_usrreq.c > @@ -7271,7 +7271,7 @@ out: > 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 @@ sctp_accept(struct socket *so, struct sockaddr **addr) > 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 > index 3a649a1860e2..ff6672bd0248 100644 > --- a/sys/netinet/sctp_var.h > +++ b/sys/netinet/sctp_var.h > @@ -341,7 +341,7 @@ int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *); > 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 > index f89e60cce8cd..14e0b814dec9 100644 > --- a/sys/netinet/tcp_usrreq.c > +++ b/sys/netinet/tcp_usrreq.c > @@ -717,13 +717,11 @@ out: > * 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")); > @@ -734,39 +732,30 @@ tcp_usr_accept(struct socket *so, struct sockaddr **nam) > } > 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; > + > *** 273 LINES SKIPPED ***