aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/osf_sys.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-05-14 23:54:33 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-05-21 13:16:26 -0400
commit92ebce5ac55dba258c608248dddf59eca3f7f514 (patch)
treeb795de1179e0055275b6e6b5cd1e09d0c31010f6 /arch/alpha/kernel/osf_sys.c
parentwaitid(): switch copyout of siginfo to unsafe_put_user() (diff)
downloadlinux-dev-92ebce5ac55dba258c608248dddf59eca3f7f514.tar.xz
linux-dev-92ebce5ac55dba258c608248dddf59eca3f7f514.zip
osf_wait4: switch to kernel_wait4()
... and sanitize copying rusage to userland Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to '')
-rw-r--r--arch/alpha/kernel/osf_sys.c53
1 files changed, 14 insertions, 39 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ce93124a850b..b23d6fbbb225 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1183,48 +1183,23 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru)
SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
struct rusage32 __user *, ur)
{
- struct rusage r;
- long ret, err;
unsigned int status = 0;
- mm_segment_t old_fs;
-
+ struct rusage r;
+ long err = kernel_wait4(pid, &status, options, &r);
+ if (err <= 0)
+ return err;
+ if (put_user(status, ustatus))
+ return -EFAULT;
if (!ur)
- return sys_wait4(pid, ustatus, options, NULL);
-
- old_fs = get_fs();
-
- set_fs (KERNEL_DS);
- ret = sys_wait4(pid, (unsigned int __user *) &status, options,
- (struct rusage __user *) &r);
- set_fs (old_fs);
-
- if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
+ return err;
+ if (put_tv32(&ur->ru_utime, &r.ru_utime))
return -EFAULT;
-
- err = put_user(status, ustatus);
- if (ret < 0)
- return err ? err : ret;
-
- err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
- err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
- err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
- err |= __put_user(r.ru_stime.tv_usec, &ur->ru_stime.tv_usec);
- err |= __put_user(r.ru_maxrss, &ur->ru_maxrss);
- err |= __put_user(r.ru_ixrss, &ur->ru_ixrss);
- err |= __put_user(r.ru_idrss, &ur->ru_idrss);
- err |= __put_user(r.ru_isrss, &ur->ru_isrss);
- err |= __put_user(r.ru_minflt, &ur->ru_minflt);
- err |= __put_user(r.ru_majflt, &ur->ru_majflt);
- err |= __put_user(r.ru_nswap, &ur->ru_nswap);
- err |= __put_user(r.ru_inblock, &ur->ru_inblock);
- err |= __put_user(r.ru_oublock, &ur->ru_oublock);
- err |= __put_user(r.ru_msgsnd, &ur->ru_msgsnd);
- err |= __put_user(r.ru_msgrcv, &ur->ru_msgrcv);
- err |= __put_user(r.ru_nsignals, &ur->ru_nsignals);
- err |= __put_user(r.ru_nvcsw, &ur->ru_nvcsw);
- err |= __put_user(r.ru_nivcsw, &ur->ru_nivcsw);
-
- return err ? err : ret;
+ if (put_tv32(&ur->ru_stime, &r.ru_stime))
+ return -EFAULT;
+ if (copy_to_user(&ur->ru_maxrss, &r.ru_maxrss,
+ sizeof(struct rusage32) - offsetof(struct rusage32, ru_maxrss)))
+ return -EFAULT;
+ return err;
}
/*