aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2017-10-02 10:38:20 -0400
committerPaul Moore <paul@paul-moore.com>2017-10-04 10:38:25 -0400
commit6b240306ee1631587a87845127824df54a0a5abe (patch)
tree5de2bcb2c47898e7f80dbd171eb5f6c961a269ae /security/selinux/hooks.c
parent7c620ece125cbab7b5dfcb574ee1e64ab8b562cd (diff)
selinux: Perform both commoncap and selinux xattr checks
When selinux is loaded the relax permission checks for writing security.capable are not honored. Which keeps file capabilities from being used in user namespaces. Stephen Smalley <sds@tycho.nsa.gov> writes: > Originally SELinux called the cap functions directly since there was no > stacking support in the infrastructure and one had to manually stack a > secondary module internally. inode_setxattr and inode_removexattr > however were special cases because the cap functions would check > CAP_SYS_ADMIN for any non-capability attributes in the security.* > namespace, and we don't want to impose that requirement on setting > security.selinux. Thus, we inlined the capabilities logic into the > selinux hook functions and adapted it appropriately. Now that the permission checks in commoncap have evolved this inlining of their contents has become a problem. So restructure selinux_inode_removexattr, and selinux_inode_setxattr to call both the corresponding cap_inode_ function and dentry_has_perm when the attribute is not a selinux security xattr. This ensures the policies of both commoncap and selinux are enforced. This results in smack and selinux having the same basic structure for setxattr and removexattr. Performing their own special permission checks when it is their modules xattr being written to, and deferring to commoncap when that is not the case. Then finally performing their generic module policy on all xattr writes. This structure is fine when you only consider stacking with the commoncap lsm, but it becomes a problem if two lsms that don't want the commoncap security checks on their own attributes need to be stack. This means there will need to be updates in the future as lsm stacking is improved, but at least now the structure between smack and selinux is common making the code easier to refactor. This change also has the effect that selinux_linux_setotherxattr becomes unnecessary so it is removed. Fixes: 8db6c34f1dbc ("Introduce v3 namespaced file capabilities") Fixes: 7bbf0e052b76 ("[PATCH] selinux merge") Historical Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Reviewed-by: Serge Hallyn <serge@hallyn.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f5d304736852..c78dbec627f6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3124,27 +3124,6 @@ static int selinux_inode_getattr(const struct path *path)
3124 return path_has_perm(current_cred(), path, FILE__GETATTR); 3124 return path_has_perm(current_cred(), path, FILE__GETATTR);
3125} 3125}
3126 3126
3127static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
3128{
3129 const struct cred *cred = current_cred();
3130
3131 if (!strncmp(name, XATTR_SECURITY_PREFIX,
3132 sizeof XATTR_SECURITY_PREFIX - 1)) {
3133 if (!strcmp(name, XATTR_NAME_CAPS)) {
3134 if (!capable(CAP_SETFCAP))
3135 return -EPERM;
3136 } else if (!capable(CAP_SYS_ADMIN)) {
3137 /* A different attribute in the security namespace.
3138 Restrict to administrator. */
3139 return -EPERM;
3140 }
3141 }
3142
3143 /* Not an attribute we recognize, so just check the
3144 ordinary setattr permission. */
3145 return dentry_has_perm(cred, dentry, FILE__SETATTR);
3146}
3147
3148static bool has_cap_mac_admin(bool audit) 3127static bool has_cap_mac_admin(bool audit)
3149{ 3128{
3150 const struct cred *cred = current_cred(); 3129 const struct cred *cred = current_cred();
@@ -3167,8 +3146,15 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3167 u32 newsid, sid = current_sid(); 3146 u32 newsid, sid = current_sid();
3168 int rc = 0; 3147 int rc = 0;
3169 3148
3170 if (strcmp(name, XATTR_NAME_SELINUX)) 3149 if (strcmp(name, XATTR_NAME_SELINUX)) {
3171 return selinux_inode_setotherxattr(dentry, name); 3150 rc = cap_inode_setxattr(dentry, name, value, size, flags);
3151 if (rc)
3152 return rc;
3153
3154 /* Not an attribute we recognize, so just check the
3155 ordinary setattr permission. */
3156 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3157 }
3172 3158
3173 sbsec = inode->i_sb->s_security; 3159 sbsec = inode->i_sb->s_security;
3174 if (!(sbsec->flags & SBLABEL_MNT)) 3160 if (!(sbsec->flags & SBLABEL_MNT))
@@ -3282,8 +3268,15 @@ static int selinux_inode_listxattr(struct dentry *dentry)
3282 3268
3283static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 3269static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
3284{ 3270{
3285 if (strcmp(name, XATTR_NAME_SELINUX)) 3271 if (strcmp(name, XATTR_NAME_SELINUX)) {
3286 return selinux_inode_setotherxattr(dentry, name); 3272 int rc = cap_inode_removexattr(dentry, name);
3273 if (rc)
3274 return rc;
3275
3276 /* Not an attribute we recognize, so just check the
3277 ordinary setattr permission. */
3278 return dentry_has_perm(current_cred(), dentry, FILE__SETATTR);
3279 }
3287 3280
3288 /* No one is allowed to remove a SELinux security label. 3281 /* No one is allowed to remove a SELinux security label.
3289 You can change the label, but all data must be labeled. */ 3282 You can change the label, but all data must be labeled. */