aboutsummaryrefslogtreecommitdiff
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2016-07-14 11:20:55 -0700
committerAmit Pundir <amit.pundir@linaro.org>2016-08-18 18:56:03 +0530
commita819ad8088b54cd5f904a134d0775a1ad1f0246f (patch)
tree89272c3738c19d206f69ff0da60f3770fd2da585 /fs/proc/base.c
parent0e1b4ef27e57a8c3c9687c5c2da9dc773ab46672 (diff)
FROMLIST: 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. Cc: Kees Cook <keescook@chromium.org> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: Andrew Morton <akpm@linux-foundation.org> 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> Reviewed-by: Nick Kralevich <nnk@google.com> Acked-by: Serge Hallyn <serge@hallyn.com> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: John Stultz <john.stultz@linaro.org> FROMLIST URL: https://lkml.org/lkml/2016/7/21/522 Change-Id: Ia75481402e3948165a1b7c1551c539530cb25509 (Cherry picked against common/android-4.4) Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'fs/proc/base.c')
-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 67b6d7e2313f..f9600828c2e0 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2261,16 +2261,19 @@ static ssize_t timerslack_ns_write(struct file *file, const char __user *buf,
if (!p)
return -ESRCH;
- if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) {
- task_lock(p);
- if (slack_ns == 0)
- p->timer_slack_ns = p->default_timer_slack_ns;
- else
- p->timer_slack_ns = slack_ns;
- task_unlock(p);
- } else
+ if (!capable(CAP_SYS_NICE)) {
count = -EPERM;
+ goto out;
+ }
+
+ task_lock(p);
+ if (slack_ns == 0)
+ p->timer_slack_ns = p->default_timer_slack_ns;
+ else
+ p->timer_slack_ns = slack_ns;
+ task_unlock(p);
+out:
put_task_struct(p);
return count;
@@ -2280,19 +2283,22 @@ static int timerslack_ns_show(struct seq_file *m, void *v)
{
struct inode *inode = m->private;
struct task_struct *p;
- int err = 0;
+ int err = 0;
p = get_proc_task(inode);
if (!p)
return -ESRCH;
- if (ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS)) {
- task_lock(p);
- seq_printf(m, "%llu\n", p->timer_slack_ns);
- task_unlock(p);
- } else
+ if (!capable(CAP_SYS_NICE)) {
err = -EPERM;
+ goto out;
+ }
+ task_lock(p);
+ seq_printf(m, "%llu\n", p->timer_slack_ns);
+ task_unlock(p);
+
+out:
put_task_struct(p);
return err;