From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
To: linux-fsdevel@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk,
akpm@linux-foundation.org, willy@infradead.org, arnd@kernel.org,
Willem de Bruijn <willemb@google.com>
Subject: [PATCH 3/6] ppoll: deduplicate compat logic
Date: Mon, 11 Jan 2021 19:30:14 -0500 [thread overview]
Message-ID: <20210112003017.4010304-4-willemdebruijn.kernel@gmail.com> (raw)
In-Reply-To: <20210112003017.4010304-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemb@google.com>
Apply the same compat deduplication strategy to ppoll that was
previously applied to select and pselect.
Like pselect, ppoll has timespec and sigmask arguments, which have
compat variants. poll has neither, so is not modified.
Convert the ppoll syscall to a do_ppoll() helper that branches on
timespec and sigmask variants internally.
This allows calling the same implementation for all syscall variants:
standard, time32, compat, compat + time32.
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
fs/select.c | 91 ++++++++++++++++++-----------------------------------
1 file changed, 30 insertions(+), 61 deletions(-)
diff --git a/fs/select.c b/fs/select.c
index dee7dfc5217b..27567795a892 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -1120,28 +1120,48 @@ SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
return ret;
}
-SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
- struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
- size_t, sigsetsize)
+static int do_ppoll(struct pollfd __user *ufds, unsigned int nfds,
+ void __user *tsp, const void __user *sigmask,
+ size_t sigsetsize, enum poll_time_type type)
{
struct timespec64 ts, end_time, *to = NULL;
int ret;
if (tsp) {
- if (get_timespec64(&ts, tsp))
- return -EFAULT;
+ switch (type) {
+ case PT_TIMESPEC:
+ if (get_timespec64(&ts, tsp))
+ return -EFAULT;
+ break;
+ case PT_OLD_TIMESPEC:
+ if (get_old_timespec32(&ts, tsp))
+ return -EFAULT;
+ break;
+ default:
+ BUG();
+ }
to = &end_time;
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
return -EINVAL;
}
- ret = set_user_sigmask(sigmask, sigsetsize);
+ if (!in_compat_syscall())
+ ret = set_user_sigmask(sigmask, sigsetsize);
+ else
+ ret = set_compat_user_sigmask(sigmask, sigsetsize);
if (ret)
return ret;
ret = do_sys_poll(ufds, nfds, to);
- return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
+ return poll_select_finish(&end_time, tsp, type, ret);
+}
+
+SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
+ struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
+ size_t, sigsetsize)
+{
+ return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_TIMESPEC);
}
#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
@@ -1150,24 +1170,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
size_t, sigsetsize)
{
- struct timespec64 ts, end_time, *to = NULL;
- int ret;
-
- if (tsp) {
- if (get_old_timespec32(&ts, tsp))
- return -EFAULT;
-
- to = &end_time;
- if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
- return -EINVAL;
- }
-
- ret = set_user_sigmask(sigmask, sigsetsize);
- if (ret)
- return ret;
-
- ret = do_sys_poll(ufds, nfds, to);
- return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
+ return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_OLD_TIMESPEC);
}
#endif
@@ -1258,24 +1261,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
unsigned int, nfds, struct old_timespec32 __user *, tsp,
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
{
- struct timespec64 ts, end_time, *to = NULL;
- int ret;
-
- if (tsp) {
- if (get_old_timespec32(&ts, tsp))
- return -EFAULT;
-
- to = &end_time;
- if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
- return -EINVAL;
- }
-
- ret = set_compat_user_sigmask(sigmask, sigsetsize);
- if (ret)
- return ret;
-
- ret = do_sys_poll(ufds, nfds, to);
- return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
+ return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_OLD_TIMESPEC);
}
#endif
@@ -1284,24 +1270,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
unsigned int, nfds, struct __kernel_timespec __user *, tsp,
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
{
- struct timespec64 ts, end_time, *to = NULL;
- int ret;
-
- if (tsp) {
- if (get_timespec64(&ts, tsp))
- return -EFAULT;
-
- to = &end_time;
- if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
- return -EINVAL;
- }
-
- ret = set_compat_user_sigmask(sigmask, sigsetsize);
- if (ret)
- return ret;
-
- ret = do_sys_poll(ufds, nfds, to);
- return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
+ return do_ppoll(ufds, nfds, tsp, sigmask, sigsetsize, PT_TIMESPEC);
}
#endif
--
2.30.0.284.gd98b1dd5eaa7-goog
next prev parent reply other threads:[~2021-01-12 0:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-12 0:30 [PATCH 0/6] fs: deduplicate compat logic Willem de Bruijn
2021-01-12 0:30 ` [PATCH 1/6] selftests/filesystems: add initial select and poll selftest Willem de Bruijn
2021-01-12 0:30 ` [PATCH 2/6] select: deduplicate compat logic Willem de Bruijn
2021-01-12 0:30 ` Willem de Bruijn [this message]
2021-01-12 0:30 ` [PATCH 4/6] epoll: " Willem de Bruijn
2021-01-12 0:30 ` [PATCH 5/6] compat: add set_maybe_compat_user_sigmask helper Willem de Bruijn
2021-01-12 7:11 ` kernel test robot
2021-01-12 0:30 ` [PATCH 6/6] io_pgetevents: deduplicate compat logic Willem de Bruijn
2021-01-12 0:58 ` [PATCH 0/6] fs: " Al Viro
2021-01-12 1:16 ` Willem de Bruijn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210112003017.4010304-4-willemdebruijn.kernel@gmail.com \
--to=willemdebruijn.kernel@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=willemb@google.com \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).