aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2016-10-07 20:02:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 21:46:30 -0400
commit7abbaf94049914f074306d960b0f968ffe52e59f (patch)
tree8b0166be20e0400467cd7441783ba7b34b32985b /fs/proc
parente16e2d8e14a14bd87df8482c637dde8f760a8d5f (diff)
proc: relax /proc/<tid>/timerslack_ns capability requirements
When an interface to allow a task to change another tasks timerslack was first proposed, it was suggested that something greater then CAP_SYS_NICE would be needed, as a task could be delayed further then what normally could be done with nice adjustments. So CAP_SYS_PTRACE was adopted instead for what became the /proc/<tid>/timerslack_ns interface. However, for Android (where this feature originates), giving the system_server CAP_SYS_PTRACE would allow it to observe and modify all tasks memory. This is considered too high a privilege level for only needing to change the timerslack. After some discussion, it was realized that a CAP_SYS_NICE process can set a task as SCHED_FIFO, so they could fork some spinning processes and set them all SCHED_FIFO 99, in effect delaying all other tasks for an infinite amount of time. So as a CAP_SYS_NICE task can already cause trouble for other tasks, using it as a required capability for accessing and modifying /proc/<tid>/timerslack_ns seems sufficient. Thus, this patch loosens the capability requirements to CAP_SYS_NICE and removes CAP_SYS_PTRACE, simplifying some of the code flow as well. This is technically an ABI change, but as the feature just landed in 4.6, I suspect no one is yet using it. Link: http://lkml.kernel.org/r/1469132667-17377-1-git-send-email-john.stultz@linaro.org Signed-off-by: John Stultz <john.stultz@linaro.org> Reviewed-by: Nick Kralevich <nnk@google.com> Acked-by: Serge Hallyn <serge@hallyn.com> Acked-by: Kees Cook <keescook@chromium.org> Cc: Kees Cook <keescook@chromium.org> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Oren Laadan <orenl@cellrox.com> Cc: Ruchi Kandoi <kandoiruchi@google.com> Cc: Rom Lemarchand <romlem@android.com> Cc: Todd Kjos <tkjos@google.com> Cc: Colin Cross <ccross@android.com> Cc: Nick Kralevich <nnk@google.com> Cc: Dmitry Shmidt <dimitrysh@google.com> Cc: Elliott Hughes <enh@google.com> Cc: Android Kernel Team <kernel-team@android.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/base.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 3b792ab3c0dc..248f008d46b8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2280,16 +2280,19 @@ static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
2280 if (!p) 2280 if (!p)
2281 return -ESRCH; 2281 return -ESRCH;
2282 2282
2283 if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) { 2283 if (!capable(CAP_SYS_NICE)) {
2284 task_lock(p);
2285 if (slack_ns == 0)
2286 p->timer_slack_ns = p->default_timer_slack_ns;
2287 else
2288 p->timer_slack_ns = slack_ns;
2289 task_unlock(p);
2290 } else
2291 count = -EPERM; 2284 count = -EPERM;
2285 goto out;
2286 }
2292 2287
2288 task_lock(p);
2289 if (slack_ns == 0)
2290 p->timer_slack_ns = p->default_timer_slack_ns;
2291 else
2292 p->timer_slack_ns = slack_ns;
2293 task_unlock(p);
2294
2295out:
2293 put_task_struct(p); 2296 put_task_struct(p);
2294 2297
2295 return count; 2298 return count;
@@ -2299,19 +2302,22 @@ static int timerslack_ns_show(struct seq_file *m, void *v)
2299{ 2302{
2300 struct inode *inode = m->private; 2303 struct inode *inode = m->private;
2301 struct task_struct *p; 2304 struct task_struct *p;
2302 int err = 0; 2305 int err = 0;
2303 2306
2304 p = get_proc_task(inode); 2307 p = get_proc_task(inode);
2305 if (!p) 2308 if (!p)
2306 return -ESRCH; 2309 return -ESRCH;
2307 2310
2308 if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) { 2311 if (!capable(CAP_SYS_NICE)) {
2309 task_lock(p);
2310 seq_printf(m, "%llu\n", p->timer_slack_ns);
2311 task_unlock(p);
2312 } else
2313 err = -EPERM; 2312 err = -EPERM;
2313 goto out;
2314 }
2314 2315
2316 task_lock(p);
2317 seq_printf(m, "%llu\n", p->timer_slack_ns);
2318 task_unlock(p);
2319
2320out:
2315 put_task_struct(p); 2321 put_task_struct(p);
2316 2322
2317 return err; 2323 return err;