From nobody Thu Nov 30 16:34:48 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 4Sh1xj27llz52GYl; Thu, 30 Nov 2023 16:34:49 +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 4Sh1xj1TJlz4Wjn; Thu, 30 Nov 2023 16:34:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701362089; 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=yr8RdVSjFJs51jrTXVHQ9Ak3+ocY1mEpGtvUR8jlrfg=; b=GT4fK991vlghM4NcrSYJeoY+h/gvCg1CeLVbzfTtJBmT5LlqPtkuOJ+hpcTIN+CgLcdCn1 oonHm44UkJORDzPYZPlmEoVc/nrfCKQiJbzje/A6TZy1FiKd4rqYNm+J3kpkeCT1LBZbkr YgOFhOzwx0LQwL3E3/Gy4TJjY3ouXEfV/IgntvJyn7s2GH2B3W8SgTBcw/J5HobY53Wnvd V1Th7VSrUycaPRe61yZyvPfehxutq2AjNZYp0DdXZn/fC3pJrBuG5ENEIbnqyT40HVjSig VTZysPZPa0Yz2Urj3TpIPlmG7qUgJ7ltIslOImy3rjhKU77zoYIDSop+bWWAJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1701362089; 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=yr8RdVSjFJs51jrTXVHQ9Ak3+ocY1mEpGtvUR8jlrfg=; b=qPYrslPHStqYUZSoxur90m47bg2GHWBwWx7cKOjdmPodCobMR6kdRlGz/LxQjcJs28Vl4L L/rHWiMhb4MCt+kYwOzWIEiJ/SAdsOWQqgB+y9PbX8Y9dcEnnFuMH5xH4aKdUcIlZ9qcV1 pCHCMAgqnLY/XvO1FcGxbV69p+Q+eWOopSjOI6RnAsoOAG96t56B1VfBSOOZyjm4DHZHWp Z+i91N57o/Ha7P69m5mxcie/xBjaU23xIBgBpVfOixZBcohjDn69gjx+zffy+y//sUeqeg ckCjyMrnqS+L+UhaxGk0I5boQ0uSlPIG5l2/Qu+Jj4g7DcCfUpvV+k9vyWdnYw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1701362089; a=rsa-sha256; cv=none; b=o+trf1+vREs7Hm73rjENrxU8T/k49DFjwPICVzk3IkN3Hn4Z9nqlAeZvxBLLp8brvcaxLW nSpWfW0vjaPtuywsRpiFFWiAxou4fzwA+Tp5LEnlQEpvTaVszDcWWJFx1J0bgi2/ubqMPX OV9YuZSpOzT40Hm10CEU50U/IOdgjf9IwojuisK+e8eo1CUGNCg4evkqn/vROpk36LkruK Dv9VYjE7D1S7WKlkGXWNmbJUlcmfBUuUwRZNLG8yxrT8rSotYae2Iap2z0kBAi6iz7lXi0 H1/Dfg9ezcgVy34SDH6I7emG18pfV60zzK6B1nvNcRMVyVKG4A7Jgvdm0h9L9w== 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 4Sh1xj0X5Wzwsm; Thu, 30 Nov 2023 16:34:49 +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 3AUGYnBc055465; Thu, 30 Nov 2023 16:34:49 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3AUGYm9O055462; Thu, 30 Nov 2023 16:34:48 GMT (envelope-from git) Date: Thu, 30 Nov 2023 16:34:48 GMT Message-Id: <202311301634.3AUGYm9O055462@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: 0fac350c54d0 - main - sockets: don't malloc/free sockaddr memory on getpeername/getsockname 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: 0fac350c54d0a72f5341e15021efcde63eb58a4b Auto-Submitted: auto-generated The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=0fac350c54d0a72f5341e15021efcde63eb58a4b commit 0fac350c54d0a72f5341e15021efcde63eb58a4b Author: Gleb Smirnoff AuthorDate: 2023-11-30 16:30:55 +0000 Commit: Gleb Smirnoff CommitDate: 2023-11-30 16:31:10 +0000 sockets: don't malloc/free sockaddr memory on getpeername/getsockname Just like it was done for accept(2) in cfb1e92912b4, use same approach for two simplier syscalls that return socket addresses. Although, these two syscalls aren't performance critical, this change generalizes some code between 3 syscalls trimming code size. Following example of accept(2), provide VNET-aware and INVARIANT-checking wrappers sopeeraddr() and sosockaddr() around protosw methods. Reviewed by: tuexen Differential Revision: https://reviews.freebsd.org/D42694 --- sys/compat/linux/linux_socket.c | 45 +++++------ sys/compat/linuxkpi/common/include/linux/net.h | 17 +++-- sys/dev/cxgbe/iw_cxgbe/cm.c | 14 +--- sys/dev/hyperv/hvsock/hv_sock.c | 12 +-- sys/dev/hyperv/hvsock/hv_sock.h | 4 +- sys/dev/wg/if_wg.c | 24 +++--- sys/kern/sys_socket.c | 17 ++--- sys/kern/uipc_domain.c | 4 +- sys/kern/uipc_socket.c | 34 +++++++++ sys/kern/uipc_syscalls.c | 86 +++++++--------------- sys/kern/uipc_usrreq.c | 48 +++--------- sys/net/if_ovpn.c | 12 +-- .../bluetooth/include/ng_btsocket_hci_raw.h | 3 +- sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h | 9 +-- .../bluetooth/include/ng_btsocket_rfcomm.h | 4 +- sys/netgraph/bluetooth/include/ng_btsocket_sco.h | 4 +- sys/netgraph/bluetooth/socket/ng_btsocket.c | 8 +- .../bluetooth/socket/ng_btsocket_hci_raw.c | 29 +++----- sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c | 75 ++++++------------- .../bluetooth/socket/ng_btsocket_l2cap_raw.c | 47 ++++++------ sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c | 61 +++++---------- sys/netgraph/bluetooth/socket/ng_btsocket_sco.c | 62 +++++----------- sys/netgraph/ng_ksocket.c | 28 +++---- sys/netgraph/ng_socket.c | 23 ++---- sys/netinet/in_pcb.c | 49 ++++-------- sys/netinet/in_pcb.h | 6 +- sys/netinet/sctp_os.h | 3 - sys/netinet/sctp_os_bsd.h | 7 -- sys/netinet/sctp_usrreq.c | 40 ++++------ sys/netinet/sctp_var.h | 4 +- sys/netinet6/in6.c | 14 ---- sys/netinet6/in6.h | 1 - sys/netinet6/in6_pcb.c | 74 ++++++++----------- sys/netinet6/in6_pcb.h | 10 +-- sys/netinet6/sctp6_usrreq.c | 84 +++++++-------------- sys/netlink/netlink_domain.c | 27 +++---- sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c | 36 ++++----- sys/rpc/rpc_generic.c | 45 ++++------- sys/rpc/svc_dg.c | 9 +-- sys/rpc/svc_vc.c | 27 ++----- sys/sys/protosw.h | 4 +- sys/sys/socketvar.h | 2 + sys/sys/syscallsubr.h | 6 +- 43 files changed, 420 insertions(+), 698 deletions(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 2893e93bbcd7..f474ea06440a 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1106,48 +1106,50 @@ linux_accept4(struct thread *td, struct linux_accept4_args *args) int linux_getsockname(struct thread *td, struct linux_getsockname_args *args) { - struct sockaddr *sa; - int len, error; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; + socklen_t len; + int error; error = copyin(PTRIN(args->namelen), &len, sizeof(len)); if (error != 0) return (error); - error = kern_getsockname(td, args->s, &sa, &len); + error = kern_getsockname(td, args->s, (struct sockaddr *)&ss); if (error != 0) return (error); - if (len != 0) - error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len); - - free(sa, M_SONAME); - if (error == 0) + len = min(ss.ss_len, len); + error = linux_copyout_sockaddr((struct sockaddr *)&ss, + PTRIN(args->addr), len); + if (error == 0) { + len = ss.ss_len; error = copyout(&len, PTRIN(args->namelen), sizeof(len)); + } return (error); } int linux_getpeername(struct thread *td, struct linux_getpeername_args *args) { - struct sockaddr *sa; - int len, error; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; + socklen_t len; + int error; error = copyin(PTRIN(args->namelen), &len, sizeof(len)); if (error != 0) return (error); - if (len < 0) - return (EINVAL); - error = kern_getpeername(td, args->s, &sa, &len); + error = kern_getpeername(td, args->s, (struct sockaddr *)&ss); if (error != 0) return (error); - if (len != 0) - error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len); - - free(sa, M_SONAME); - if (error == 0) + len = min(ss.ss_len, len); + error = linux_copyout_sockaddr((struct sockaddr *)&ss, + PTRIN(args->addr), len); + if (error == 0) { + len = ss.ss_len; error = copyout(&len, PTRIN(args->namelen), sizeof(len)); + } return (error); } @@ -1348,6 +1350,7 @@ static int linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, l_uint flags) { + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; struct cmsghdr *cmsg; struct mbuf *control; struct msghdr msg; @@ -1356,7 +1359,6 @@ linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, struct l_msghdr linux_msghdr; struct iovec *iov; socklen_t datalen; - struct sockaddr *sa; struct socket *so; sa_family_t sa_family; struct file *fp; @@ -1395,11 +1397,10 @@ linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr, control = NULL; - error = kern_getsockname(td, s, &sa, &datalen); + error = kern_getsockname(td, s, (struct sockaddr *)&ss); if (error != 0) goto bad; - sa_family = sa->sa_family; - free(sa, M_SONAME); + sa_family = ss.ss_family; if (flags & LINUX_MSG_OOB) { error = EOPNOTSUPP; diff --git a/sys/compat/linuxkpi/common/include/linux/net.h b/sys/compat/linuxkpi/common/include/linux/net.h index f750de8c5cf3..dc0b46df9c99 100644 --- a/sys/compat/linuxkpi/common/include/linux/net.h +++ b/sys/compat/linuxkpi/common/include/linux/net.h @@ -45,26 +45,27 @@ sock_create_kern(int family, int type, int proto, struct socket **res) } static inline int -sock_getname(struct socket *so, struct sockaddr *addr, int *sockaddr_len, +sock_getname(struct socket *so, struct sockaddr *sa, int *sockaddr_len, int peer) { - struct sockaddr *nam; int error; - nam = NULL; + /* + * XXXGL: we can't use sopeeraddr()/sosockaddr() here since with + * INVARIANTS they would check if supplied sockaddr has enough + * length. Such notion doesn't even exist in Linux KPI. + */ if (peer) { if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) return (-ENOTCONN); - error = so->so_proto->pr_peeraddr(so, &nam); + error = so->so_proto->pr_peeraddr(so, sa); } else - error = so->so_proto->pr_sockaddr(so, &nam); + error = so->so_proto->pr_sockaddr(so, sa); if (error) return (-error); - *addr = *nam; - *sockaddr_len = addr->sa_len; + *sockaddr_len = sa->sa_len; - free(nam, M_SONAME); return (0); } diff --git a/sys/dev/cxgbe/iw_cxgbe/cm.c b/sys/dev/cxgbe/iw_cxgbe/cm.c index 84d6df3f2832..e0e48fdff9ba 100644 --- a/sys/dev/cxgbe/iw_cxgbe/cm.c +++ b/sys/dev/cxgbe/iw_cxgbe/cm.c @@ -145,30 +145,24 @@ static void process_newconn(struct c4iw_listen_ep *master_lep, #define GET_LOCAL_ADDR(pladdr, so) \ do { \ - struct sockaddr_storage *__a = NULL; \ struct inpcb *__inp = sotoinpcb(so); \ KASSERT(__inp != NULL, \ ("GET_LOCAL_ADDR(%s):so:%p, inp = NULL", __func__, so)); \ if (__inp->inp_vflag & INP_IPV4) \ - in_getsockaddr(so, (struct sockaddr **)&__a); \ + in_getsockaddr(so, (struct sockaddr *)pladdr); \ else \ - in6_getsockaddr(so, (struct sockaddr **)&__a); \ - *(pladdr) = *__a; \ - free(__a, M_SONAME); \ + in6_getsockaddr(so, (struct sockaddr *)pladdr); \ } while (0) #define GET_REMOTE_ADDR(praddr, so) \ do { \ - struct sockaddr_storage *__a = NULL; \ struct inpcb *__inp = sotoinpcb(so); \ KASSERT(__inp != NULL, \ ("GET_REMOTE_ADDR(%s):so:%p, inp = NULL", __func__, so)); \ if (__inp->inp_vflag & INP_IPV4) \ - in_getpeeraddr(so, (struct sockaddr **)&__a); \ + in_getpeeraddr(so, (struct sockaddr *)praddr); \ else \ - in6_getpeeraddr(so, (struct sockaddr **)&__a); \ - *(praddr) = *__a; \ - free(__a, M_SONAME); \ + in6_getpeeraddr(so, (struct sockaddr *)praddr); \ } while (0) static char *states[] = { diff --git a/sys/dev/hyperv/hvsock/hv_sock.c b/sys/dev/hyperv/hvsock/hv_sock.c index 655cc990876e..78ec520f1bb3 100644 --- a/sys/dev/hyperv/hvsock/hv_sock.c +++ b/sys/dev/hyperv/hvsock/hv_sock.c @@ -876,7 +876,7 @@ out: } int -hvs_trans_peeraddr(struct socket *so, struct sockaddr **nam) +hvs_trans_peeraddr(struct socket *so, struct sockaddr *sa) { struct hvs_pcb *pcb = so2hvspcb(so); @@ -886,13 +886,13 @@ hvs_trans_peeraddr(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 -hvs_trans_sockaddr(struct socket *so, struct sockaddr **nam) +hvs_trans_sockaddr(struct socket *so, struct sockaddr *sa) { struct hvs_pcb *pcb = so2hvspcb(so); @@ -902,9 +902,9 @@ hvs_trans_sockaddr(struct socket *so, struct sockaddr **nam) if (pcb == NULL) return (EINVAL); - *nam = sodupsockaddr((struct sockaddr *) &pcb->local_addr, M_NOWAIT); + memcpy(sa, &pcb->local_addr, pcb->local_addr.sa_len); - return ((*nam == NULL)? ENOMEM : 0); + return (0); } void diff --git a/sys/dev/hyperv/hvsock/hv_sock.h b/sys/dev/hyperv/hvsock/hv_sock.h index ee6416a29662..e11621d76dbc 100644 --- a/sys/dev/hyperv/hvsock/hv_sock.h +++ b/sys/dev/hyperv/hvsock/hv_sock.h @@ -103,8 +103,8 @@ int hvs_trans_listen(struct socket *, int, struct thread *); 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 **); -int hvs_trans_sockaddr(struct socket *, struct sockaddr **); +int hvs_trans_peeraddr(struct socket *, struct sockaddr *); +int hvs_trans_sockaddr(struct socket *, struct sockaddr *); int hvs_trans_soreceive(struct socket *, struct sockaddr **, struct uio *, struct mbuf **, struct mbuf **, int *); int hvs_trans_sosend(struct socket *, struct sockaddr *, struct uio *, diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c index 0ea40b763416..71c80c8b5f77 100644 --- a/sys/dev/wg/if_wg.c +++ b/sys/dev/wg/if_wg.c @@ -806,14 +806,15 @@ wg_socket_bind(struct socket **in_so4, struct socket **in_so6, in_port_t *reques if (ret4 && ret4 != EADDRNOTAVAIL) return (ret4); if (!ret4 && !sin.sin_port) { - struct sockaddr_in *bound_sin; - int ret = so4->so_proto->pr_sockaddr(so4, - (struct sockaddr **)&bound_sin); + struct sockaddr_in bound_sin = + { .sin_len = sizeof(bound_sin) }; + int ret; + + ret = sosockaddr(so4, (struct sockaddr *)&bound_sin); if (ret) return (ret); - port = ntohs(bound_sin->sin_port); - sin6.sin6_port = bound_sin->sin_port; - free(bound_sin, M_SONAME); + port = ntohs(bound_sin.sin_port); + sin6.sin6_port = bound_sin.sin_port; } } @@ -822,13 +823,14 @@ wg_socket_bind(struct socket **in_so4, struct socket **in_so6, in_port_t *reques if (ret6 && ret6 != EADDRNOTAVAIL) return (ret6); if (!ret6 && !sin6.sin6_port) { - struct sockaddr_in6 *bound_sin6; - int ret = so6->so_proto->pr_sockaddr(so6, - (struct sockaddr **)&bound_sin6); + struct sockaddr_in6 bound_sin6 = + { .sin6_len = sizeof(bound_sin6) }; + int ret; + + ret = sosockaddr(so6, (struct sockaddr *)&bound_sin6); if (ret) return (ret); - port = ntohs(bound_sin6->sin6_port); - free(bound_sin6, M_SONAME); + port = ntohs(bound_sin6.sin6_port); } } diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 7169805a0d3f..314576281d6e 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -355,7 +355,7 @@ soo_close(struct file *fp, struct thread *td) static int soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) { - struct sockaddr *sa; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; struct inpcb *inpcb; struct unpcb *unpcb; struct socket *so; @@ -404,17 +404,16 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) } break; } - error = so->so_proto->pr_sockaddr(so, &sa); + error = sosockaddr(so, (struct sockaddr *)&ss); if (error == 0 && - sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) { - bcopy(sa, &kif->kf_un.kf_sock.kf_sa_local, sa->sa_len); - free(sa, M_SONAME); + ss.ss_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) { + bcopy(&ss, &kif->kf_un.kf_sock.kf_sa_local, ss.ss_len); } - error = so->so_proto->pr_peeraddr(so, &sa); + ss.ss_len = sizeof(ss); + error = sopeeraddr(so, (struct sockaddr *)&ss); if (error == 0 && - sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) { - bcopy(sa, &kif->kf_un.kf_sock.kf_sa_peer, sa->sa_len); - free(sa, M_SONAME); + ss.ss_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) { + bcopy(&ss, &kif->kf_un.kf_sock.kf_sa_peer, ss.ss_len); } strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name, sizeof(kif->kf_path)); diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index cf9b91511574..435b13842041 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -116,7 +116,7 @@ pr_listen_notsupp(struct socket *so, int backlog, struct thread *td) } static int -pr_peeraddr_notsupp(struct socket *so, struct sockaddr **nam) +pr_peeraddr_notsupp(struct socket *so, struct sockaddr *nam) { return (EOPNOTSUPP); } @@ -157,7 +157,7 @@ pr_shutdown_notsupp(struct socket *so) } static int -pr_sockaddr_notsupp(struct socket *so, struct sockaddr **nam) +pr_sockaddr_notsupp(struct socket *so, struct sockaddr *nam) { return (EOPNOTSUPP); } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index d16c0049dc43..efa349d140ff 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1363,6 +1363,40 @@ soaccept(struct socket *so, struct sockaddr *sa) return (error); } +int +sopeeraddr(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_peeraddr(so, sa); + KASSERT(sa->sa_len <= len, + ("%s: protocol %p sockaddr overflow", __func__, so->so_proto)); + CURVNET_RESTORE(); + + return (error); +} + +int +sosockaddr(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_sockaddr(so, sa); + KASSERT(sa->sa_len <= len, + ("%s: protocol %p sockaddr overflow", __func__, so->so_proto)); + CURVNET_RESTORE(); + + return (error); +} + int soconnect(struct socket *so, struct sockaddr *nam, struct thread *td) { diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 0361144f2763..e46fdef84fc9 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1308,7 +1308,7 @@ static int user_getsockname(struct thread *td, int fdes, struct sockaddr *asa, socklen_t *alen, bool compat) { - struct sockaddr *sa; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; socklen_t len; int error; @@ -1316,30 +1316,28 @@ user_getsockname(struct thread *td, int fdes, struct sockaddr *asa, if (error != 0) return (error); - error = kern_getsockname(td, fdes, &sa, &len); + error = kern_getsockname(td, fdes, (struct sockaddr *)&ss); if (error != 0) return (error); - if (len != 0) { #ifdef COMPAT_OLDSOCK - if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT)) - ((struct osockaddr *)sa)->sa_family = sa->sa_family; + if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT)) + ((struct osockaddr *)&ss)->sa_family = ss.ss_family; #endif - error = copyout(sa, asa, len); - } - free(sa, M_SONAME); - if (error == 0) + len = min(ss.ss_len, len); + error = copyout(&ss, asa, len); + if (error == 0) { + len = ss.ss_len; error = copyout(&len, alen, sizeof(len)); + } return (error); } int -kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, - socklen_t *alen) +kern_getsockname(struct thread *td, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; - socklen_t len; int error; AUDIT_ARG_FD(fd); @@ -1347,27 +1345,12 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa, if (error != 0) return (error); so = fp->f_data; - *sa = NULL; - CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_sockaddr(so, sa); - CURVNET_RESTORE(); - if (error != 0) - goto bad; - if (*sa == NULL) - len = 0; - else - len = MIN(*alen, (*sa)->sa_len); - *alen = len; + error = sosockaddr(so, sa); #ifdef KTRACE - if (KTRPOINT(td, KTR_STRUCT)) - ktrsockaddr(*sa); + if (error == 0 && KTRPOINT(td, KTR_STRUCT)) + ktrsockaddr(sa); #endif -bad: fdrop(fp, td); - if (error != 0 && *sa != NULL) { - free(*sa, M_SONAME); - *sa = NULL; - } return (error); } @@ -1389,7 +1372,7 @@ static int user_getpeername(struct thread *td, int fdes, struct sockaddr *asa, socklen_t *alen, bool compat) { - struct sockaddr *sa; + struct sockaddr_storage ss = { .ss_len = sizeof(ss) }; socklen_t len; int error; @@ -1397,30 +1380,28 @@ user_getpeername(struct thread *td, int fdes, struct sockaddr *asa, if (error != 0) return (error); - error = kern_getpeername(td, fdes, &sa, &len); + error = kern_getpeername(td, fdes, (struct sockaddr *)&ss); if (error != 0) return (error); - if (len != 0) { #ifdef COMPAT_OLDSOCK - if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT)) - ((struct osockaddr *)sa)->sa_family = sa->sa_family; + if (compat && SV_PROC_FLAG(td->td_proc, SV_AOUT)) + ((struct osockaddr *)&ss)->sa_family = ss.ss_family; #endif - error = copyout(sa, asa, len); - } - free(sa, M_SONAME); - if (error == 0) + len = min(ss.ss_len, len); + error = copyout(&ss, asa, len); + if (error == 0) { + len = ss.ss_len; error = copyout(&len, alen, sizeof(len)); + } return (error); } int -kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, - socklen_t *alen) +kern_getpeername(struct thread *td, int fd, struct sockaddr *sa) { struct socket *so; struct file *fp; - socklen_t len; int error; AUDIT_ARG_FD(fd); @@ -1432,26 +1413,11 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa, error = ENOTCONN; goto done; } - *sa = NULL; - CURVNET_SET(so->so_vnet); - error = so->so_proto->pr_peeraddr(so, sa); - CURVNET_RESTORE(); - if (error != 0) - goto bad; - if (*sa == NULL) - len = 0; - else - len = MIN(*alen, (*sa)->sa_len); - *alen = len; + error = sopeeraddr(so, sa); #ifdef KTRACE - if (KTRPOINT(td, KTR_STRUCT)) - ktrsockaddr(*sa); + if (error == 0 && KTRPOINT(td, KTR_STRUCT)) + ktrsockaddr(sa); #endif -bad: - if (error != 0 && *sa != NULL) { - free(*sa, M_SONAME); - *sa = NULL; - } done: fdrop(fp, td); return (error); diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 3071a5169b72..069294e1c963 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -436,33 +436,6 @@ uipc_abort(struct socket *so) UNP_PCB_UNLOCK(unp); } -static int -uipc_accept(struct socket *so, struct sockaddr *ret) -{ - struct unpcb *unp, *unp2; - const struct sockaddr *sa; - - /* - * Pass back name of connected socket, if it was bound and we are - * still connected (our peer may have closed already!). - */ - unp = sotounpcb(so); - KASSERT(unp != NULL, ("uipc_accept: unp == NULL")); - - 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, ret, sa->sa_len); - if (unp2 != NULL) - unp_pcb_unlock_pair(unp, unp2); - else - UNP_PCB_UNLOCK(unp); - return (0); -} - static int uipc_attach(struct socket *so, int proto, struct thread *td) { @@ -874,7 +847,7 @@ uipc_listen(struct socket *so, int backlog, struct thread *td) } static int -uipc_peeraddr(struct socket *so, struct sockaddr **nam) +uipc_peeraddr(struct socket *so, struct sockaddr *ret) { struct unpcb *unp, *unp2; const struct sockaddr *sa; @@ -882,8 +855,6 @@ uipc_peeraddr(struct socket *so, struct sockaddr **nam) unp = sotounpcb(so); KASSERT(unp != NULL, ("uipc_peeraddr: 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) { @@ -891,12 +862,12 @@ uipc_peeraddr(struct socket *so, struct sockaddr **nam) sa = (struct sockaddr *)unp2->unp_addr; else sa = &sun_noname; - bcopy(sa, *nam, sa->sa_len); + bcopy(sa, ret, sa->sa_len); unp_pcb_unlock_pair(unp, unp2); } else { - sa = &sun_noname; - bcopy(sa, *nam, sa->sa_len); UNP_PCB_UNLOCK(unp); + sa = &sun_noname; + bcopy(sa, ret, sa->sa_len); } return (0); } @@ -1704,7 +1675,7 @@ uipc_shutdown(struct socket *so) } static int -uipc_sockaddr(struct socket *so, struct sockaddr **nam) +uipc_sockaddr(struct socket *so, struct sockaddr *ret) { struct unpcb *unp; const struct sockaddr *sa; @@ -1712,13 +1683,12 @@ uipc_sockaddr(struct socket *so, struct sockaddr **nam) unp = sotounpcb(so); KASSERT(unp != NULL, ("uipc_sockaddr: unp == NULL")); - *nam = malloc(sizeof(struct sockaddr_un), M_SONAME, M_WAITOK); UNP_PCB_LOCK(unp); if (unp->unp_addr != NULL) sa = (struct sockaddr *) unp->unp_addr; else sa = &sun_noname; - bcopy(sa, *nam, sa->sa_len); + bcopy(sa, ret, sa->sa_len); UNP_PCB_UNLOCK(unp); return (0); } @@ -3322,7 +3292,7 @@ static struct protosw streamproto = { PR_CAPATTACH, .pr_ctloutput = &uipc_ctloutput, .pr_abort = uipc_abort, - .pr_accept = uipc_accept, + .pr_accept = uipc_peeraddr, .pr_attach = uipc_attach, .pr_bind = uipc_bind, .pr_bindat = uipc_bindat, @@ -3349,7 +3319,7 @@ static struct protosw dgramproto = { PR_SOCKBUF, .pr_ctloutput = &uipc_ctloutput, .pr_abort = uipc_abort, - .pr_accept = uipc_accept, + .pr_accept = uipc_peeraddr, .pr_attach = uipc_attach, .pr_bind = uipc_bind, .pr_bindat = uipc_bindat, @@ -3378,7 +3348,7 @@ static struct protosw seqpacketproto = { PR_WANTRCVD|PR_RIGHTS|PR_CAPATTACH, .pr_ctloutput = &uipc_ctloutput, .pr_abort = uipc_abort, - .pr_accept = uipc_accept, + .pr_accept = uipc_peeraddr, .pr_attach = uipc_attach, .pr_bind = uipc_bind, .pr_bindat = uipc_bindat, diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c index 1b5d419fe58b..fb9596069101 100644 --- a/sys/net/if_ovpn.c +++ b/sys/net/if_ovpn.c @@ -508,7 +508,6 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) struct sockaddr_storage remote; struct ovpn_kpeer *peer = NULL; struct file *fp = NULL; - struct sockaddr *name = NULL; struct ovpn_softc *sc = ifp->if_softc; struct thread *td = curthread; struct socket *so = NULL; @@ -574,23 +573,21 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) callout_init_rm(&peer->ping_send, &sc->lock, CALLOUT_SHAREDLOCK); callout_init_rm(&peer->ping_rcv, &sc->lock, 0); - ret = so->so_proto->pr_sockaddr(so, &name); + peer->local.ss_len = sizeof(peer->local); + ret = sosockaddr(so, (struct sockaddr *)&peer->local); if (ret) goto error; - if (ovpn_get_port((struct sockaddr_storage *)name) == 0) { + if (ovpn_get_port(&peer->local) == 0) { ret = EINVAL; goto error; } - if (name->sa_family != remote.ss_family) { + if (peer->local.ss_family != remote.ss_family) { ret = EINVAL; goto error; } - memcpy(&peer->local, name, name->sa_len); memcpy(&peer->remote, &remote, sizeof(remote)); - free(name, M_SONAME); - name = NULL; if (peer->local.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&TO_IN6(&peer->remote)->sin6_addr)) { @@ -656,7 +653,6 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl) error_locked: OVPN_WUNLOCK(sc); error: - free(name, M_SONAME); COUNTER_ARRAY_FREE(peer->counters, OVPN_PEER_COUNTER_SIZE); uma_zfree_pcpu(pcpu_zone_4, peer->last_active); free(peer, M_OVPN); diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_hci_raw.h b/sys/netgraph/bluetooth/include/ng_btsocket_hci_raw.h index 05c109df1570..b55c95b29ee3 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_hci_raw.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_hci_raw.h @@ -78,11 +78,10 @@ int ng_btsocket_hci_raw_control (struct socket *, u_long, void *, int ng_btsocket_hci_raw_ctloutput (struct socket *, struct sockopt *); void ng_btsocket_hci_raw_detach (struct socket *); int ng_btsocket_hci_raw_disconnect (struct socket *); -int ng_btsocket_hci_raw_peeraddr (struct socket *, struct sockaddr **); int ng_btsocket_hci_raw_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); -int ng_btsocket_hci_raw_sockaddr (struct socket *, struct sockaddr **); +int ng_btsocket_hci_raw_sockaddr (struct socket *, struct sockaddr *); #endif /* _KERNEL */ diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h index b512112f8b7d..7181e369119d 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_l2cap.h @@ -105,11 +105,11 @@ int ng_btsocket_l2cap_raw_control (struct socket *, u_long, void *, struct ifnet *, struct thread *); void ng_btsocket_l2cap_raw_detach (struct socket *); int ng_btsocket_l2cap_raw_disconnect (struct socket *); -int ng_btsocket_l2cap_raw_peeraddr (struct socket *, struct sockaddr **); +int ng_btsocket_l2cap_raw_peeraddr (struct socket *, struct sockaddr *); int ng_btsocket_l2cap_raw_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); -int ng_btsocket_l2cap_raw_sockaddr (struct socket *, struct sockaddr **); +int ng_btsocket_l2cap_raw_sockaddr (struct socket *, struct sockaddr *); #endif /* _KERNEL */ @@ -191,7 +191,6 @@ 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_attach (struct socket *, int, struct thread *); int ng_btsocket_l2cap_bind (struct socket *, struct sockaddr *, struct thread *); @@ -203,11 +202,11 @@ int ng_btsocket_l2cap_ctloutput (struct socket *, struct sockopt *); void ng_btsocket_l2cap_detach (struct socket *); int ng_btsocket_l2cap_disconnect (struct socket *); int ng_btsocket_l2cap_listen (struct socket *, int, struct thread *); -int ng_btsocket_l2cap_peeraddr (struct socket *, struct sockaddr **); +int ng_btsocket_l2cap_peeraddr (struct socket *, struct sockaddr *); int ng_btsocket_l2cap_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); -int ng_btsocket_l2cap_sockaddr (struct socket *, struct sockaddr **); +int ng_btsocket_l2cap_sockaddr (struct socket *, struct sockaddr *); #endif /* _KERNEL */ diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h index d40b694ece14..a5448ed943a2 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h @@ -328,11 +328,11 @@ int ng_btsocket_rfcomm_ctloutput (struct socket *, struct sockopt *); void ng_btsocket_rfcomm_detach (struct socket *); int ng_btsocket_rfcomm_disconnect (struct socket *); int ng_btsocket_rfcomm_listen (struct socket *, int, struct thread *); -int ng_btsocket_rfcomm_peeraddr (struct socket *, struct sockaddr **); +int ng_btsocket_rfcomm_peeraddr (struct socket *, struct sockaddr *); int ng_btsocket_rfcomm_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); -int ng_btsocket_rfcomm_sockaddr (struct socket *, struct sockaddr **); +int ng_btsocket_rfcomm_sockaddr (struct socket *, struct sockaddr *); #endif /* _KERNEL */ diff --git a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h index 282980cce881..4b131dab4223 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket_sco.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket_sco.h @@ -118,11 +118,11 @@ int ng_btsocket_sco_ctloutput (struct socket *, struct sockopt *); void ng_btsocket_sco_detach (struct socket *); int ng_btsocket_sco_disconnect (struct socket *); int ng_btsocket_sco_listen (struct socket *, int, struct thread *); -int ng_btsocket_sco_peeraddr (struct socket *, struct sockaddr **); +int ng_btsocket_sco_peeraddr (struct socket *, struct sockaddr *); int ng_btsocket_sco_send (struct socket *, int, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); -int ng_btsocket_sco_sockaddr (struct socket *, struct sockaddr **); +int ng_btsocket_sco_sockaddr (struct socket *, struct sockaddr *); #endif /* _KERNEL */ diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket.c b/sys/netgraph/bluetooth/socket/ng_btsocket.c index 03fa322e7775..a90256595911 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket.c @@ -79,7 +79,7 @@ static struct protosw ng_btsocket_hci_raw_protosw = { .pr_control = ng_btsocket_hci_raw_control, .pr_detach = ng_btsocket_hci_raw_detach, .pr_disconnect = ng_btsocket_hci_raw_disconnect, - .pr_peeraddr = ng_btsocket_hci_raw_peeraddr, + .pr_peeraddr = ng_btsocket_hci_raw_sockaddr, .pr_send = ng_btsocket_hci_raw_send, .pr_sockaddr = ng_btsocket_hci_raw_sockaddr, .pr_close = ng_btsocket_hci_raw_close, @@ -110,7 +110,7 @@ static struct protosw ng_btsocket_l2cap_protosw = { .pr_flags = PR_ATOMIC|PR_CONNREQUIRED, .pr_ctloutput = ng_btsocket_l2cap_ctloutput, .pr_abort = ng_btsocket_l2cap_abort, - .pr_accept = ng_btsocket_l2cap_accept, + .pr_accept = ng_btsocket_l2cap_peeraddr, .pr_attach = ng_btsocket_l2cap_attach, .pr_bind = ng_btsocket_l2cap_bind, .pr_connect = ng_btsocket_l2cap_connect, @@ -131,7 +131,7 @@ static struct protosw ng_btsocket_rfcomm_protosw = { .pr_flags = PR_CONNREQUIRED, .pr_ctloutput = ng_btsocket_rfcomm_ctloutput, .pr_abort = ng_btsocket_rfcomm_abort, - .pr_accept = ng_btsocket_rfcomm_accept, + .pr_accept = ng_btsocket_rfcomm_peeraddr, .pr_attach = ng_btsocket_rfcomm_attach, .pr_bind = ng_btsocket_rfcomm_bind, .pr_connect = ng_btsocket_rfcomm_connect, @@ -152,7 +152,7 @@ static struct protosw ng_btsocket_sco_protosw = { .pr_flags = PR_ATOMIC|PR_CONNREQUIRED, .pr_ctloutput = ng_btsocket_sco_ctloutput, .pr_abort = ng_btsocket_sco_abort, - .pr_accept = ng_btsocket_sco_accept, + .pr_accept = ng_btsocket_sco_peeraddr, .pr_attach = ng_btsocket_sco_attach, .pr_bind = ng_btsocket_sco_bind, .pr_connect = ng_btsocket_sco_connect, diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c b/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c index 935991696929..5d015b2eac6e 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c @@ -1556,16 +1556,6 @@ ng_btsocket_hci_raw_disconnect(struct socket *so) return (0); } /* ng_btsocket_hci_raw_disconnect */ -/* - * Get socket peer's address - */ - -int -ng_btsocket_hci_raw_peeraddr(struct socket *so, struct sockaddr **nam) -{ - return (ng_btsocket_hci_raw_sockaddr(so, nam)); -} /* ng_btsocket_hci_raw_peeraddr */ - /* * Send data */ @@ -1656,25 +1646,24 @@ drop: */ int -ng_btsocket_hci_raw_sockaddr(struct socket *so, struct sockaddr **nam) +ng_btsocket_hci_raw_sockaddr(struct socket *so, struct sockaddr *sa) { ng_btsocket_hci_raw_pcb_p pcb = so2hci_raw_pcb(so); - struct sockaddr_hci sa; + struct sockaddr_hci *hci = (struct sockaddr_hci *)sa; if (pcb == NULL) return (EINVAL); if (ng_btsocket_hci_raw_node == NULL) return (EINVAL); - bzero(&sa, sizeof(sa)); - sa.hci_len = sizeof(sa); - sa.hci_family = AF_BLUETOOTH; + *hci = (struct sockaddr_hci ){ + .hci_len = sizeof(struct sockaddr_hci), + .hci_family = AF_BLUETOOTH, + }; mtx_lock(&pcb->pcb_mtx); - strlcpy(sa.hci_node, pcb->addr.hci_node, sizeof(sa.hci_node)); + strlcpy(hci->hci_node, pcb->addr.hci_node, sizeof(hci->hci_node)); mtx_unlock(&pcb->pcb_mtx); - *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); - - return ((*nam == NULL)? ENOMEM : 0); -} /* ng_btsocket_hci_raw_sockaddr */ + return (0); +} diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c index d221cc34d36a..ae5405529667 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c @@ -2509,68 +2509,43 @@ out: *** 1566 LINES SKIPPED ***