diff options
author | Dmitry Chagin <dchagin@FreeBSD.org> | 2022-04-26 16:35:57 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2022-06-17 19:34:04 +0000 |
commit | 92870cb499e3672f26fcf1ee16111b130b74c188 (patch) | |
tree | 506c0a367e3f042c7696edad612fa8cbe9b27537 | |
parent | 2d05c4f018fa4514c3ee5391802ce9eadcc5e140 (diff) | |
download | src-92870cb499e3672f26fcf1ee16111b130b74c188.tar.gz src-92870cb499e3672f26fcf1ee16111b130b74c188.zip |
linux(4): Add copyin_sigset() helper.
MFC after: 2 weeks
(cherry picked from commit 3923e632094a7e4cc66cd8e68964b9cb495119e2)
-rw-r--r-- | sys/compat/linux/linux_event.c | 17 | ||||
-rw-r--r-- | sys/compat/linux/linux_signal.c | 37 | ||||
-rw-r--r-- | 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 661e68ce4289..c96159dcdfe3 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_ */ |