aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2016-11-16 23:06:51 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-06 04:40:12 -0500
commit21245b8635e8636e9e01df06f33cf08f369322b7 (patch)
tree6fa28804e8942edc6f90d099d4d3cd129303710f /fs
parent0de98eef9c115ce0a23995d06bba32691297fbf8 (diff)
exec: Ensure mm->user_ns contains the execed files
commit f84df2a6f268de584a201e8911384a2d244876e3 upstream. When the user namespace support was merged the need to prevent ptrace from revealing the contents of an unreadable executable was overlooked. Correct this oversight by ensuring that the executed file or files are in mm->user_ns, by adjusting mm->user_ns. Use the new function privileged_wrt_inode_uidgid to see if the executable is a member of the user namespace, and as such if having CAP_SYS_PTRACE in the user namespace should allow tracing the executable. If not update mm->user_ns to the parent user namespace until an appropriate parent is found. Reported-by: Jann Horn <jann@thejh.net> Fixes: 9e4a36ece652 ("userns: Fail exec for suid and sgid binaries with ids outside our user namespace.") Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 4e497b9ee71e..669c09bfdcad 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1275,8 +1275,22 @@ EXPORT_SYMBOL(flush_old_exec);
1275 1275
1276void would_dump(struct linux_binprm *bprm, struct file *file) 1276void would_dump(struct linux_binprm *bprm, struct file *file)
1277{ 1277{
1278 if (inode_permission(file_inode(file), MAY_READ) < 0) 1278 struct inode *inode = file_inode(file);
1279 if (inode_permission(inode, MAY_READ) < 0) {
1280 struct user_namespace *old, *user_ns;
1279 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; 1281 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
1282
1283 /* Ensure mm->user_ns contains the executable */
1284 user_ns = old = bprm->mm->user_ns;
1285 while ((user_ns != &init_user_ns) &&
1286 !privileged_wrt_inode_uidgid(user_ns, inode))
1287 user_ns = user_ns->parent;
1288
1289 if (old != user_ns) {
1290 bprm->mm->user_ns = get_user_ns(user_ns);
1291 put_user_ns(old);
1292 }
1293 }
1280} 1294}
1281EXPORT_SYMBOL(would_dump); 1295EXPORT_SYMBOL(would_dump);
1282 1296
@@ -1306,7 +1320,6 @@ void setup_new_exec(struct linux_binprm * bprm)
1306 !gid_eq(bprm->cred->gid, current_egid())) { 1320 !gid_eq(bprm->cred->gid, current_egid())) {
1307 current->pdeath_signal = 0; 1321 current->pdeath_signal = 0;
1308 } else { 1322 } else {
1309 would_dump(bprm, bprm->file);
1310 if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) 1323 if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
1311 set_dumpable(current->mm, suid_dumpable); 1324 set_dumpable(current->mm, suid_dumpable);
1312 } 1325 }
@@ -1741,6 +1754,8 @@ static int do_execveat_common(int fd, struct filename *filename,
1741 if (retval < 0) 1754 if (retval < 0)
1742 goto out; 1755 goto out;
1743 1756
1757 would_dump(bprm, bprm->file);
1758
1744 retval = exec_binprm(bprm); 1759 retval = exec_binprm(bprm);
1745 if (retval < 0) 1760 if (retval < 0)
1746 goto out; 1761 goto out;