diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 9bb7489ee645..0dc3158667a2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2906,6 +2906,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, | |||
2906 | * @q: the waitqueue | 2906 | * @q: the waitqueue |
2907 | * @mode: which threads | 2907 | * @mode: which threads |
2908 | * @nr_exclusive: how many wake-one or wake-many threads to wake up | 2908 | * @nr_exclusive: how many wake-one or wake-many threads to wake up |
2909 | * @key: is directly passed to the wakeup function | ||
2909 | */ | 2910 | */ |
2910 | void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, | 2911 | void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, |
2911 | int nr_exclusive, void *key) | 2912 | int nr_exclusive, void *key) |
@@ -2928,7 +2929,7 @@ void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode) | |||
2928 | } | 2929 | } |
2929 | 2930 | ||
2930 | /** | 2931 | /** |
2931 | * __wake_up - sync- wake up threads blocked on a waitqueue. | 2932 | * __wake_up_sync - wake up threads blocked on a waitqueue. |
2932 | * @q: the waitqueue | 2933 | * @q: the waitqueue |
2933 | * @mode: which threads | 2934 | * @mode: which threads |
2934 | * @nr_exclusive: how many wake-one or wake-many threads to wake up | 2935 | * @nr_exclusive: how many wake-one or wake-many threads to wake up |
@@ -3223,6 +3224,19 @@ out_unlock: | |||
3223 | 3224 | ||
3224 | EXPORT_SYMBOL(set_user_nice); | 3225 | EXPORT_SYMBOL(set_user_nice); |
3225 | 3226 | ||
3227 | /* | ||
3228 | * can_nice - check if a task can reduce its nice value | ||
3229 | * @p: task | ||
3230 | * @nice: nice value | ||
3231 | */ | ||
3232 | int can_nice(const task_t *p, const int nice) | ||
3233 | { | ||
3234 | /* convert nice value [19,-20] to rlimit style value [0,39] */ | ||
3235 | int nice_rlim = 19 - nice; | ||
3236 | return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || | ||
3237 | capable(CAP_SYS_NICE)); | ||
3238 | } | ||
3239 | |||
3226 | #ifdef __ARCH_WANT_SYS_NICE | 3240 | #ifdef __ARCH_WANT_SYS_NICE |
3227 | 3241 | ||
3228 | /* | 3242 | /* |
@@ -3242,12 +3256,8 @@ asmlinkage long sys_nice(int increment) | |||
3242 | * We don't have to worry. Conceptually one call occurs first | 3256 | * We don't have to worry. Conceptually one call occurs first |
3243 | * and we have a single winner. | 3257 | * and we have a single winner. |
3244 | */ | 3258 | */ |
3245 | if (increment < 0) { | 3259 | if (increment < -40) |
3246 | if (!capable(CAP_SYS_NICE)) | 3260 | increment = -40; |
3247 | return -EPERM; | ||
3248 | if (increment < -40) | ||
3249 | increment = -40; | ||
3250 | } | ||
3251 | if (increment > 40) | 3261 | if (increment > 40) |
3252 | increment = 40; | 3262 | increment = 40; |
3253 | 3263 | ||
@@ -3257,6 +3267,9 @@ asmlinkage long sys_nice(int increment) | |||
3257 | if (nice > 19) | 3267 | if (nice > 19) |
3258 | nice = 19; | 3268 | nice = 19; |
3259 | 3269 | ||
3270 | if (increment < 0 && !can_nice(current, nice)) | ||
3271 | return -EPERM; | ||
3272 | |||
3260 | retval = security_task_setnice(current, nice); | 3273 | retval = security_task_setnice(current, nice); |
3261 | if (retval) | 3274 | if (retval) |
3262 | return retval; | 3275 | return retval; |
@@ -3372,6 +3385,7 @@ recheck: | |||
3372 | return -EINVAL; | 3385 | return -EINVAL; |
3373 | 3386 | ||
3374 | if ((policy == SCHED_FIFO || policy == SCHED_RR) && | 3387 | if ((policy == SCHED_FIFO || policy == SCHED_RR) && |
3388 | param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur && | ||
3375 | !capable(CAP_SYS_NICE)) | 3389 | !capable(CAP_SYS_NICE)) |
3376 | return -EPERM; | 3390 | return -EPERM; |
3377 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 3391 | if ((current->euid != p->euid) && (current->euid != p->uid) && |