]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
osf_wait4: switch to kernel_wait4()
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 15 May 2017 03:54:33 +0000 (23:54 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 21 May 2017 17:16:26 +0000 (13:16 -0400)
... and sanitize copying rusage to userland

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/alpha/kernel/osf_sys.c
include/linux/sched/task.h
kernel/exit.c

index ce93124a850be26520524579d30188e1ba5fcee6..b23d6fbbb2255aaeecbe576ecb308333ab637008 100644 (file)
@@ -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;
 }
 
 /*
index a978d7189cfddd3f83cc15b68dd187a65068e816..6b830fd9d809f4745e8b9b7ec3b76d0510f2b0bc 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/sched.h>
 
 struct task_struct;
+struct rusage;
 union thread_union;
 
 /*
@@ -74,6 +75,7 @@ extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *,
 extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *);
 struct task_struct *fork_idle(int);
 extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern long kernel_wait4(pid_t, int *, int, struct rusage *);
 
 extern void free_task(struct task_struct *tsk);
 
index f3b8c3a87bc197a4b4a8a494e8021f079ceb40c9..462fc25eec6e7ffe9b4bc33f80134c238b023fdb 100644 (file)
@@ -1639,8 +1639,8 @@ Efault:
        return -EFAULT;
 }
 
-static long kernel_wait4(pid_t upid, int __user *stat_addr,
-                       int options, struct rusage *ru)
+long kernel_wait4(pid_t upid, int __user *stat_addr, int options,
+                 struct rusage *ru)
 {
        struct wait_opts wo;
        struct pid *pid = NULL;