The branch main has been updated by dchagin:

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

commit e884512ad143952f0dbacad631487ce28363fd08
Author:     Dmitry Chagin <[email protected]>
AuthorDate: 2021-06-10 12:11:25 +0000
Commit:     Dmitry Chagin <[email protected]>
CommitDate: 2021-06-10 12:11:25 +0000

    Split kern_poll() on two counterparts.
    
    The kern_poll_kfds() operates on clear kernel data, kfds points to an
    array in the kernel, while kern_poll() operates on user supplied pollfd.
    Move nfds check to kern_poll_maxfds().
    
    No functional changes, it's for future use in the Linux emulation layer.
    
    Reviewd by:             kib
    Differential Revision:  https://reviews.freebsd.org/D30690
    MFC after:              2 weeks
---
 sys/kern/sys_generic.c | 83 +++++++++++++++++++++++++++++---------------------
 sys/sys/syscallsubr.h  |  3 ++
 2 files changed, 52 insertions(+), 34 deletions(-)

diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 6fcdee7a088f..c89a643cfcf9 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1417,12 +1417,13 @@ sys_poll(struct thread *td, struct poll_args *uap)
        return (kern_poll(td, uap->fds, uap->nfds, tsp, NULL));
 }
 
+/*
+ * kfds points to an array in the kernel.
+ */
 int
-kern_poll(struct thread *td, struct pollfd *ufds, u_int nfds,
+kern_poll_kfds(struct thread *td, struct pollfd *kfds, u_int nfds,
     struct timespec *tsp, sigset_t *uset)
 {
-       struct pollfd *kfds;
-       struct pollfd stackfds[32];
        sbintime_t sbt, precision, tmp;
        time_t over;
        struct timespec ts;
@@ -1453,28 +1454,11 @@ kern_poll(struct thread *td, struct pollfd *ufds, u_int 
nfds,
        } else
                sbt = -1;
 
-       /*
-        * This is kinda bogus.  We have fd limits, but that is not
-        * really related to the size of the pollfd array.  Make sure
-        * we let the process use at least FD_SETSIZE entries and at
-        * least enough for the system-wide limits.  We want to be reasonably
-        * safe, but not overly restrictive.
-        */
-       if (nfds > maxfilesperproc && nfds > FD_SETSIZE) 
-               return (EINVAL);
-       if (nfds > nitems(stackfds))
-               kfds = mallocarray(nfds, sizeof(*kfds), M_TEMP, M_WAITOK);
-       else
-               kfds = stackfds;
-       error = copyin(ufds, kfds, nfds * sizeof(*kfds));
-       if (error)
-               goto done;
-
        if (uset != NULL) {
                error = kern_sigprocmask(td, SIG_SETMASK, uset,
                    &td->td_oldsigmask, 0);
                if (error)
-                       goto done;
+                       return (error);
                td->td_pflags |= TDP_OLDMASK;
                /*
                 * Make sure that ast() is called on return to
@@ -1501,20 +1485,11 @@ kern_poll(struct thread *td, struct pollfd *ufds, u_int 
nfds,
        }
        seltdclear(td);
 
-done:
        /* poll is not restarted after signals... */
        if (error == ERESTART)
                error = EINTR;
        if (error == EWOULDBLOCK)
                error = 0;
-       if (error == 0) {
-               error = pollout(td, kfds, ufds, nfds);
-               if (error)
-                       goto out;
-       }
-out:
-       if (nfds > nitems(stackfds))
-               free(kfds, M_TEMP);
        return (error);
 }
 
@@ -1539,12 +1514,52 @@ sys_ppoll(struct thread *td, struct ppoll_args *uap)
                ssp = &set;
        } else
                ssp = NULL;
+       return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
+}
+
+/*
+ * ufds points to an array in user space.
+ */
+int
+kern_poll(struct thread *td, struct pollfd *ufds, u_int nfds,
+    struct timespec *tsp, sigset_t *set)
+{
+       struct pollfd *kfds;
+       struct pollfd stackfds[32];
+       int error;
+
+       if (kern_poll_maxfds(nfds))
+               return (EINVAL);
+       if (nfds > nitems(stackfds))
+               kfds = mallocarray(nfds, sizeof(*kfds), M_TEMP, M_WAITOK);
+       else
+               kfds = stackfds;
+       error = copyin(ufds, kfds, nfds * sizeof(*kfds));
+       if (error != 0)
+               goto out;
+
+       error = kern_poll_kfds(td, kfds, nfds, tsp, set);
+       if (error == 0)
+               error = pollout(td, kfds, ufds, nfds);
+
+out:
+       if (nfds > nitems(stackfds))
+               free(kfds, M_TEMP);
+       return (error);
+}
+
+bool
+kern_poll_maxfds(u_int nfds)
+{
+
        /*
-        * fds is still a pointer to user space. kern_poll() will
-        * take care of copyin that array to the kernel space.
+        * This is kinda bogus.  We have fd limits, but that is not
+        * really related to the size of the pollfd array.  Make sure
+        * we let the process use at least FD_SETSIZE entries and at
+        * least enough for the system-wide limits.  We want to be reasonably
+        * safe, but not overly restrictive.
         */
-
-       return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
+       return (nfds > maxfilesperproc && nfds > FD_SETSIZE);
 }
 
 static int
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 471c38ab0e12..eb7b82946988 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -225,6 +225,9 @@ int kern_pipe(struct thread *td, int fildes[2], int flags,
            struct filecaps *fcaps1, struct filecaps *fcaps2);
 int    kern_poll(struct thread *td, struct pollfd *fds, u_int nfds,
            struct timespec *tsp, sigset_t *uset);
+int    kern_poll_kfds(struct thread *td, struct pollfd *fds, u_int nfds,
+           struct timespec *tsp, sigset_t *uset);
+bool   kern_poll_maxfds(u_int nfds);
 int    kern_posix_error(struct thread *td, int error);
 int    kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len,
            int advice);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to