|
@@ -3223,6 +3223,19 @@ out_unlock:
|
|
|
|
|
|
EXPORT_SYMBOL(set_user_nice);
|
|
|
|
|
|
+/*
|
|
|
+ * can_nice - check if a task can reduce its nice value
|
|
|
+ * @p: task
|
|
|
+ * @nice: nice value
|
|
|
+ */
|
|
|
+int can_nice(const task_t *p, const int nice)
|
|
|
+{
|
|
|
+ /* convert nice value [19,-20] to rlimit style value [0,39] */
|
|
|
+ int nice_rlim = 19 - nice;
|
|
|
+ return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
|
|
|
+ capable(CAP_SYS_NICE));
|
|
|
+}
|
|
|
+
|
|
|
#ifdef __ARCH_WANT_SYS_NICE
|
|
|
|
|
|
/*
|
|
@@ -3242,12 +3255,8 @@ asmlinkage long sys_nice(int increment)
|
|
|
* We don't have to worry. Conceptually one call occurs first
|
|
|
* and we have a single winner.
|
|
|
*/
|
|
|
- if (increment < 0) {
|
|
|
- if (!capable(CAP_SYS_NICE))
|
|
|
- return -EPERM;
|
|
|
- if (increment < -40)
|
|
|
- increment = -40;
|
|
|
- }
|
|
|
+ if (increment < -40)
|
|
|
+ increment = -40;
|
|
|
if (increment > 40)
|
|
|
increment = 40;
|
|
|
|
|
@@ -3257,6 +3266,9 @@ asmlinkage long sys_nice(int increment)
|
|
|
if (nice > 19)
|
|
|
nice = 19;
|
|
|
|
|
|
+ if (increment < 0 && !can_nice(current, nice))
|
|
|
+ return -EPERM;
|
|
|
+
|
|
|
retval = security_task_setnice(current, nice);
|
|
|
if (retval)
|
|
|
return retval;
|
|
@@ -3372,6 +3384,7 @@ recheck:
|
|
|
return -EINVAL;
|
|
|
|
|
|
if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
|
|
|
+ param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur &&
|
|
|
!capable(CAP_SYS_NICE))
|
|
|
return -EPERM;
|
|
|
if ((current->euid != p->euid) && (current->euid != p->uid) &&
|