diff options
author | Dhaval Giani <dhaval@linux.vnet.ibm.com> | 2009-02-27 04:43:54 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-27 05:11:53 -0500 |
commit | 54e991242850edc8c53f71fa5aa3ba7a93ce38f5 (patch) | |
tree | 7f136214aab690a8ee4a294ca9c1a7e01de0dc49 /kernel/user.c | |
parent | cac64d00c256e65776d575e82aaf540632b66178 (diff) |
sched: don't allow setuid to succeed if the user does not have rt bandwidth
Impact: fix hung task with certain (non-default) rt-limit settings
Corey Hickey reported that on using setuid to change the uid of a
rt process, the process would be unkillable and not be running.
This is because there was no rt runtime for that user group. Add
in a check to see if a user can attach an rt task to its task group.
On failure, return EINVAL, which is also returned in
CONFIG_CGROUP_SCHED.
Reported-by: Corey Hickey <bugfood-ml@fatooh.org>
Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/user.c')
-rw-r--r-- | kernel/user.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/kernel/user.c b/kernel/user.c index 3551ac742395..6a9b696128c8 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
@@ -362,6 +362,24 @@ static void free_user(struct user_struct *up, unsigned long flags) | |||
362 | 362 | ||
363 | #endif | 363 | #endif |
364 | 364 | ||
365 | #if defined(CONFIG_RT_GROUP_SCHED) && defined(CONFIG_USER_SCHED) | ||
366 | /* | ||
367 | * We need to check if a setuid can take place. This function should be called | ||
368 | * before successfully completing the setuid. | ||
369 | */ | ||
370 | int task_can_switch_user(struct user_struct *up, struct task_struct *tsk) | ||
371 | { | ||
372 | |||
373 | return sched_rt_can_attach(up->tg, tsk); | ||
374 | |||
375 | } | ||
376 | #else | ||
377 | int task_can_switch_user(struct user_struct *up, struct task_struct *tsk) | ||
378 | { | ||
379 | return 1; | ||
380 | } | ||
381 | #endif | ||
382 | |||
365 | /* | 383 | /* |
366 | * Locate the user_struct for the passed UID. If found, take a ref on it. The | 384 | * Locate the user_struct for the passed UID. If found, take a ref on it. The |
367 | * caller must undo that ref with free_uid(). | 385 | * caller must undo that ref with free_uid(). |