On 09/18/2016 11:05 AM, Jann Horn wrote: > This adds a new ptrace_may_access_noncurrent() method that > uses the supplied credentials instead of those of the > current task. (However, the current task may still be > inspected for auditing purposes, e.g. by the Smack LSM.) > > procfs used the caller's creds for a few ptrace_may_access() > checks at read() time, which made a confused deputy attack > by passing an FD to a procfs file to a setuid program > possible. Therefore, the following was a local userspace > ASLR bypass: > > rm -f /tmp/foobar > procmail <(echo 'DEFAULT=/tmp/foobar') </proc/1/stat > ( > echo 'obase=16' > cut -d' ' -f26-30,45-51 </tmp/foobar | tr ' ' '\n' > ) | bc > rm /tmp/foobar > > procmail is installed setuid root on Debian and read()s > data from stdin before dropping privs, so the > ptrace_may_access() check in the VFS read handler of > /proc/1/stat passes. Procmail then dumps the read data > to a user-accessible file (/tmp/foobar here). > > Signed-off-by: Jann Horn <jann@xxxxxxxxx> > --- > fs/proc/array.c | 3 +- > fs/proc/base.c | 63 ++++++++++++++++++++++++++++++++++------- > fs/proc/internal.h | 14 +++++++++ > include/linux/lsm_hooks.h | 3 +- > include/linux/ptrace.h | 5 ++++ > include/linux/security.h | 10 ++++--- > kernel/ptrace.c | 40 +++++++++++++++++++------- > security/apparmor/include/ipc.h | 2 +- > security/apparmor/ipc.c | 4 +-- > security/apparmor/lsm.c | 14 +++++++-- > security/commoncap.c | 8 +++--- > security/security.c | 5 ++-- > security/selinux/hooks.c | 4 +-- > security/smack/smack_lsm.c | 18 ++++++++---- > security/yama/yama_lsm.c | 9 ++++-- > 15 files changed, 150 insertions(+), 52 deletions(-) > > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index 13185a6..f9a0be7 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -2133,10 +2133,10 @@ static int selinux_binder_transfer_file(struct task_struct *from, > } > > static int selinux_ptrace_access_check(struct task_struct *child, > - unsigned int mode) > + unsigned int mode, const struct cred *cred) > { > if (mode & PTRACE_MODE_READ) { > - u32 sid = current_sid(); > + u32 sid = cred_sid(cred); > u32 csid = task_sid(child); > return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); > } For consistency, don't you also need to change the next line of code to use cred_has_perm() rather than current_has_perm()? -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html