The branch main has been updated by mjg:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3212ad15abde2bd40030c7818672fd488da548d1

commit 3212ad15abde2bd40030c7818672fd488da548d1
Author:     Mateusz Guzik <m...@freebsd.org>
AuthorDate: 2022-09-07 15:41:55 +0000
Commit:     Mateusz Guzik <m...@freebsd.org>
CommitDate: 2022-09-10 19:47:47 +0000

    Add getsock
    
    All but one consumers of getsock_cap only pass 4 arguments.
    Take advantage of it.
---
 sys/compat/linux/linux_socket.c | 29 ++++++++++----------------
 sys/kern/kern_sendfile.c        |  3 +--
 sys/kern/uipc_syscalls.c        | 46 ++++++++++++++++++++++++-----------------
 sys/net/if_ovpn.c               |  4 +---
 sys/netinet/sctp_syscalls.c     | 13 ++++++------
 sys/sys/socketvar.h             |  2 ++
 6 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 9434e40709bb..fa9c39673fee 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -970,7 +970,6 @@ linux_connect(struct thread *td, struct linux_connect_args 
*args)
        struct socket *so;
        struct sockaddr *sa;
        struct file *fp;
-       u_int fflag;
        int error;
 
        error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa,
@@ -988,14 +987,13 @@ linux_connect(struct thread *td, struct 
linux_connect_args *args)
         * when on a non-blocking socket. Instead it returns the
         * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
         */
-       error = getsock_cap(td, args->s, &cap_connect_rights,
-           &fp, &fflag, NULL);
+       error = getsock(td, args->s, &cap_connect_rights, &fp);
        if (error != 0)
                return (error);
 
        error = EISCONN;
        so = fp->f_data;
