summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2016-04-08 13:52:00 -0400
committerPaul Moore <paul@paul-moore.com>2016-04-26 15:41:43 -0400
commit8e4ff6f228e4722cac74db716e308d1da33d744f (patch)
treedb853a9321a0a656a7cb232b5328b17689ccf18e /security
parent1ac42476263eec99fb2d3c31ee946cb44e80ddd5 (diff)
selinux: distinguish non-init user namespace capability checks
Distinguish capability checks against a target associated with the init user namespace versus capability checks against a target associated with a non-init user namespace by defining and using separate security classes for the latter. This is needed to support e.g. Chrome usage of user namespaces for the Chrome sandbox without needing to allow Chrome to also exercise capabilities on targets in the init user namespace. Suggested-by: Dan Walsh <dwalsh@redhat.com> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c14
-rw-r--r--security/selinux/include/classmap.h28
2 files changed, 25 insertions, 17 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 474011c46bbd..bbff80c6d3f2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1631,7 +1631,7 @@ static int current_has_perm(const struct task_struct *tsk,
1631 1631
1632/* Check whether a task is allowed to use a capability. */ 1632/* Check whether a task is allowed to use a capability. */
1633static int cred_has_capability(const struct cred *cred, 1633static int cred_has_capability(const struct cred *cred,
1634 int cap, int audit) 1634 int cap, int audit, bool initns)
1635{ 1635{
1636 struct common_audit_data ad; 1636 struct common_audit_data ad;
1637 struct av_decision avd; 1637 struct av_decision avd;
@@ -1645,10 +1645,10 @@ static int cred_has_capability(const struct cred *cred,
1645 1645
1646 switch (CAP_TO_INDEX(cap)) { 1646 switch (CAP_TO_INDEX(cap)) {
1647 case 0: 1647 case 0:
1648 sclass = SECCLASS_CAPABILITY; 1648 sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS;
1649 break; 1649 break;
1650 case 1: 1650 case 1:
1651 sclass = SECCLASS_CAPABILITY2; 1651 sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS;
1652 break; 1652 break;
1653 default: 1653 default:
1654 printk(KERN_ERR 1654 printk(KERN_ERR
@@ -2152,7 +2152,7 @@ static int selinux_capset(struct cred *new, const struct cred *old,
2152static int selinux_capable(const struct cred *cred, struct user_namespace *ns, 2152static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
2153 int cap, int audit) 2153 int cap, int audit)
2154{ 2154{
2155 return cred_has_capability(cred, cap, audit); 2155 return cred_has_capability(cred, cap, audit, ns == &init_user_ns);
2156} 2156}
2157 2157
2158static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) 2158static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
@@ -2230,7 +2230,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2230 int rc, cap_sys_admin = 0; 2230 int rc, cap_sys_admin = 0;
2231 2231
2232 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, 2232 rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN,
2233 SECURITY_CAP_NOAUDIT); 2233 SECURITY_CAP_NOAUDIT, true);
2234 if (rc == 0) 2234 if (rc == 0)
2235 cap_sys_admin = 1; 2235 cap_sys_admin = 1;
2236 2236
@@ -3213,7 +3213,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3213 SECURITY_CAP_NOAUDIT); 3213 SECURITY_CAP_NOAUDIT);
3214 if (!error) 3214 if (!error)
3215 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, 3215 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
3216 SECURITY_CAP_NOAUDIT); 3216 SECURITY_CAP_NOAUDIT, true);
3217 isec = inode_security(inode); 3217 isec = inode_security(inode);
3218 if (!error) 3218 if (!error)
3219 error = security_sid_to_context_force(isec->sid, &context, 3219 error = security_sid_to_context_force(isec->sid, &context,
@@ -3390,7 +3390,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3390 case KDSKBENT: 3390 case KDSKBENT:
3391 case KDSKBSENT: 3391 case KDSKBSENT:
3392 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, 3392 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
3393 SECURITY_CAP_AUDIT); 3393 SECURITY_CAP_AUDIT, true);
3394 break; 3394 break;
3395 3395
3396 /* default case assumes that the command will go 3396 /* default case assumes that the command will go
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 8fbd1383d75e..1f1f4b2f6018 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -12,6 +12,18 @@
12#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ 12#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
13 "write", "associate", "unix_read", "unix_write" 13 "write", "associate", "unix_read", "unix_write"
14 14
15#define COMMON_CAP_PERMS "chown", "dac_override", "dac_read_search", \
16 "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", \
17 "linux_immutable", "net_bind_service", "net_broadcast", \
18 "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", \
19 "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", \
20 "sys_boot", "sys_nice", "sys_resource", "sys_time", \
21 "sys_tty_config", "mknod", "lease", "audit_write", \
22 "audit_control", "setfcap"
23
24#define COMMON_CAP2_PERMS "mac_override", "mac_admin", "syslog", \
25 "wake_alarm", "block_suspend", "audit_read"
26
15/* 27/*
16 * Note: The name for any socket class should be suffixed by "socket", 28 * Note: The name for any socket class should be suffixed by "socket",
17 * and doesn't contain more than one substr of "socket". 29 * and doesn't contain more than one substr of "socket".
@@ -34,14 +46,7 @@ struct security_class_mapping secclass_map[] = {
34 { "ipc_info", "syslog_read", "syslog_mod", 46 { "ipc_info", "syslog_read", "syslog_mod",
35 "syslog_console", "module_request", "module_load", NULL } }, 47 "syslog_console", "module_request", "module_load", NULL } },
36 { "capability", 48 { "capability",
37 { "chown", "dac_override", "dac_read_search", 49 { COMMON_CAP_PERMS, NULL } },
38 "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",
39 "linux_immutable", "net_bind_service", "net_broadcast",
40 "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module",
41 "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin",
42 "sys_boot", "sys_nice", "sys_resource", "sys_time",
43 "sys_tty_config", "mknod", "lease", "audit_write",
44 "audit_control", "setfcap", NULL } },
45 { "filesystem", 50 { "filesystem",
46 { "mount", "remount", "unmount", "getattr", 51 { "mount", "remount", "unmount", "getattr",
47 "relabelfrom", "relabelto", "associate", "quotamod", 52 "relabelfrom", "relabelto", "associate", "quotamod",
@@ -150,12 +155,15 @@ struct security_class_mapping secclass_map[] = {
150 { "memprotect", { "mmap_zero", NULL } }, 155 { "memprotect", { "mmap_zero", NULL } },
151 { "peer", { "recv", NULL } }, 156 { "peer", { "recv", NULL } },
152 { "capability2", 157 { "capability2",
153 { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", 158 { COMMON_CAP2_PERMS, NULL } },
154 "audit_read", NULL } },
155 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 159 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
156 { "tun_socket", 160 { "tun_socket",
157 { COMMON_SOCK_PERMS, "attach_queue", NULL } }, 161 { COMMON_SOCK_PERMS, "attach_queue", NULL } },
158 { "binder", { "impersonate", "call", "set_context_mgr", "transfer", 162 { "binder", { "impersonate", "call", "set_context_mgr", "transfer",
159 NULL } }, 163 NULL } },
164 { "cap_userns",
165 { COMMON_CAP_PERMS, NULL } },
166 { "cap2_userns",
167 { COMMON_CAP2_PERMS, NULL } },
160 { NULL } 168 { NULL }
161 }; 169 };