aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2022-04-26 16:35:57 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2022-06-17 19:34:04 +0000
commit92870cb499e3672f26fcf1ee16111b130b74c188 (patch)
tree506c0a367e3f042c7696edad612fa8cbe9b27537
parent2d05c4f018fa4514c3ee5391802ce9eadcc5e140 (diff)
downloadsrc-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.c17
-rw-r--r--sys/compat/linux/linux_signal.c37
-rw-r--r--sys/compat/linux/linux_signal.h1
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_ */