[PATCH 5/6] compat: add set_maybe_compat_user_sigmask helper

From: Willem de Bruijn
Date: Mon Jan 11 2021 - 19:33:18 EST


From: Willem de Bruijn <willemb@xxxxxxxxxx>

Deduplicate the open coded branch on sigmask compat handling.

Signed-off-by: Willem de Bruijn <willemb@xxxxxxxxxx>
Cc: Jens Axboe <axboe@xxxxxxxxx>
---
fs/eventpoll.c | 5 +----
fs/io_uring.c | 9 +--------
fs/select.c | 10 ++--------
include/linux/compat.h | 10 ++++++++++
4 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index c9dcffba2da1..c011327c8402 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -2247,10 +2247,7 @@ static int do_epoll_pwait(int epfd, struct epoll_event __user *events,
* If the caller wants a certain signal mask to be set during the wait,
* we apply it here.
*/
- if (!in_compat_syscall())
- error = set_user_sigmask(sigmask, sigsetsize);
- else
- error = set_compat_user_sigmask(sigmask, sigsetsize);
+ error = set_maybe_compat_user_sigmask(sigmask, sigsetsize);
if (error)
return error;

diff --git a/fs/io_uring.c b/fs/io_uring.c
index fdc923e53873..abc88bc738ce 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -7190,14 +7190,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
} while (1);

if (sig) {
-#ifdef CONFIG_COMPAT
- if (in_compat_syscall())
- ret = set_compat_user_sigmask((const compat_sigset_t __user *)sig,
- sigsz);
- else
-#endif
- ret = set_user_sigmask(sig, sigsz);
-
+ ret = set_maybe_compat_user_sigmask(sig, sigsz);
if (ret)
return ret;
}
diff --git a/fs/select.c b/fs/select.c
index 27567795a892..c013662bbf51 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -773,10 +773,7 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
return -EINVAL;
}

- if (!in_compat_syscall())
- ret = set_user_sigmask(sigmask, sigsetsize);
- else
- ret = set_compat_user_sigmask(sigmask, sigsetsize);
+ ret = set_maybe_compat_user_sigmask(sigmask, sigsetsize);
if (ret)
return ret;

@@ -1146,10 +1143,7 @@ static int do_ppoll(struct pollfd __user *ufds, unsigned int nfds,
return -EINVAL;
}

- if (!in_compat_syscall())
- ret = set_user_sigmask(sigmask, sigsetsize);
- else
- ret = set_compat_user_sigmask(sigmask, sigsetsize);
+ ret = set_maybe_compat_user_sigmask(sigmask, sigsetsize);
if (ret)
return ret;

diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6e65be753603..4a9b740496b4 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -18,6 +18,7 @@
#include <linux/aio_abi.h> /* for aio_context_t */
#include <linux/uaccess.h>
#include <linux/unistd.h>
+#include <linux/sched/signal.h>

#include <asm/compat.h>

@@ -942,6 +943,15 @@ static inline bool in_compat_syscall(void) { return false; }

#endif /* CONFIG_COMPAT */

+static inline int set_maybe_compat_user_sigmask(const void __user *umask,
+ size_t sigsetsize)
+{
+ if (!in_compat_syscall())
+ return set_user_sigmask(umask, sigsetsize);
+ else
+ return set_compat_user_sigmask(umask, sigsetsize);
+}
+
/*
* Some legacy ABIs like the i386 one use less than natural alignment for 64-bit
* types, and will need special compat treatment for that. Most architectures
--
2.30.0.284.gd98b1dd5eaa7-goog