aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2009-11-14 11:37:04 -0500
committerJiri Slaby <jirislaby@gmail.com>2010-07-16 03:48:47 -0400
commit86f162f4c75ceb6daf43165469eeeca1bc3d4639 (patch)
treebca0e9d28d636fbaefb1846bdb85d9b57708df11 /kernel/sys.c
parent1c1e618ddd15f69fd87ccea596769f78c8065504 (diff)
rlimits: do security check under task_lock
Do security_task_setrlimit under task_lock. Other tasks may change limits under our hands while we are checking limits inside the function. From now on, they can't. Note that all the security work is done under a spinlock here now. Security hooks count with that, they are called from interrupt context (like security_task_kill) and with spinlocks already held (e.g. capable->security_capable). Signed-off-by: Jiri Slaby <jslaby@suse.cz> Acked-by: James Morris <jmorris@namei.org> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 9dbcbbcce153..c762eebdebf7 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1277,7 +1277,7 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
1277 struct rlimit *new_rlim) 1277 struct rlimit *new_rlim)
1278{ 1278{
1279 struct rlimit *old_rlim; 1279 struct rlimit *old_rlim;
1280 int retval; 1280 int retval = 0;
1281 1281
1282 if (resource >= RLIM_NLIMITS) 1282 if (resource >= RLIM_NLIMITS)
1283 return -EINVAL; 1283 return -EINVAL;
@@ -1293,9 +1293,14 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
1293 goto out; 1293 goto out;
1294 } 1294 }
1295 1295
1296 retval = security_task_setrlimit(tsk->group_leader, resource, new_rlim); 1296 old_rlim = tsk->signal->rlim + resource;
1297 if (retval) 1297 task_lock(tsk->group_leader);
1298 goto out; 1298 if (new_rlim->rlim_max > old_rlim->rlim_max &&
1299 !capable(CAP_SYS_RESOURCE))
1300 retval = -EPERM;
1301 if (!retval)
1302 retval = security_task_setrlimit(tsk->group_leader, resource,
1303 new_rlim);
1299 1304
1300 if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) { 1305 if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
1301 /* 1306 /*
@@ -1307,12 +1312,7 @@ int do_setrlimit(struct task_struct *tsk, unsigned int resource,
1307 new_rlim->rlim_cur = 1; 1312 new_rlim->rlim_cur = 1;
1308 } 1313 }
1309 1314
1310 old_rlim = tsk->signal->rlim + resource; 1315 if (!retval)
1311 task_lock(tsk->group_leader);
1312 if (new_rlim->rlim_max > old_rlim->rlim_max &&
1313 !capable(CAP_SYS_RESOURCE))
1314 retval = -EPERM;
1315 else
1316 *old_rlim = *new_rlim; 1316 *old_rlim = *new_rlim;
1317 task_unlock(tsk->group_leader); 1317 task_unlock(tsk->group_leader);
1318 1318