From nobody Thu Nov 30 16:34:47 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Sh1xh10rMz52GYk; Thu, 30 Nov 2023 16:34:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Sh1xh0fJNz4WgX; Thu, 30 Nov 2023 16:34:48 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701362088; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZXzyuaETvhtH/TM11pMkBxFVinCnkMQYOFuyQMn2RJg=; b=e169c63TvV8QWjWbd9orqzYQWh+kviXOah6YwTuSzocq4VlnQ9+eie63o26/naqhHKV05R ziUGdxv44zUYFq6P6TaWPqvx7qtMPkZbOjpZlXlyHwfsBhZcy+/woZ7hwJBgAA3n2ZFuDC dw6v4Mm3NNeYnAY684wmeLH6TUBSRctsrHlRzWFnPktsNWC9GJbLY8DNOsM0YcbUiY9chE 6NNFPd76WpdmoLX0dhSG+OoTYLxrBmT3ii+oJT0qzGPi0P23KXcgSsBBdgwJoWOblXMY7x UOHDxMNYH/xsTmXNz/juxSaelZckB3vSyn6ZccEitdO7QzpgAncv/GyL7PdggA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701362088; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZXzyuaETvhtH/TM11pMkBxFVinCnkMQYOFuyQMn2RJg=; b=o29bmoqkivh4owJaZtiyVP8hgm5khaUqww6xw4oQsL5WkW5DUrSuzp/ibc0IlEL3tJEua0 4wlvRdNEwHm1CSLE5C1lvowSgP3Mk3rRl/AnLY8Tzq+9YR/vVdUQKaAqKJm2MwF2I/4QEi G4XeOaFN44TNRAIBdNCdxrkI1uWCCEa+JFVQwaGTnrulVemDHv4wADdFaWLFlzuIbOQTf/ ISOXAi/2rqIcteWivPO9tqqv0+256oQYQyHYYGXzgtrF0ZhuM22K/AulmRtLhCQ8jR1uOI eRwozHk1Gdl+7qSm5VyLCKw5ehDSMRPVTmRQvMBWjpIHyriBLZ1WZ4UKPDRb3w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1701362088; a=rsa-sha256; cv=none; b=aHkXZmX40A4KxgjZxMQgF0/R04Sq9FZbsgM0+22rluy7NPPM66nbl1iPZKeLko0fDY9K/k 3cEpvnr84gEJPjwNqFyvioHgQVUMecyNKkOM4BMbQPHPwGx67R9c5/wVbrGcCyzOUHAilg USdcRzLHnIzquA2nPMo6PvKrGykLQCOosOJXhG8UNFtBxydE5R+621rKH1ACCWJ8BDRK/Y oSpzNacxQbHdPmxXLFdhBvO4MNBrPFjulhqMG4mYJY9g5yQ2c8gH2PjR3maWQdR3ml6fXt 0fIKoGZ3od0EvbEtVlEVxdB72ZnMFaKSPmJ5M9ToRx9B6TuO+UhnDPWn7bICXw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Sh1xg6qx4zx4k; Thu, 30 Nov 2023 16:34:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3AUGYlbm055416; Thu, 30 Nov 2023 16:34:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3AUGYljD055413; Thu, 30 Nov 2023 16:34:47 GMT (envelope-from git) Date: Thu, 30 Nov 2023 16:34:47 GMT Message-Id: <202311301634.3AUGYljD055413@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: cfb1e92912b4 - main - sockets: don't malloc/free sockaddr memory on accept(2) List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: cfb1e92912b4cf75360b7fbe86197cc29bc212c1 Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=cfb1e92912b4cf75360b7fbe86197cc29bc212c1 commit cfb1e92912b4cf75360b7fbe86197cc29bc212c1 Author: Gleb Smirnoff AuthorDate: 2023-11-30 16:30:55 +0000 Commit: Gleb Smirnoff 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. 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 ***