Commit 36819ad0 authored by Deepa Dinamani's avatar Deepa Dinamani Committed by Al Viro

select: Use get/put_timespec64

Usage of these apis and their compat versions makes
the syscalls: select family of syscalls and their
compat implementations simpler.

This is a preparatory patch to isolate data conversions to
struct timespec64 at userspace boundaries. This helps contain
the changes needed to transition to new y2038 safe types.
Signed-off-by: default avatarDeepa Dinamani <deepa.kernel@gmail.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 176826af
...@@ -291,8 +291,7 @@ static int poll_select_copy_remaining(struct timespec64 *end_time, ...@@ -291,8 +291,7 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
void __user *p, void __user *p,
int timeval, int ret) int timeval, int ret)
{ {
struct timespec64 rts64; struct timespec64 rts;
struct timespec rts;
struct timeval rtv; struct timeval rtv;
if (!p) if (!p)
...@@ -305,23 +304,22 @@ static int poll_select_copy_remaining(struct timespec64 *end_time, ...@@ -305,23 +304,22 @@ static int poll_select_copy_remaining(struct timespec64 *end_time,
if (!end_time->tv_sec && !end_time->tv_nsec) if (!end_time->tv_sec && !end_time->tv_nsec)
return ret; return ret;
ktime_get_ts64(&rts64); ktime_get_ts64(&rts);
rts64 = timespec64_sub(*end_time, rts64); rts = timespec64_sub(*end_time, rts);
if (rts64.tv_sec < 0) if (rts.tv_sec < 0)
rts64.tv_sec = rts64.tv_nsec = 0; rts.tv_sec = rts.tv_nsec = 0;
rts = timespec64_to_timespec(rts64);
if (timeval) { if (timeval) {
if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec)) if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
memset(&rtv, 0, sizeof(rtv)); memset(&rtv, 0, sizeof(rtv));
rtv.tv_sec = rts64.tv_sec; rtv.tv_sec = rts.tv_sec;
rtv.tv_usec = rts64.tv_nsec / NSEC_PER_USEC; rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
if (!copy_to_user(p, &rtv, sizeof(rtv))) if (!copy_to_user(p, &rtv, sizeof(rtv)))
return ret; return ret;
} else if (!copy_to_user(p, &rts, sizeof(rts))) } else if (!put_timespec64(&rts, p))
return ret; return ret;
/* /*
...@@ -704,17 +702,15 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, ...@@ -704,17 +702,15 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
const sigset_t __user *sigmask, size_t sigsetsize) const sigset_t __user *sigmask, size_t sigsetsize)
{ {
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct timespec ts; struct timespec64 ts, end_time, *to = NULL;
struct timespec64 ts64, end_time, *to = NULL;
int ret; int ret;
if (tsp) { if (tsp) {
if (copy_from_user(&ts, tsp, sizeof(ts))) if (get_timespec64(&ts, tsp))
return -EFAULT; return -EFAULT;
ts64 = timespec_to_timespec64(ts);
to = &end_time; to = &end_time;
if (poll_select_set_timeout(to, ts64.tv_sec, ts64.tv_nsec)) if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
return -EINVAL; return -EINVAL;
} }
...@@ -1051,12 +1047,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, ...@@ -1051,12 +1047,11 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
size_t, sigsetsize) size_t, sigsetsize)
{ {
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct timespec ts; struct timespec64 ts, end_time, *to = NULL;
struct timespec64 end_time, *to = NULL;
int ret; int ret;
if (tsp) { if (tsp) {
if (copy_from_user(&ts, tsp, sizeof(ts))) if (get_timespec64(&ts, tsp))
return -EFAULT; return -EFAULT;
to = &end_time; to = &end_time;
...@@ -1102,10 +1097,10 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, ...@@ -1102,10 +1097,10 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t)) #define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
static static
int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, int compat_poll_select_copy_remaining(struct timespec64 *end_time, void __user *p,
int timeval, int ret) int timeval, int ret)
{ {
struct timespec ts; struct timespec64 ts;
if (!p) if (!p)
return ret; return ret;
...@@ -1117,8 +1112,8 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, ...@@ -1117,8 +1112,8 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
if (!end_time->tv_sec && !end_time->tv_nsec) if (!end_time->tv_sec && !end_time->tv_nsec)
return ret; return ret;
ktime_get_ts(&ts); ktime_get_ts64(&ts);
ts = timespec_sub(*end_time, ts); ts = timespec64_sub(*end_time, ts);
if (ts.tv_sec < 0) if (ts.tv_sec < 0)
ts.tv_sec = ts.tv_nsec = 0; ts.tv_sec = ts.tv_nsec = 0;
...@@ -1131,12 +1126,7 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p, ...@@ -1131,12 +1126,7 @@ int compat_poll_select_copy_remaining(struct timespec *end_time, void __user *p,
if (!copy_to_user(p, &rtv, sizeof(rtv))) if (!copy_to_user(p, &rtv, sizeof(rtv)))
return ret; return ret;
} else { } else {
struct compat_timespec rts; if (!compat_put_timespec64(&ts, p))
rts.tv_sec = ts.tv_sec;
rts.tv_nsec = ts.tv_nsec;
if (!copy_to_user(p, &rts, sizeof(rts)))
return ret; return ret;
} }
/* /*
...@@ -1194,7 +1184,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, ...@@ -1194,7 +1184,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
*/ */
static int compat_core_sys_select(int n, compat_ulong_t __user *inp, static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
compat_ulong_t __user *outp, compat_ulong_t __user *exp, compat_ulong_t __user *outp, compat_ulong_t __user *exp,
struct timespec *end_time) struct timespec64 *end_time)
{ {
fd_set_bits fds; fd_set_bits fds;
void *bits; void *bits;
...@@ -1267,7 +1257,7 @@ COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp, ...@@ -1267,7 +1257,7 @@ COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp, compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
struct compat_timeval __user *, tvp) struct compat_timeval __user *, tvp)
{ {
struct timespec end_time, *to = NULL; struct timespec64 end_time, *to = NULL;
struct compat_timeval tv; struct compat_timeval tv;
int ret; int ret;
...@@ -1313,12 +1303,11 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, ...@@ -1313,12 +1303,11 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
{ {
compat_sigset_t ss32; compat_sigset_t ss32;
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct compat_timespec ts; struct timespec64 ts, end_time, *to = NULL;
struct timespec end_time, *to = NULL;
int ret; int ret;
if (tsp) { if (tsp) {
if (copy_from_user(&ts, tsp, sizeof(ts))) if (compat_get_timespec64(&ts, tsp))
return -EFAULT; return -EFAULT;
to = &end_time; to = &end_time;
...@@ -1382,12 +1371,11 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, ...@@ -1382,12 +1371,11 @@ COMPAT_SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds,
{ {
compat_sigset_t ss32; compat_sigset_t ss32;
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct compat_timespec ts; struct timespec64 ts, end_time, *to = NULL;
struct timespec end_time, *to = NULL;
int ret; int ret;
if (tsp) { if (tsp) {
if (copy_from_user(&ts, tsp, sizeof(ts))) if (compat_get_timespec64(&ts, tsp))
return -EFAULT; return -EFAULT;
to = &end_time; to = &end_time;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment