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 <gleb...@freebsd.org>
> AuthorDate: 2023-11-30 16:30:55 +0000
> Commit:     Gleb Smirnoff <gleb...@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 ***

Reply via email to