Home » Mailing lists » Devel » userns: targeted capabilities v5  
	
		
		
			| [PATCH 2/9] security: Make capabilities relative to the user namespace. [message #41744 is a reply to message #41743] | 
			Thu, 17 February 2011 15:03    | 
		 
		
			
				
				
				
					
						  
						serge
						 Messages: 72 Registered: January 2007 
						
					 | 
					Member  | 
					 | 
		 
		 
	 | 
 
	
		- Introduce ns_capable to test for a capability in a non-default 
  user namespace. 
- Teach cap_capable to handle capabilities in a non-default 
  user namespace. 
 
The motivation is to get to the unprivileged creation of new 
namespaces.  It looks like this gets us 90% of the way there, with 
only potential uid confusion issues left. 
 
I still need to handle getting all caps after creation but otherwise I 
think I have a good starter patch that achieves all of your goals. 
 
Changelog: 
	11/05/2010: [serge] add apparmor 
	12/14/2010: [serge] fix capabilities to created user namespaces 
	Without this, if user serge creates a user_ns, he won't have 
	capabilities to the user_ns he created.  THis is because we 
	were first checking whether his effective caps had the caps 
	he needed and returning -EPERM if not, and THEN checking whether 
	he was the creator.  Reverse those checks. 
	12/16/2010: [serge] security_real_capable needs ns argument in !security case 
	01/11/2011: [serge] add task_ns_capable helper 
	01/11/2011: [serge] add nsown_capable() helper per Bastian Blank suggestion 
	02/16/2011: [serge] fix a logic bug: the root user is always creator of 
		    init_user_ns, but should not always have capabilities to 
		    it!  Fix the check in cap_capable(). 
 
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> 
Signed-off-by: Serge E. Hallyn <serge.hallyn@canonical.com> 
--- 
 include/linux/capability.h |   10 ++++++++-- 
 include/linux/security.h   |   25 ++++++++++++++----------- 
 kernel/capability.c        |   32 ++++++++++++++++++++++++++++++-- 
 security/apparmor/lsm.c    |    5 +++-- 
 security/commoncap.c       |   40 +++++++++++++++++++++++++++++++++------- 
 security/security.c        |   16 ++++++++++------ 
 security/selinux/hooks.c   |   14 +++++++++----- 
 7 files changed, 107 insertions(+), 35 deletions(-) 
 
diff --git a/include/linux/capability.h b/include/linux/capability.h 
index fb16a36..cb3d2d9 100644 
--- a/include/linux/capability.h 
+++ b/include/linux/capability.h 
@@ -544,7 +544,7 @@ extern const kernel_cap_t __cap_init_eff_set; 
  * 
  * Note that this does not set PF_SUPERPRIV on the task. 
  */ 
-#define has_capability(t, cap) (security_real_capable((t), (cap)) == 0) 
+#define has_capability(t, cap) (security_real_capable((t), &init_user_ns, (cap)) == 0) 
  
 /** 
  * has_capability_noaudit - Determine if a task has a superior capability available (unaudited) 
@@ -558,9 +558,15 @@ extern const kernel_cap_t __cap_init_eff_set; 
  * Note that this does not set PF_SUPERPRIV on the task. 
  */ 
 #define has_capability_noaudit(t, cap) \ 
-	(security_real_capable_noaudit((t), (cap)) == 0) 
+	(security_real_capable_noaudit((t), &init_user_ns, (cap)) == 0) 
  
+struct user_namespace; 
+extern struct user_namespace init_user_ns; 
 extern int capable(int cap); 
+extern int ns_capable(struct user_namespace *ns, int cap); 
+extern int task_ns_capable(struct task_struct *t, int cap); 
+ 
+#define nsown_capable(cap) (ns_capable(current_user_ns(), (cap))) 
  
 /* audit system wants to get cap info from files as well */ 
 struct dentry; 
diff --git a/include/linux/security.h b/include/linux/security.h 
index b2b7f97..6bbee08 100644 
--- a/include/linux/security.h 
+++ b/include/linux/security.h 
@@ -46,13 +46,14 @@ 
  
 struct ctl_table; 
 struct audit_krule; 
+struct user_namespace; 
  
 /* 
  * These functions are in security/capability.c and are used 
  * as the default capabilities functions 
  */ 
 extern int cap_capable(struct task_struct *tsk, const struct cred *cred, 
-		       int cap, int audit); 
+		       struct user_namespace *ns, int cap, int audit); 
 extern int cap_settime(struct timespec *ts, struct timezone *tz); 
 extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); 
 extern int cap_ptrace_traceme(struct task_struct *parent); 
