restructure sys_setrlimit
RFC PATCH 3/3 restructure sys_setrlimit
Signed-off-by Hirofumi Nakagawa <[email protected]>
--- include/linux/resource.h | 2 + kernel/sys.c | 56 ++++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 24 deletions(-)
kernel/sys.c +32 -24
@@ -1457,42 +1457,37 @@ asmlinkage long sys_old_getrlimit(unsign#endif -asmlinkage long sys_setrlimit (unsigned int resource,struct rlimit __user *rlim) +long __setrlimit (struct task_struct *tsk,unsigned int resource, +struct rlimit *new_rlim) { -struct rlimit new_rlim, *old_rlim; +struct rlimit *old_rlim;unsigned long it_prof_secs;int retval; -if (resource >=RLIM_NLIMITS ) -return -EINVAL ; -if (copy_from_user (&new_rlim, rlim,sizeof (*rlim))) -return -EFAULT ; -if (new_rlim.rlim_cur > new_rlim.rlim_max) -return -EINVAL ; - old_rlim = current->signal->rlim + resource; -if ((new_rlim.rlim_max > old_rlim->rlim_max) && + old_rlim = tsk->signal->rlim + resource; +if ((new_rlim->rlim_max > old_rlim->rlim_max) && !capable (CAP_SYS_RESOURCE ))return -EPERM ; -if (resource ==RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) +if (resource ==RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)return -EPERM ; - retval =security_task_setrlimit (resource, &new_rlim); + retval =security_task_setrlimit (resource, new_rlim);if (retval)return retval; -if (resource ==RLIMIT_CPU && new_rlim.rlim_cur ==0 ) { +if (resource ==RLIMIT_CPU && new_rlim->rlim_cur ==0 ) {/* * The caller is asking for an immediate RLIMIT_CPU * expiry. But we use the zero value to mean "it was * never set". So let's cheat and make it one second * instead */ - new_rlim.rlim_cur =1 ; + new_rlim->rlim_cur =1 ; } -task_lock (current->group_leader); - *old_rlim = new_rlim; -task_unlock (current->group_leader); +task_lock (tsk->group_leader); + *old_rlim = *new_rlim; +task_unlock (tsk->group_leader);if (resource !=RLIMIT_CPU ) goto out;
@@ -1503,25 +1498,38 @@ asmlinkage long sys_setrlimit(unsigned i* very long-standing error, and fixing it now risks breakage of * applications, so we live with it */ -if (new_rlim.rlim_cur ==RLIM_INFINITY ) +if (new_rlim->rlim_cur ==RLIM_INFINITY ) goto out; - it_prof_secs =cputime_to_secs (current->signal->it_prof_expires); -if (it_prof_secs ==0 || new_rlim.rlim_cur <= it_prof_secs) { -unsigned long rlim_cur = new_rlim.rlim_cur; + it_prof_secs =cputime_to_secs (tsk->signal->it_prof_expires); +if (it_prof_secs ==0 || new_rlim->rlim_cur <= it_prof_secs) { +unsigned long rlim_cur = new_rlim->rlim_cur;cputime_t cputime; cputime =secs_to_cputime (rlim_cur);read_lock (&tasklist_lock); -spin_lock_irq (¤t->sighand->siglock); -set_process_cpu_timer (current,CPUCLOCK_PROF , &cputime,NULL ); -spin_unlock_irq (¤t->sighand->siglock); +spin_lock_irq (&tsk->sighand->siglock); +set_process_cpu_timer (tsk,CPUCLOCK_PROF , &cputime,NULL ); +spin_unlock_irq (&tsk->sighand->siglock);read_unlock (&tasklist_lock); } out:return 0 ; } +asmlinkage long sys_setrlimit (unsigned int resource,struct rlimit __user *rlim) +{ +struct rlimit new_rlim; + +if (resource >=RLIM_NLIMITS ) +return -EINVAL ; +if (copy_from_user (&new_rlim, rlim,sizeof (*rlim))) +return -EFAULT ; +if (new_rlim.rlim_cur > new_rlim.rlim_max) +return -EINVAL ; +return __setrlimit (current, resource, &new_rlim); +} +/* * It would make sense to put struct rusage in the task_struct, * except that would make the task_struct be *really big*. After
include/linux/resource.h +2 -0
@@ -96,4 +96,6 @@ static const struct limit_names lnames[Rint getrusage (struct task_struct *p,int who,struct rusage __user *ru); +long __setrlimit (struct task_struct *tsk,unsigned int resource, +struct rlimit *new_rlim);#endif