The branch main has been updated by dchagin:

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

commit 3923e632094a7e4cc66cd8e68964b9cb495119e2
Author:     Dmitry Chagin <dcha...@freebsd.org>
AuthorDate: 2022-04-26 16:35:57 +0000
Commit:     Dmitry Chagin <dcha...@freebsd.org>
CommitDate: 2022-04-26 16:35:57 +0000

    linux(4): Add copyin_sigset() helper.
    
    MFC after:      2 weeks
---
 sys/compat/linux/linux_event.c  | 17 ++++++-----------
 sys/compat/linux/linux_signal.c | 37 +++++++++++++++++++++++++------------
 sys/compat/linux/linux_signal.h |  1 +
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
index 4389e8daa0dd..52f7c58a4347 100644
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_event.h>
 #include <compat/linux/linux_file.h>
+#include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_timer.h>
 #include <compat/linux/linux_util.h>
 
@@ -523,19 +524,13 @@ int
 linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args)
 {
        sigset_t mask, *pmask;
-       l_sigset_t lmask;
        int error;
 
-       if (args->mask != NULL) {
-               if (args->sigsetsize != sizeof(l_sigset_t))
-                       return (EINVAL);
-               error = copyin(args->mask, &lmask, sizeof(l_sigset_t));
-               if (error != 0)
-                       return (error);
-               linux_to_bsd_sigset(&lmask, &mask);
-               pmask = &mask;
-       } else
-               pmask = NULL;
+       error = linux_copyin_sigset(args->mask, sizeof(l_sigset_t),
+           &mask, &pmask);
+       if (error != 0)
+               return (error);
+
        return (linux_epoll_wait_common(td, args->epfd, args->events,
            args->maxevents, args->timeout, pmask));
 }
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index c506edae0fc9..0848040d009c 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -458,17 +458,13 @@ linux_common_rt_sigtimedwait(struct thread *td, 
l_sigset_t *mask,
     struct timespec *tsa, l_siginfo_t *ptr, l_size_t sigsetsize)
 {
        int error, sig;
-       l_sigset_t lset;
        sigset_t bset;
        l_siginfo_t lsi;
        ksiginfo_t ksi;
 
-       if (sigsetsize != sizeof(l_sigset_t))
-               return (EINVAL);
-
-       if ((error = copyin(mask, &lset, sizeof(lset))))
+       error = linux_copyin_sigset(mask, sigsetsize, &bset, NULL);
+       if (error != 0)
                return (error);
-       linux_to_bsd_sigset(&lset, &bset);
 
        ksiginfo_init(&ksi);
        error = kern_sigtimedwait(td, bset, &ksi, tsa);
@@ -772,18 +768,14 @@ linux_rt_tgsigqueueinfo(struct thread *td, struct 
linux_rt_tgsigqueueinfo_args *
 int
 linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap)
 {
-       l_sigset_t lmask;
        sigset_t sigmask;
        int error;
 
-       if (uap->sigsetsize != sizeof(l_sigset_t))
-               return (EINVAL);
-
-       error = copyin(uap->newset, &lmask, sizeof(l_sigset_t));
+       error = linux_copyin_sigset(uap->newset, uap->sigsetsize,
+           &sigmask, NULL);
        if (error != 0)
                return (error);
 
-       linux_to_bsd_sigset(&lmask, &sigmask);
        return (kern_sigsuspend(td, sigmask));
 }
 
@@ -867,3 +859,24 @@ linux_psignal(struct thread *td, int pid, int sig)
        ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
        return (linux_pksignal(td, pid, sig, &ksi));
 }
+
+int
+linux_copyin_sigset(l_sigset_t *lset, l_size_t sigsetsize, sigset_t *set,
+    sigset_t **pset)
+{
+       l_sigset_t lmask;
+       int error;
+
+       if (sigsetsize != sizeof(l_sigset_t))
+               return (EINVAL);
+       if (lset != NULL) {
+               error = copyin(lset, &lmask, sizeof(l_sigset_t));
+               if (error != 0)
+                       return (error);
+               linux_to_bsd_sigset(&lmask, set);
+               if (pset != NULL)
+                       *pset = set;
+       } else if (pset != NULL)
+               *pset = NULL;
+       return (0);
+}
diff --git a/sys/compat/linux/linux_signal.h b/sys/compat/linux/linux_signal.h
index f434ab1b1b35..8d6022fc3cc7 100644
--- a/sys/compat/linux/linux_signal.h
+++ b/sys/compat/linux/linux_signal.h
@@ -47,5 +47,6 @@ int linux_do_sigaction(struct thread *, int, l_sigaction_t *, 
l_sigaction_t *);
 void siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig);
 int lsiginfo_to_siginfo(struct thread *td, const l_siginfo_t *lsi,
                siginfo_t *si, int sig);
+int linux_copyin_sigset(l_sigset_t *, l_size_t, sigset_t *, sigset_t **);
 
 #endif /* _LINUX_SIGNAL_H_ */

Reply via email to