@@ -1254,6 +1255,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) 
  *	credentials. 
  *	@tsk contains the task_struct for the process. 
  *	@cred contains the credentials to use. 
+ *      @ns contains the user namespace we want the capability in 
  *	@cap contains the capability <include/linux/capability.h>. 
  *	@audit: Whether to write an audit message or not 
  *	Return 0 if the capability is granted for @tsk. 
@@ -1382,7 +1384,7 @@ struct security_operations { 
 		       const kernel_cap_t *inheritable, 
 		       const kernel_cap_t *permitted); 
 	int (*capable) (struct task_struct *tsk, const struct cred *cred, 
-			int cap, int audit); 
+			struct user_namespace *ns, int cap, int audit); 
 	int (*sysctl) (struct ctl_table *table, int op); 
 	int (*quotactl) (int cmds, int type, int id, struct super_block *sb); 
 	int (*quota_on) (struct dentry *dentry); 
@@ -1662,9 +1664,9 @@ int security_capset(struct cred *new, const struct cred *old, 
 		    const kernel_cap_t *effective, 
 		    const kernel_cap_t *inheritable, 
 		    const kernel_cap_t *permitted); 
-int security_capable(const struct cred *cred, int cap); 
-int security_real_capable(struct task_struct *tsk, int cap); 
-int security_real_capable_noaudit(struct task_struct *tsk, int cap); 
+int security_capable(struct user_namespace *ns, const struct cred *cred, int cap); 
+int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap); 
+int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace *ns, int cap); 
 int security_sysctl(struct ctl_table *table, int op); 
 int security_quotactl(int cmds, int type, int id, struct super_block *sb); 
 int security_quota_on(struct dentry *dentry); 
@@ -1856,28 +1858,29 @@ static inline int security_capset(struct cred *new, 
 	return cap_capset(new, old, effective, inheritable, permitted); 
 } 
  
-static inline int security_capable(const struct cred *cred, int cap) 
+static inline int security_capable(struct user_namespace *ns, 
+				   const struct cred *cred, int cap) 
 { 
-	return cap_capable(current, cred, cap, SECURITY_CAP_AUDIT); 
+	return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT); 
 } 
  
-static inline int security_real_capable(struct task_struct *tsk, int cap) 
+static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap) 
 { 
 	int ret; 
  
 	rcu_read_lock(); 
-	ret = cap_capable(tsk, __task_cred(tsk), cap, SECURITY_CAP_AUDIT); 
+	ret = cap_capable(tsk, __task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT); 
 	rcu_read_unlock(); 
 	return ret; 
 } 
  
 static inline 
