aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/capability.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2016-11-16 23:06:51 -0500
committerEric W. Biederman <ebiederm@xmission.com>2016-11-22 14:21:00 -0500
commitf84df2a6f268de584a201e8911384a2d244876e3 (patch)
tree09976911531fe57cff9299cd8687ae6d1c9b14ed /kernel/capability.c
parent84d77d3f06e7e8dea057d10e8ec77ad71f721be3 (diff)
exec: Ensure mm->user_ns contains the execed files
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. Cc: stable@vger.kernel.org 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>
Diffstat (limited to 'kernel/capability.c')
-rw-r--r--kernel/capability.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/kernel/capability.c b/kernel/capability.c
index dfa0e4528b0b..4984e1f552eb 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -457,6 +457,19 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns,
457EXPORT_SYMBOL(file_ns_capable); 457EXPORT_SYMBOL(file_ns_capable);
458 458
459/** 459/**
460 * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode?
461 * @ns: The user namespace in question
462 * @inode: The inode in question
463 *
464 * Return true if the inode uid and gid are within the namespace.
465 */
466bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode)
467{
468 return kuid_has_mapping(ns, inode->i_uid) &&
469 kgid_has_mapping(ns, inode->i_gid);
470}
471
472/**
460 * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped 473 * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
461 * @inode: The inode in question 474 * @inode: The inode in question
462 * @cap: The capability in question 475 * @cap: The capability in question
@@ -469,8 +482,7 @@ bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
469{ 482{
470 struct user_namespace *ns = current_user_ns(); 483 struct user_namespace *ns = current_user_ns();
471 484
472 return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) && 485 return ns_capable(ns, cap) && privileged_wrt_inode_uidgid(ns, inode);
473 kgid_has_mapping(ns, inode->i_gid);
474} 486}
475EXPORT_SYMBOL(capable_wrt_inode_uidgid); 487EXPORT_SYMBOL(capable_wrt_inode_uidgid);
476 488