57 lines
1.6 KiB
Diff
57 lines
1.6 KiB
Diff
|
From a35547da680829ce9036a476678a5fd4bfa59a6b Mon Sep 17 00:00:00 2001
|
||
|
From: Jiri Slaby <jirislaby@gmail.com>
|
||
|
Date: Fri, 28 Aug 2009 14:08:17 +0200
|
||
|
Subject: [PATCH] core: allow setrlimit to non-current tasks
|
||
|
References: FATE#305733
|
||
|
Patch-mainline: no (later)
|
||
|
|
||
|
Add locking to allow setrlimit accept task parameter other than
|
||
|
current.
|
||
|
|
||
|
Namely, lock tasklist_lock for read and check whether the task
|
||
|
structure has sighand non-null. Do all the signal processing under
|
||
|
that lock still held.
|
||
|
|
||
|
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||
|
Cc: Oleg Nesterov <oleg@redhat.com>
|
||
|
---
|
||
|
kernel/sys.c | 11 ++++++++++-
|
||
|
1 file changed, 10 insertions(+), 1 deletion(-)
|
||
|
|
||
|
--- a/kernel/sys.c
|
||
|
+++ b/kernel/sys.c
|
||
|
@@ -1302,6 +1302,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned
|
||
|
|
||
|
#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)
|
||
|
{
|
||
|
@@ -1315,9 +1316,16 @@ int do_setrlimit(struct task_struct *tsk
|
||
|
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, resource, new_rlim);
|
||
|
if (retval)
|
||
|
- return retval;
|
||
|
+ goto out;
|
||
|
|
||
|
if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
|
||
|
/*
|
||
|
@@ -1352,6 +1360,7 @@ int do_setrlimit(struct task_struct *tsk
|
||
|
|
||
|
update_rlimit_cpu(tsk, new_rlim->rlim_cur);
|
||
|
out:
|
||
|
+ read_unlock(&tasklist_lock);
|
||
|
return retval;
|
||
|
}
|
||
|
|