On Tue, Aug 9, 2016 at 4:54 PM, John Stultz <john.stu...@linaro.org> wrote: > In changing from checking ptrace_may_access(p, PTRACE_MODE_ATTACH_FSCREDS) > to capable(CAP_SYS_NICE), I missed that ptrace_my_access succeeds > when p == current, but the CAP_SYS_NICE doesn't. > > Thus while the previous commit was intended to loosen the needed > privledges to modify a processes timerslack, it needlessly restricted > a task modifying its own timerslack via the proc/<tid>/timerslack_ns > (which is permitted also via the PR_SET_TIMERSLACK method). > > This patch corrects this by checking if p == current before checking > the CAP_SYS_NICE value. > > This patch applies on top of my two previous patches currently in -mm > > Cc: Kees Cook <keesc...@chromium.org> > Cc: "Serge E. Hallyn" <se...@hallyn.com> > Cc: Andrew Morton <a...@linux-foundation.org> > Cc: Thomas Gleixner <t...@linutronix.de> > CC: Arjan van de Ven <ar...@linux.intel.com> > Cc: Oren Laadan <or...@cellrox.com> > Cc: Ruchi Kandoi <kandoiru...@google.com> > Cc: Rom Lemarchand <rom...@android.com> > Cc: Todd Kjos <tk...@google.com> > Cc: Colin Cross <ccr...@android.com> > Cc: Nick Kralevich <n...@google.com> > Cc: Dmitry Shmidt <dimitr...@google.com> > Cc: Elliott Hughes <e...@google.com> > Cc: Android Kernel Team <kernel-t...@android.com> > Signed-off-by: John Stultz <john.stu...@linaro.org> > --- > fs/proc/base.c | 34 +++++++++++++++++++--------------- > 1 file changed, 19 insertions(+), 15 deletions(-) > > diff --git a/fs/proc/base.c b/fs/proc/base.c > index 02f8389..01c3c2d 100644 > --- a/fs/proc/base.c > +++ b/fs/proc/base.c > @@ -2281,15 +2281,17 @@ static ssize_t timerslack_ns_write(struct file *file, > const char __user *buf, > if (!p) > return -ESRCH; > > - if (!capable(CAP_SYS_NICE)) { > - count = -EPERM; > - goto out; > - } > + if (p != current) { > + if (!capable(CAP_SYS_NICE)) { > + count = -EPERM; > + goto out; > + } > > - err = security_task_setscheduler(p); > - if (err) { > - count = err; > - goto out; > + err = security_task_setscheduler(p); > + if (err) { > + count = err; > + goto out; > + } > }
This entirely bypasses LSM when p == current. Is that intended? -Kees > > task_lock(p); > @@ -2315,14 +2317,16 @@ static int timerslack_ns_show(struct seq_file *m, > void *v) > if (!p) > return -ESRCH; > > - if (!capable(CAP_SYS_NICE)) { > - err = -EPERM; > - goto out; > - } > + if (p != current) { > > - err = security_task_getscheduler(p); > - if (err) > - goto out; > + if (!capable(CAP_SYS_NICE)) { > + err = -EPERM; > + goto out; > + } > + err = security_task_getscheduler(p); > + if (err) > + goto out; > + } > > task_lock(p); > seq_printf(m, "%llu\n", p->timer_slack_ns); > -- > 1.9.1 > -- Kees Cook Nexus Security