Skip to content

Commit

Permalink
osf_wait4: switch to kernel_wait4()
Browse files Browse the repository at this point in the history
... and sanitize copying rusage to userland

Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed May 21, 2017
1 parent 4c48abe commit 92ebce5
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 41 deletions.
53 changes: 14 additions & 39 deletions arch/alpha/kernel/osf_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/*
Expand Down
2 changes: 2 additions & 0 deletions include/linux/sched/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/sched.h>

struct task_struct;
struct rusage;
union thread_union;

/*
Expand Down Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1639,8 +1639,8 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
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;
Expand Down

0 comments on commit 92ebce5

Please sign in to comment.