Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207830
b: refs/heads/master
c: 5b41535
h: refs/heads/master
v: v3
  • Loading branch information
Jiri Slaby authored and Jiri Slaby committed Jul 16, 2010
1 parent 7b724c2 commit e791450
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6a1d5e2c85d06da35cdfd93f1a27675bfdc3ad8c
refs/heads/master: 5b41535aac0c07135ff6a4c5c2ae115d1c20c0bc
4 changes: 2 additions & 2 deletions trunk/include/linux/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ struct rlimit64 {
struct task_struct;

int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
int do_setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim);
int do_prlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim, struct rlimit *old_rlim);

#endif /* __KERNEL__ */

Expand Down
71 changes: 37 additions & 34 deletions trunk/kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -1273,18 +1273,21 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
#endif

/* make sure you are allowed to change @tsk limits before calling this */
int do_setrlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim)
int do_prlimit(struct task_struct *tsk, unsigned int resource,
struct rlimit *new_rlim, struct rlimit *old_rlim)
{
struct rlimit *old_rlim;
struct rlimit *rlim;
int retval = 0;

if (resource >= RLIM_NLIMITS)
return -EINVAL;
if (new_rlim->rlim_cur > new_rlim->rlim_max)
return -EINVAL;
if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
return -EPERM;
if (new_rlim) {
if (new_rlim->rlim_cur > new_rlim->rlim_max)
return -EINVAL;
if (resource == RLIMIT_NOFILE &&
new_rlim->rlim_max > sysctl_nr_open)
return -EPERM;
}

/* protect tsk->signal and tsk->sighand from disappearing */
read_lock(&tasklist_lock);
Expand All @@ -1293,42 +1296,42 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
goto out;
}

old_rlim = tsk->signal->rlim + resource;
rlim = tsk->signal->rlim + resource;
task_lock(tsk->group_leader);
if (new_rlim->rlim_max > old_rlim->rlim_max &&
!capable(CAP_SYS_RESOURCE))
retval = -EPERM;
if (!retval)
retval = security_task_setrlimit(tsk->group_leader, resource,
new_rlim);

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;
if (new_rlim) {
if (new_rlim->rlim_max > rlim->rlim_max &&
!capable(CAP_SYS_RESOURCE))
retval = -EPERM;
if (!retval)
retval = security_task_setrlimit(tsk->group_leader,
resource, new_rlim);
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;
}
}
if (!retval) {
if (old_rlim)
*old_rlim = *rlim;
if (new_rlim)
*rlim = *new_rlim;
}

if (!retval)
*old_rlim = *new_rlim;
task_unlock(tsk->group_leader);

if (retval || resource != RLIMIT_CPU)
goto out;

/*
* RLIMIT_CPU handling. Note that the kernel fails to return an error
* code if it rejected the user's attempt to set RLIMIT_CPU. This is a
* very long-standing error, and fixing it now risks breakage of
* applications, so we live with it
*/
if (new_rlim->rlim_cur == RLIM_INFINITY)
goto out;

update_rlimit_cpu(tsk, new_rlim->rlim_cur);
if (!retval && new_rlim && resource == RLIMIT_CPU &&
new_rlim->rlim_cur != RLIM_INFINITY)
update_rlimit_cpu(tsk, new_rlim->rlim_cur);
out:
read_unlock(&tasklist_lock);
return retval;
Expand All @@ -1340,7 +1343,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)

if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
return -EFAULT;
return do_setrlimit(current, resource, &new_rlim);
return do_prlimit(current, resource, &new_rlim, NULL);
}

/*
Expand Down

0 comments on commit e791450

Please sign in to comment.