|
@@ -1272,6 +1272,7 @@ 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)
|
|
|
{
|
|
@@ -1285,9 +1286,16 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
|
|
|
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);
|
|
|
+ if (!tsk->sighand) {
|
|
|
+ retval = -ESRCH;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
retval = security_task_setrlimit(tsk->group_leader, resource, new_rlim);
|
|
|
if (retval)
|
|
|
- return retval;
|
|
|
+ goto out;
|
|
|
|
|
|
if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
|
|
|
/*
|
|
@@ -1322,6 +1330,7 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
|
|
|
|
|
|
update_rlimit_cpu(tsk, new_rlim->rlim_cur);
|
|
|
out:
|
|
|
+ read_unlock(&tasklist_lock);
|
|
|
return retval;
|
|
|
}
|
|
|
|