Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Nov 2023 10:56:23 -0600
From:      Mike Karels <mike@karels.net>
To:        Gleb Smirnoff <glebius@FreeBSD.org>
Cc:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   Re: git: cfb1e92912b4 - main - sockets: don't malloc/free  sockaddr memory on accept(2)
Message-ID:  <EB9A71A9-D44C-4DD8-92E8-A6506B51B7B1@karels.net>
In-Reply-To: <202311301634.3AUGYljD055413@gitrepo.freebsd.org>
References:  <202311301634.3AUGYljD055413@gitrepo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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=3Dcfb1e92912b4cf75360b7fbe=
86197cc29bc212c1
>
> 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 sockadd=
r_storage?
In particular, does local domain (aka unix domain)?  Did it before?

		Mike

>     While rewriting accept(2) make 'addrlen' a true in/out parameter, r=
eporting
>     required length in case if provided length was insufficient.  Our m=
anual
>     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 accordingl=
y.
>
>     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 =3D { .sin_len =3D sizeof(sin) };
>  	int error;
>
>  	lso =3D softc->ha_lso;
> @@ -410,16 +410,11 @@ ctl_ha_accept(struct ha_softc *softc)
>  		goto out;
>  	}
>
> -	sap =3D NULL;
> -	error =3D soaccept(so, &sap);
> +	error =3D soaccept(so, (struct sockaddr *)&sin);
>  	if (error !=3D 0) {
>  		printf("%s: soaccept() error %d\n", __func__, error);
> -		if (sap !=3D NULL)
> -			free(sap, M_SONAME);
>  		goto out;
>  	}
> -	if (sap !=3D NULL)
> -		free(sap, M_SONAME);
>  	softc->ha_so =3D so;
>  	ctl_ha_sock_setup(softc);
>  	return (0);
> diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_s=
ocket.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 =3D { .ss_len =3D sizeof(ss) };
>  	struct file *fp, *fp1;
> -	int bflags, len;
>  	struct socket *so;
> -	int error, error1;
> +	socklen_t len;
> +	int bflags, error, error1;
>
>  	bflags =3D 0;
>  	fp =3D NULL;
> -	sa =3D NULL;
>
>  	error =3D linux_set_socket_flags(flags, &bflags);
>  	if (error !=3D 0)
>  		return (error);
>
> -	if (PTRIN(addr) =3D=3D NULL) {
> -		len =3D 0;
> -		error =3D kern_accept4(td, s, NULL, NULL, bflags, NULL);
> -	} else {
> +	if (PTRIN(addr) !=3D NULL) {
>  		error =3D copyin(PTRIN(namelen), &len, sizeof(len));
>  		if (error !=3D 0)
>  			return (error);
>  		if (len < 0)
>  			return (EINVAL);
> -		error =3D kern_accept4(td, s, &sa, &len, bflags, &fp);
> -	}
> +	} else
> +		len =3D 0;
> +
> +	error =3D 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 !=3D 0) {
> -		error =3D linux_copyout_sockaddr(sa, PTRIN(addr), len);
> -		if (error =3D=3D 0)
> -			error =3D copyout(&len, PTRIN(namelen),
> -			    sizeof(len));
> +	if (PTRIN(addr) !=3D NULL) {
> +		len =3D min(ss.ss_len, len);
> +		error =3D linux_copyout_sockaddr((struct sockaddr *)&ss,
> +		    PTRIN(addr), len);
> +		if (error =3D=3D 0) {
> +			len =3D ss.ss_len;
> +			error =3D copyout(&len, PTRIN(namelen), sizeof(len));
> +		}
>  		if (error !=3D 0) {
>  			fdclose(td, fp, td->td_retval[0]);
>  			td->td_retval[0] =3D 0;
> @@ -1083,7 +1084,6 @@ linux_accept_common(struct thread *td, int s, l_u=
intptr_t addr,
>  	}
>  	if (fp !=3D 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 =3D NULL;
>  	struct c4iw_ep *new_ep =3D NULL;
> -	struct sockaddr_in *remote =3D NULL;
> +	struct sockaddr_storage remote =3D { .ss_len =3D sizeof(remote) };
>  	int ret =3D 0;
>
>  	MPASS(new_so !=3D NULL);
> @@ -1019,19 +1019,16 @@ process_newconn(struct c4iw_listen_ep *master_l=
ep, struct socket *new_so)
>  	new_ep->com.state =3D MPA_REQ_WAIT;
>
>  	setiwsockopt(new_so);
> -	ret =3D soaccept(new_so, (struct sockaddr **)&remote);
> +	ret =3D soaccept(new_so, (struct sockaddr *)&remote);
>  	if (ret !=3D 0) {
>  		CTR4(KTR_IW_CXGBE,
>  				"%s:listen sock:%p, new sock:%p, ret:%d",
>  				__func__, master_lep->com.so, new_so, ret);
> -		if (remote !=3D 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, st=
ruct 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 =3D so2hvspcb(so);
>
> @@ -488,10 +488,9 @@ hvs_trans_accept(struct socket *so, struct sockadd=
r **nam)
>  	if (pcb =3D=3D NULL)
>  		return (EINVAL);
>
> -	*nam =3D sodupsockaddr((struct sockaddr *) &pcb->remote_addr,
> -	    M_NOWAIT);
> +	memcpy(sa, &pcb->remote_addr, pcb->remote_addr.sa_len);
>
> -	return ((*nam =3D=3D 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_pr=
oxy.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 =3D { .ss_len =3D sizeof(ss) };
>  	int error;
>
>  	ils =3D arg;
> @@ -231,17 +231,15 @@ icl_accept_thread(void *arg)
>  			continue;
>  		}
>
> -		sa =3D NULL;
> -		error =3D soaccept(so, &sa);
> +		error =3D soaccept(so, (struct sockaddr *)&ss);
>  		if (error !=3D 0) {
>  			ICL_WARN("soaccept error %d", error);
> -			if (sa !=3D 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 =3D sa->sa_len;
> +#endif
>  	int error;
>
>  	CURVNET_SET(so->so_vnet);
> -	error =3D so->so_proto->pr_accept(so, nam);
> +	error =3D so->so_proto->pr_accept(so, sa);
> +	KASSERT(sa->sa_len <=3D 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 *a=
namelen,
>      int flags)
>  {
> -	struct sockaddr *name;
> -	socklen_t namelen;
> +	struct sockaddr_storage ss =3D { .ss_len =3D sizeof(ss) };
> +	socklen_t addrlen;
>  	struct file *fp;
>  	int error;
>
> -	if (uname =3D=3D NULL)
> -		return (kern_accept4(td, s, NULL, NULL, flags, NULL));
> -
> -	error =3D copyin(anamelen, &namelen, sizeof (namelen));
> -	if (error !=3D 0)
> -		return (error);
> +	if (uname !=3D NULL) {
> +		error =3D copyin(anamelen, &addrlen, sizeof(addrlen));
> +		if (error !=3D 0)
> +			return (error);
> +	}
>
> -	error =3D kern_accept4(td, s, &name, &namelen, flags, &fp);
> +	error =3D kern_accept4(td, s, (struct sockaddr *)&ss, flags, &fp);
>
>  	if (error !=3D 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) !=3D 0)
> -		((struct osockaddr *)name)->sa_family =3D
> -		    name->sa_family;
> +		((struct osockaddr *)&ss)->sa_family =3D ss.ss_family;
>  #endif
> -	error =3D copyout(name, uname, namelen);
> -	if (error =3D=3D 0)
> -		error =3D copyout(&namelen, anamelen,
> -		    sizeof(namelen));
> +	if (uname !=3D NULL) {
> +		addrlen =3D min(ss.ss_len, addrlen);
> +		error =3D copyout(&ss, uname, addrlen);
> +		if (error =3D=3D 0) {
> +			addrlen =3D ss.ss_len;
> +			error =3D copyout(&addrlen, anamelen, sizeof(addrlen));
> +		}
> +	}
>  	if (error !=3D 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 =3D NULL;
> -	struct sockaddr *sa =3D NULL;
>  	struct socket *head, *so;
>  	struct filecaps fcaps;
>  	u_int fflag;
>  	pid_t pgid;
>  	int error, fd, tmp;
>
> -	if (name !=3D NULL)
> -		*name =3D NULL;
> -
>  	AUDIT_ARG_FD(s);
>  	error =3D getsock_cap(td, s, &cap_accept_rights,
>  	    &headfp, &fcaps);
> @@ -386,29 +383,15 @@ kern_accept4(struct thread *td, int s, struct soc=
kaddr **name,
>  	(void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td);
>  	tmp =3D fflag & FASYNC;
>  	(void) fo_ioctl(nfp, FIOASYNC, &tmp, td->td_ucred, td);
> -	error =3D soaccept(so, &sa);
> -	if (error !=3D 0)
> -		goto noconnection;
> -	if (sa =3D=3D NULL) {
> -		if (name)
> -			*namelen =3D 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 =3D sa->sa_len;
> +
> +	if ((error =3D soaccept(so, sa)) =3D=3D 0) {
> +		AUDIT_ARG_SOCKADDR(td, AT_FDCWD, sa);
>  #ifdef KTRACE
>  		if (KTRPOINT(td, KTR_STRUCT))
>  			ktrsockaddr(sa);
>  #endif
> -		*name =3D sa;
> -		sa =3D 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 =3D { sizeof(sun_noname), AF_L=
OCAL };
> +static const struct sockaddr	sun_noname =3D {
> +	.sa_len =3D sizeof(sun_noname),
> +	.sa_family =3D AF_LOCAL,
> +};
>
>  /*
>   * Garbage collection of cyclic file descriptor/socket references occu=
rs
> @@ -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 =3D sotounpcb(so);
>  	KASSERT(unp !=3D NULL, ("uipc_accept: unp =3D=3D NULL"));
>
> -	*nam =3D malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK);
>  	UNP_PCB_LOCK(unp);
>  	unp2 =3D unp_pcb_lock_peer(unp);
>  	if (unp2 !=3D NULL && unp2->unp_addr !=3D NULL)
>  		sa =3D (struct sockaddr *)unp2->unp_addr;
>  	else
>  		sa =3D &sun_noname;
> -	bcopy(sa, *nam, sa->sa_len);
> +	bcopy(sa, ret, sa->sa_len);
>  	if (unp2 !=3D NULL)
>  		unp_pcb_unlock_pair(unp, unp2);
>  	else
> diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h b/sys/n=
etgraph/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 threa=
d *);
>  int  ng_btsocket_rfcomm_bind       (struct socket *, struct sockaddr *=
,
>                                      struct thread *);
> diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h b/sys/net=
graph/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_sc=
o_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/ne=
tgraph/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 con=
nected
> - * 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 =3D=3D 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 =3D so2l2cap_pcb(so);
> -	struct sockaddr_l2cap	sa;
>
>  	if (pcb =3D=3D NULL)
>  		return (EINVAL);
>  	if (ng_btsocket_l2cap_node =3D=3D NULL)
>  		return (EINVAL);
>
> -	bcopy(&pcb->dst, &sa.l2cap_bdaddr, sizeof(sa.l2cap_bdaddr));
> -	sa.l2cap_psm =3D htole16(pcb->psm);
> -	sa.l2cap_len =3D sizeof(sa);
> -	sa.l2cap_family =3D AF_BLUETOOTH;
> +	*sa =3D (struct sockaddr_l2cap ){
> +		.l2cap_len =3D sizeof(struct sockaddr_l2cap),
> +		.l2cap_family =3D AF_BLUETOOTH,
> +		.l2cap_psm =3D 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 =3D NG_L2CAP_ATT_CID;
> +		sa->l2cap_cid =3D NG_L2CAP_ATT_CID;
>  		break;
>  	case NG_L2CAP_L2CA_IDTYPE_SMP:
> -		sa.l2cap_cid =3D NG_L2CAP_SMP_CID;
> +		sa->l2cap_cid =3D NG_L2CAP_SMP_CID;
>  		break;
>  	default:
> -		sa.l2cap_cid =3D 0;
> +		sa->l2cap_cid =3D 0;
>  		break;
>  	}
> -	sa.l2cap_bdaddr_type =3D pcb->dsttype;
> +	sa->l2cap_bdaddr_type =3D 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 =3D ng_btsocket_l2cap_peeraddr1(so, &sa);
> +	if (error !=3D 0)
> +		return (error);
>  	*nam =3D sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
>
>  	return ((*nam =3D=3D NULL)? ENOMEM : 0);
> -} /* ng_btsocket_l2cap_peeraddr */
> +}
> +
> +/*
> + * Accept connection on socket. Nothing to do here, socket must be con=
nected
> + * 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 =3D=3D 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/n=
etgraph/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 con=
nected
> - * 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 =3D so2rfcomm_pcb(so);
> -	struct sockaddr_rfcomm		sa;
>
>  	if (pcb =3D=3D NULL)
>  		return (EINVAL);
>
> -	bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr));
> -	sa.rfcomm_channel =3D pcb->channel;
> -	sa.rfcomm_len =3D sizeof(sa);
> -	sa.rfcomm_family =3D AF_BLUETOOTH;
> +	*sa =3D (struct sockaddr_rfcomm ){
> +		.rfcomm_len =3D sizeof(struct sockaddr_rfcomm),
> +		.rfcomm_family =3D AF_BLUETOOTH,
> +		.rfcomm_channel =3D 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 =3D ng_btsocket_rfcomm_peeraddr1(so, &sa);
> +	if (error !=3D 0)
> +		return (error);
>  	*nam =3D sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
>
>  	return ((*nam =3D=3D NULL)? ENOMEM : 0);
> -} /* ng_btsocket_rfcomm_peeraddr */
> +}
> +
> +/*
> + * Accept connection on socket. Nothing to do here, socket must be con=
nected
> + * 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 =3D NULL;
> +	struct sockaddr_l2cap		l2sa =3D { .l2cap_len =3D sizeof(l2sa) };
>  	ng_btsocket_l2cap_pcb_t		*l2pcb =3D NULL;
>  	ng_btsocket_rfcomm_session_p	 s =3D NULL;
>  	int				 error;
> @@ -1425,7 +1437,7 @@ ng_btsocket_rfcomm_session_accept(ng_btsocket_rfc=
omm_session_p s0)
>  		return (error);
>  	}
>
> -	error =3D soaccept(l2so, (struct sockaddr **) &l2sa);
> +	error =3D soaccept(l2so, (struct sockaddr *)&l2sa);
>  	if (error !=3D 0) {
>  		NG_BTSOCKET_RFCOMM_ERR(
>  "%s: soaccept() on L2CAP socket failed, error=3D%d\n", __func__, error=
);
> diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c b/sys/netg=
raph/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 con=
nected
> - * 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 =3D=3D 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 =3D so2sco_pcb(so);
> -	struct sockaddr_sco	sa;
>
>  	if (pcb =3D=3D NULL)
>  		return (EINVAL);
>  	if (ng_btsocket_sco_node =3D=3D NULL)
>  		return (EINVAL);
>
> +	*sa =3D (struct sockaddr_sco ){
> +		.sco_len =3D sizeof(struct sockaddr_sco),
> +		.sco_family =3D 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 =3D sizeof(sa);
> -	sa.sco_family =3D 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 =3D ng_btsocket_sco_peeraddr1(so, &sa);
> +	if (error !=3D 0)
> +		return (error);
>  	*nam =3D sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT);
>
>  	return ((*nam =3D=3D NULL)? ENOMEM : 0);
> -} /* ng_btsocket_sco_peeraddr */
> +}
> +
> +/*
> + * Accept connection on socket. Nothing to do here, socket must be con=
nected
> + * 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 =3D=3D 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 =3D priv->so;
>  	struct socket *so;
> -	struct sockaddr *sa =3D NULL;
> +	struct sockaddr_storage ss =3D { .ss_len =3D 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 =3D soaccept(so, &sa)) !=3D 0)
> +	if ((error =3D soaccept(so, (struct sockaddr *)&ss)) !=3D 0)
>  		return (error);
>
>  	len =3D OFFSETOF(struct ng_ksocket_accept, addr);
> -	if (sa !=3D NULL)
> -		len +=3D sa->sa_len;
> +	len +=3D 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 =3D (struct ng_ksocket_accept *)resp->data;
>  	resp_data->nodeid =3D NG_NODE_ID(node);
> -	if (sa !=3D 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 !=3D 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 =3D 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 =3D=3D NULL)
> -				return (ENOMEM);
> -			sin->sin_family =3D AF_INET;
> -			sin->sin_len =3D sizeof(*sin);
> -			sin->sin_port =3D store.sin.sin_port;
> -			sin->sin_addr =3D store.sin.sin_addr;
> -			*addr =3D (struct sockaddr *)sin;
> -			break;
> -		}
> +		*(struct sockaddr_in *)sa =3D (struct sockaddr_in ){
> +			.sin_family =3D AF_INET,
> +			.sin_len =3D sizeof(struct sockaddr_in),
> +			.sin_port =3D store.sin.sin_port,
> +			.sin_addr =3D 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 =3D=3D NULL)
> -				return (ENOMEM);
> -			sin6->sin6_family =3D AF_INET6;
> -			sin6->sin6_len =3D sizeof(*sin6);
> -			sin6->sin6_port =3D store.sin6.sin6_port;
> -			sin6->sin6_addr =3D store.sin6.sin6_addr;
> -			if ((error =3D sa6_recoverscope(sin6)) !=3D 0) {
> -				SCTP_FREE_SONAME(sin6);
> -				return (error);
> -			}
> -			*addr =3D (struct sockaddr *)sin6;
> -			break;
> -		}
> +		*(struct sockaddr_in6 *)sa =3D (struct sockaddr_in6 ){
> +			.sin6_family =3D AF_INET6,
> +			.sin6_len =3D sizeof(struct sockaddr_in6),
> +			.sin6_port =3D store.sin6.sin6_port,
> +			.sin6_addr =3D store.sin6.sin6_addr,
> +		};
> +		if ((error =3D sa6_recoverscope((struct sockaddr_in6 *)sa)) !=3D 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 =3D 0;
>  	struct inpcb *inp;
>  	struct tcpcb *tp;
> -	struct in_addr addr;
> -	in_port_t port =3D 0;
> +	int error =3D 0;
>
>  	inp =3D sotoinpcb(so);
>  	KASSERT(inp !=3D NULL, ("tcp_usr_accept: inp =3D=3D NULL"));
> @@ -734,39 +732,30 @@ tcp_usr_accept(struct socket *so, struct sockaddr=
 **nam)
>  	}
>  	tp =3D intotcpcb(inp);
>
> -	if (so->so_state & SS_ISDISCONNECTED) {
> +	if (so->so_state & SS_ISDISCONNECTED)
>  		error =3D 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 =3D inp->inp_fport;
> -	addr =3D inp->inp_faddr;
> -
> -out:
> +	else
> +		*(struct sockaddr_in *)sa =3D (struct sockaddr_in ){
> +			.sin_family =3D AF_INET,
> +			.sin_len =3D sizeof(struct sockaddr_in),
> +			.sin_port =3D inp->inp_fport,
> +			.sin_addr =3D inp->inp_faddr,
> +		};
>  	tcp_bblog_pru(tp, PRU_ACCEPT, error);
>  	TCP_PROBE2(debug__user, tp, PRU_ACCEPT);
>  	INP_WUNLOCK(inp);
> -	if (error =3D=3D 0)
> -		*nam =3D in_sockaddr(port, &addr);
> -	return error;
> +
> *** 273 LINES SKIPPED ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?EB9A71A9-D44C-4DD8-92E8-A6506B51B7B1>