-       if (fflag & FNONBLOCK) {
+       if (atomic_load_int(&fp->f_flag) & FNONBLOCK) {
                SOCK_LOCK(so);
                if (so->so_emuldata == 0)
                        error = so->so_error;
@@ -1058,7 +1056,7 @@ linux_accept_common(struct thread *td, int s, l_uintptr_t 
addr,
                                error = EINVAL;
                        break;
                case EINVAL:
-                       error1 = getsock_cap(td, s, &cap_accept_rights, &fp1, 
NULL, NULL);
+                       error1 = getsock(td, s, &cap_accept_rights, &fp1);
                        if (error1 != 0) {
                                error = error1;
                                break;
@@ -1207,7 +1205,7 @@ linux_send(struct thread *td, struct linux_send_args 
*args)
                int tolen;
        } */ bsd_args;
        struct file *fp;
-       int error, fflag;
+       int error;
 
        bsd_args.s = args->s;
        bsd_args.buf = (caddr_t)PTRIN(args->msg);
@@ -1221,10 +1219,9 @@ linux_send(struct thread *td, struct linux_send_args 
*args)
                 * Linux doesn't return ENOTCONN for non-blocking sockets.
                 * Instead it returns the EAGAIN.
                 */
-               error = getsock_cap(td, args->s, &cap_send_rights, &fp,
-                   &fflag, NULL);
+               error = getsock(td, args->s, &cap_send_rights, &fp);
                if (error == 0) {
-                       if (fflag & FNONBLOCK)
+                       if (atomic_load_int(&fp->f_flag) & FNONBLOCK)
                                error = EAGAIN;
                        fdrop(fp, td);
                }
@@ -1275,8 +1272,7 @@ linux_sendto(struct thread *td, struct linux_sendto_args 
*args)
                return (linux_sendto_hdrincl(td, args));
 
        bzero(&msg, sizeof(msg));
-       error = getsock_cap(td, args->s, &cap_send_connect_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, args->s, &cap_send_connect_rights, &fp);
        if (error != 0)
                return (error);
        so = fp->f_data;
@@ -1366,7 +1362,7 @@ linux_sendmsg_common(struct thread *td, l_int s, struct 
l_msghdr *msghdr,
        void *data;
        l_size_t len;
        l_size_t clen;
-       int error, fflag;
+       int error;
 
        error = copyin(msghdr, &linux_msghdr, sizeof(linux_msghdr));
        if (error != 0)
@@ -1409,8 +1405,7 @@ linux_sendmsg_common(struct thread *td, l_int s, struct 
l_msghdr *msghdr,
                if (sa_family == AF_UNIX)
                        goto bad;
 
-               error = getsock_cap(td, s, &cap_send_rights, &fp,
-                   &fflag, NULL);
+               error = getsock(td, s, &cap_send_rights, &fp);
                if (error != 0)
                        goto bad;
                so = fp->f_data;
@@ -1908,8 +1903,7 @@ linux_recvmsg(struct thread *td, struct 
linux_recvmsg_args *args)
        struct file *fp;
        int error;
 
-       error = getsock_cap(td, args->s, &cap_recv_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, args->s, &cap_recv_rights, &fp);
        if (error != 0)
                return (error);
        fdrop(fp, td);
@@ -1927,8 +1921,7 @@ linux_recvmmsg_common(struct thread *td, l_int s, struct 
l_mmsghdr *msg,
        l_uint retval;
        int error, datagrams;
 
-       error = getsock_cap(td, s, &cap_recv_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, s, &cap_recv_rights, &fp);
        if (error != 0)
                return (error);
        datagrams = 0;
diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
index f444e38e153d..96f95e4c841f 100644
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -653,8 +653,7 @@ sendfile_getsock(struct thread *td, int s, struct file 
**sock_fp,
        /*
         * The socket must be a stream socket and connected.
         */
-       error = getsock_cap(td, s, &cap_send_rights,
-           sock_fp, NULL, NULL);
+       error = getsock(td, s, &cap_send_rights, sock_fp);
        if (error != 0)
                return (error);
        *so = (*sock_fp)->f_data;
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index e77475992d0b..c269bd09f139 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -110,6 +110,23 @@ getsock_cap(struct thread *td, int fd, cap_rights_t 
*rightsp,
        return (0);
 }
 
+int
+getsock(struct thread *td, int fd, cap_rights_t *rightsp, struct file **fpp)
+{
+       struct file *fp;
+       int error;
+
+       error = fget_unlocked(td, fd, rightsp, &fp);
+       if (__predict_false(error != 0))
+               return (error);
+       if (__predict_false(fp->f_type != DTYPE_SOCKET)) {
+               fdrop(fp, td);
+               return (ENOTSOCK);
+       }
+       *fpp = fp;
+       return (0);
+}
+
 /*
  * System call interface to the socket abstraction.
  */
@@ -194,8 +211,7 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct 
sockaddr *sa)
 
        AUDIT_ARG_FD(fd);
        AUDIT_ARG_SOCKADDR(td, dirfd, sa);
-       error = getsock_cap(td, fd, &cap_bind_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, fd, &cap_bind_rights, &fp);
        if (error != 0)
                return (error);
        so = fp->f_data;
@@ -247,8 +263,7 @@ kern_listen(struct thread *td, int s, int backlog)
        int error;
 
        AUDIT_ARG_FD(s);
-       error = getsock_cap(td, s, &cap_listen_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, s, &cap_listen_rights, &fp);
        if (error == 0) {
                so = fp->f_data;
 #ifdef MAC
@@ -491,8 +506,7 @@ kern_connectat(struct thread *td, int dirfd, int fd, struct 
sockaddr *sa)
 
        AUDIT_ARG_FD(fd);
        AUDIT_ARG_SOCKADDR(td, dirfd, sa);
-       error = getsock_cap(td, fd, &cap_connect_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, fd, &cap_connect_rights, &fp);
        if (error != 0)
                return (error);
        so = fp->f_data;
@@ -738,7 +752,7 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, 
int flags,
                AUDIT_ARG_SOCKADDR(td, AT_FDCWD, mp->msg_name);
                rights = &cap_send_connect_rights;
        }
-       error = getsock_cap(td, s, rights, &fp, NULL, NULL);
+       error = getsock(td, s, rights, &fp);
        if (error != 0) {
                m_freem(control);
                return (error);
@@ -916,8 +930,7 @@ kern_recvit(struct thread *td, int s, struct msghdr *mp, 
enum uio_seg fromseg,
                *controlp = NULL;
 
        AUDIT_ARG_FD(s);
-       error = getsock_cap(td, s, &cap_recv_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, s, &cap_recv_rights, &fp);
        if (error != 0)
                return (error);
        so = fp->f_data;
@@ -1205,8 +1218,7 @@ kern_shutdown(struct thread *td, int s, int how)
        int error;
 
        AUDIT_ARG_FD(s);
-       error = getsock_cap(td, s, &cap_shutdown_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, s, &cap_shutdown_rights, &fp);
        if (error == 0) {
                so = fp->f_data;
                error = soshutdown(so, how);
@@ -1263,8 +1275,7 @@ kern_setsockopt(struct thread *td, int s, int level, int 
name, const void *val,
        }
 
        AUDIT_ARG_FD(s);
-       error = getsock_cap(td, s, &cap_setsockopt_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, s, &cap_setsockopt_rights, &fp);
        if (error == 0) {
                so = fp->f_data;
                error = sosetopt(so, &sopt);
@@ -1328,8 +1339,7 @@ kern_getsockopt(struct thread *td, int s, int level, int 
name, void *val,
        }
 
        AUDIT_ARG_FD(s);
-       error = getsock_cap(td, s, &cap_getsockopt_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, s, &cap_getsockopt_rights, &fp);
        if (error == 0) {
                so = fp->f_data;
                error = sogetopt(so, &sopt);
@@ -1378,8 +1388,7 @@ kern_getsockname(struct thread *td, int fd, struct 
sockaddr **sa,
        int error;
 
        AUDIT_ARG_FD(fd);
-       error = getsock_cap(td, fd, &cap_getsockname_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, fd, &cap_getsockname_rights, &fp);
        if (error != 0)
                return (error);
        so = fp->f_data;
@@ -1460,8 +1469,7 @@ kern_getpeername(struct thread *td, int fd, struct 
sockaddr **sa,
        int error;
 
        AUDIT_ARG_FD(fd);
-       error = getsock_cap(td, fd, &cap_getpeername_rights,
-           &fp, NULL, NULL);
+       error = getsock(td, fd, &cap_getpeername_rights, &fp);
        if (error != 0)
                return (error);
        so = fp->f_data;
diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index a90c11c1dcbf..9e0829d996ce 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -449,7 +449,6 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
        struct ovpn_softc *sc = ifp->if_softc;
        struct thread *td = curthread;
        struct socket *so = NULL;
-       u_int fflag;
        int fd;
        uint32_t peerid;
        int ret = 0, i;
@@ -476,8 +475,7 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
        fd = nvlist_get_number(nvl, "fd");
 
        /* Look up the userspace process and use the fd to find the socket. */
-       ret = getsock_cap(td, fd, &cap_connect_rights, &fp,
-           &fflag, NULL);
+       ret = getsock(td, fd, &cap_connect_rights, &fp);
        if (ret != 0)
                return (ret);
 
diff --git a/sys/netinet/sctp_syscalls.c b/sys/netinet/sctp_syscalls.c
index 2697d139300c..a58ba9c231f3 100644
--- a/sys/netinet/sctp_syscalls.c
+++ b/sys/netinet/sctp_syscalls.c
@@ -153,10 +153,11 @@ sys_sctp_peeloff(td, uap)
        int error, fd;
 
        AUDIT_ARG_FD(uap->sd);
-       error = getsock_cap(td, uap->sd, cap_rights_init_one(&rights, 
CAP_PEELOFF),
-           &headfp, &fflag, NULL);
+       error = getsock(td, uap->sd, cap_rights_init_one(&rights, CAP_PEELOFF),
+           &headfp);
        if (error != 0)
                goto done2;
+       fflag = atomic_load_int(&fp->f_flag);
        head = headfp->f_data;
        if (head->so_proto->pr_protocol != IPPROTO_SCTP) {
                error = EOPNOTSUPP;
@@ -252,7 +253,7 @@ sys_sctp_generic_sendmsg (td, uap)
        }
 
        AUDIT_ARG_FD(uap->sd);
-       error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL);
+       error = getsock(td, uap->sd, &rights, &fp);
        if (error != 0)
                goto sctp_bad;
 #ifdef KTRACE
@@ -361,7 +362,7 @@ sys_sctp_generic_sendmsg_iov(td, uap)
        }
 
        AUDIT_ARG_FD(uap->sd);
-       error = getsock_cap(td, uap->sd, &rights, &fp, NULL, NULL);
+       error = getsock(td, uap->sd, &rights, &fp);
        if (error != 0)
                goto sctp_bad1;
 
@@ -472,8 +473,8 @@ sys_sctp_generic_recvmsg(td, uap)
        int error, fromlen, i, msg_flags;
 
        AUDIT_ARG_FD(uap->sd);
-       error = getsock_cap(td, uap->sd, cap_rights_init_one(&rights, CAP_RECV),
-           &fp, NULL, NULL);
+       error = getsock(td, uap->sd, cap_rights_init_one(&rights, CAP_RECV),
+           &fp);
        if (error != 0)
                return (error);
 #ifdef COMPAT_FREEBSD32
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 0c60b9e13cf2..101c6f3f4513 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -450,6 +450,8 @@ int getsockaddr(struct sockaddr **namp, const struct 
sockaddr *uaddr,
            size_t len);
 int    getsock_cap(struct thread *td, int fd, cap_rights_t *rightsp,
            struct file **fpp, u_int *fflagp, struct filecaps *havecaps);
+int    getsock(struct thread *td, int fd, cap_rights_t *rightsp,
+           struct file **fpp);
 void   soabort(struct socket *so);
 int    soaccept(struct socket *so, struct sockaddr **nam);
 void   soaio_enqueue(struct task *task);

Reply via email to