aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/namespaces.c
diff options
context:
space:
mode:
authorJann Horn <jann@thejh.net>2016-01-20 18:00:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-20 20:09:18 -0500
commitcaaee6234d05a58c5b4d05e7bf766131b810a657 (patch)
tree6227530109dd91ab5447fbd2211f09bc636845a7 /fs/proc/namespaces.c
parent3dfb7d8cdbc7ea0c2970450e60818bb3eefbad69 (diff)
ptrace: use fsuid, fsgid, effective creds for fs access checks
By checking the effective credentials instead of the real UID / permitted capabilities, ensure that the calling process actually intended to use its credentials. To ensure that all ptrace checks use the correct caller credentials (e.g. in case out-of-tree code or newly added code omits the PTRACE_MODE_*CREDS flag), use two new flags and require one of them to be set. The problem was that when a privileged task had temporarily dropped its privileges, e.g. by calling setreuid(0, user_uid), with the intent to perform following syscalls with the credentials of a user, it still passed ptrace access checks that the user would not be able to pass. While an attacker should not be able to convince the privileged task to perform a ptrace() syscall, this is a problem because the ptrace access check is reused for things in procfs. In particular, the following somewhat interesting procfs entries only rely on ptrace access checks: /proc/$pid/stat - uses the check for determining whether pointers should be visible, useful for bypassing ASLR /proc/$pid/maps - also useful for bypassing ASLR /proc/$pid/cwd - useful for gaining access to restricted directories that contain files with lax permissions, e.g. in this scenario: lrwxrwxrwx root root /proc/13020/cwd -> /root/foobar drwx------ root root /root drwxr-xr-x root root /root/foobar -rw-r--r-- root root /root/foobar/secret Therefore, on a system where a root-owned mode 6755 binary changes its effective credentials as described and then dumps a user-specified file, this could be used by an attacker to reveal the memory layout of root's processes or reveal the contents of files he is not allowed to access (through /proc/$pid/cwd). [akpm@linux-foundation.org: fix warning] Signed-off-by: Jann Horn <jann@thejh.net> Acked-by: Kees Cook <keescook@chromium.org> Cc: Casey Schaufler <casey@schaufler-ca.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Morris <james.l.morris@oracle.com> Cc: "Serge E. Hallyn" <serge.hallyn@ubuntu.com> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Andy Lutomirski <luto@kernel.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Willy Tarreau <w@1wt.eu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc/namespaces.c')
-rw-r--r--fs/proc/namespaces.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 1dece8781f91..276f12431dbf 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -46,7 +46,7 @@ static const char *proc_ns_get_link(struct dentry *dentry,
46 if (!task) 46 if (!task)
47 return error; 47 return error;
48 48
49 if (ptrace_may_access(task, PTRACE_MODE_READ)) { 49 if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
50 error = ns_get_path(&ns_path, task, ns_ops); 50 error = ns_get_path(&ns_path, task, ns_ops);
51 if (!error) 51 if (!error)
52 nd_jump_link(&ns_path); 52 nd_jump_link(&ns_path);
@@ -67,7 +67,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
67 if (!task) 67 if (!task)
68 return res; 68 return res;
69 69
70 if (ptrace_may_access(task, PTRACE_MODE_READ)) { 70 if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
71 res = ns_get_name(name, sizeof(name), task, ns_ops); 71 res = ns_get_name(name, sizeof(name), task, ns_ops);
72 if (res >= 0) 72 if (res >= 0)
73 res = readlink_copy(buffer, buflen, name); 73 res = readlink_copy(buffer, buflen, name);