-int security_real_capable_noaudit(struct task_struct *tsk, int cap) 
+int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace *ns, int cap) 
 { 
 	int ret; 
  
 	rcu_read_lock(); 
-	ret = cap_capable(tsk, __task_cred(tsk), cap, 
+	ret = cap_capable(tsk, __task_cred(tsk), ns, cap, 
 			       SECURITY_CAP_NOAUDIT); 
 	rcu_read_unlock(); 
 	return ret; 
diff --git a/kernel/capability.c b/kernel/capability.c 
index 9e9385f..916658c 100644 
--- a/kernel/capability.c 
+++ b/kernel/capability.c 
@@ -14,6 +14,7 @@ 
 #include <linux/security.h> 
 #include <linux/syscalls.h> 
 #include <linux/pid_namespace.h> 
+#include <linux/user_namespace.h> 
 #include <asm/uaccess.h> 
  
 /* 
@@ -301,15 +302,42 @@ error: 
  */ 
 int capable(int cap) 
 { 
+	return ns_capable(&init_user_ns, cap); 
+} 
+EXPORT_SYMBOL(capable); 
+ 
+/** 
+ * ns_capable - Determine if the current task has a superior capability in effect 
+ * @ns:  The usernamespace we want the capability in 
+ * @cap: The capability to be tested for 
+ * 
+ * Return true if the current task has the given superior capability currently 
+ * available for use, false if not. 
+ * 
+ * This sets PF_SUPERPRIV on the task if the capability is available on the 
+ * assumption that it's about to be used. 
+ */ 
+int ns_capable(struct user_namespace *ns, int cap) 
+{ 
 	if (unlikely(!cap_valid(cap))) { 
 		printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap); 
 		BUG(); 
 	} 
  
-	if (security_capable(current_cred(), cap) == 0) { 
+	if (security_capable(ns, current_cred(), cap) == 0) { 
 		current->flags |= PF_SUPERPRIV; 
 		return 1; 
 	} 
 	return 0; 
 } 
-EXPORT_SYMBOL(capable); 
+EXPORT_SYMBOL(ns_capable); 
+ 
+/* 
+ * does current have capability 'cap' to the user namespace of task 
+ * 't'.  Return true if it does, false otherwise. 
+ */ 
+int task_ns_capable(struct task_struct *t, int cap) 
+{ 
+	return ns_capable(task_cred_xxx(t, user)->user_ns, cap); 
+} 
+EXPORT_SYMBOL(task_ns_capable); 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c 
index b7106f1..b37c2cd 100644 
--- a/security/apparmor/lsm.c 
+++ b/security/apparmor/lsm.c 
@@ -22,6 +22,7 @@ 
 #include <linux/ctype.h> 
 #include <linux/sysctl.h> 
 #include <linux/audit.h> 
+#include <linux/user_namespace.h> 
 #include <net/sock.h> 
  
 #include "include/apparmor.h" 
@@ -136,11 +137,11 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, 
 } 
  
 static int apparmor_capable(struct task_struct *task, const struct cred *cred, 
-			    int cap, int audit) 
+			    struct user_namespace *ns, int cap, int audit) 
 { 
 	struct aa_profile *profile; 
 	/* cap_capable returns 0 on success, else -EPERM */ 
-	int error = cap_capable(task, cred, cap, audit); 
+	int error = cap_capable(task, cred, ns, cap, audit); 
 	if (!error) { 
 		profile = aa_cred_profile(cred); 
 		if (!unconfined(profile)) 
diff --git a/security/commoncap.c b/security/commoncap.c 
index 64c2ed9..51fa9ec 100644 
--- a/security/commoncap.c 
+++ b/security/commoncap.c 
@@ -27,6 +27,7 @@ 
 #include <linux/sched.h> 
 #include <linux/prctl.h> 
 #include <linux/securebits.h> 
+#include <linux/user_namespace.h> 
  
 /* 
  * If a non-root user executes a setuid-root binary in 
@@ -68,6 +69,7 @@ EXPORT_SYMBOL(cap_netlink_recv); 
  * cap_capable - Determine whether a task has a particular effective capability 
  * @tsk: The task to query 
  * @cred: The credentials to use 
+ * @ns:  The user namespace in which we need the capability 
  * @cap: The capability to check for 
  * @audit: Whether to write 
...
  
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
  
 
	
	  | 
	 | 
	
		userns: targeted capabilities v5
		By:  serge on Thu, 17 February 2011 15:02  
	 | 
 
	  | 
	 | 
	
		[PATCH 2/9] security: Make capabilities relative to the user namespace.
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		By:  ebiederm on Fri, 18 February 2011 03:46  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		By:  serge on Wed, 23 February 2011 13:43  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 2/9] security: Make capabilities relative to the user namespace.
		
	 | 
 
	  | 
	 | 
	
		[PATCH 9/9] userns: check user namespace for task->file uid equivalence checks
		By:  serge on Thu, 17 February 2011 15:04  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 9/9] userns: check user namespace for task->file uid equivalence checks
		By:  ebiederm on Fri, 18 February 2011 01:29  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 9/9] userns: check user namespace for task->file uid equivalence checks
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 9/9] userns: check user namespace for task->file uid equivalence checks
		By:  serge on Thu, 24 February 2011 03:24  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 9/9] userns: check user namespace for task->file uid equivalence checks
		By:  akpm on Thu, 24 February 2011 05:08  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 9/9] userns: check user namespace for task->file uid	equivalence checks
		
	 | 
 
	  | 
	 | 
	
		[PATCH 7/9] add a user namespace owner of ipc ns
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 7/9] add a user namespace owner of ipc ns
		By:  ebiederm on Fri, 18 February 2011 03:19  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 7/9] add a user namespace owner of ipc ns
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 7/9] add a user namespace owner of ipc ns
		
	 | 
 
	  | 
	 | 
	
		[PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		By:  serge on Thu, 17 February 2011 15:02  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		By:  ebiederm on Fri, 18 February 2011 03:31  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		By:  ebiederm on Wed, 23 February 2011 21:21  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 1/9] Add a user_namespace as creator/owner of uts_namespace
		By:  ebiederm on Wed, 23 February 2011 23:54  
	 | 
 
	  | 
	 | 
	
		[PATCH 3/9] allow sethostname in a container
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 3/9] allow sethostname in a container
		By:  ebiederm on Fri, 18 February 2011 03:05  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 3/9] allow sethostname in a container
		
	 | 
 
	  | 
	 | 
	
		[PATCH 4/9] allow killing tasks in your own or child userns
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 4/9] allow killing tasks in your own or child userns
		By:  ebiederm on Fri, 18 February 2011 03:00  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 4/9] allow killing tasks in your own or child userns
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 4/9] allow killing tasks in your own or child userns
		By:  serge on Thu, 24 February 2011 00:48  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 4/9] allow killing tasks in your own or child userns
		By:  akpm on Thu, 24 February 2011 00:54  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 4/9] allow killing tasks in your own or child userns
		
	 | 
 
	  | 
	 | 
	
		[PATCH 6/9] user namespaces: convert all capable checks in kernel/sys.c
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 6/9] user namespaces: convert all capable checks in kernel/sys.c
		By:  ebiederm on Fri, 18 February 2011 01:57  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 6/9] user namespaces: convert all capable checks in kernel/sys.c
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 6/9] user namespaces: convert all capable checks in kernel/sys.c
		By:  akpm on Sat, 19 February 2011 00:01  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 6/9] user namespaces: convert all capable checks in	kernel/sys.c
		
	 | 
 
	  | 
	 | 
	
		[PATCH 5/9] Allow ptrace from non-init user namespaces
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		By:  ebiederm on Fri, 18 February 2011 02:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		By:  serge on Fri, 18 February 2011 04:36  
	 | 
 
	  | 
	 | 
	
		[PATCH] userns: ptrace: incorporate feedback from Eric
		By:  serge on Thu, 24 February 2011 00:49  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH] userns: ptrace: incorporate feedback from Eric
		By:  akpm on Thu, 24 February 2011 00:56  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH] userns: ptrace: incorporate feedback from Eric
		By:  serge on Thu, 24 February 2011 03:15  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		By:  akpm on Fri, 18 February 2011 23:59  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		By:  serge on Thu, 24 February 2011 00:43  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 5/9] Allow ptrace from non-init user namespaces
		
	 | 
 
	  | 
	 | 
	
		[PATCH 8/9] user namespaces: convert several capable() calls
		By:  serge on Thu, 17 February 2011 15:03  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 8/9] user namespaces: convert several capable() calls
		By:  ebiederm on Fri, 18 February 2011 01:51  
	 | 
 
	  | 
	 | 
	
		Re: [PATCH 8/9] user namespaces: convert several capable() calls
		
	 | 
 
	  | 
	 | 
	
		Re: userns: targeted capabilities v5
		By:  akpm on Fri, 18 February 2011 00:21  
	 | 
 
	  | 
	 | 
	
		Re: userns: targeted capabilities v5
		By:  ebiederm on Fri, 18 February 2011 03:53  
	 | 
 
	  | 
	 | 
	
		Re: userns: targeted capabilities v5
		By:  serge on Fri, 18 February 2011 04:28  
	 | 
 
	  | 
	 | 
	
		User namespaces and keys
		
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		By:  serge on Wed, 23 February 2011 13:58  
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		By:  ebiederm on Wed, 23 February 2011 14:46  
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		By:  ebiederm on Wed, 23 February 2011 15:45  
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		By:  ebiederm on Wed, 23 February 2011 20:55  
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		
	 | 
 
	  | 
	 | 
	
		Re: User namespaces and keys
		By:  ebiederm on Thu, 24 February 2011 06:56  
	 | 
  
Goto Forum:
 
 Current Time: Tue Nov 04 09:04:29 GMT 2025 
 Total time taken to generate the page: 0.15787 seconds 
 |