aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2017-04-21 20:14:32 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-05-24 13:03:31 -0400
commitb1d749c5c34112fab5902c43b2a37a0ba1e5f0f1 (patch)
tree4e0c26b4c2b9ee8db3306f5d70df7d52a2cd4a0f
parentbc6155d1326092f4c29fe05a32b614249620d88e (diff)
capabilities: Allow privileged user in s_user_ns to set security.* xattrs
A privileged user in s_user_ns will generally have the ability to manipulate the backing store and insert security.* xattrs into the filesystem directly. Therefore the kernel must be prepared to handle these xattrs from unprivileged mounts, and it makes little sense for commoncap to prevent writing these xattrs to the filesystem. The capability and LSM code have already been updated to appropriately handle xattrs from unprivileged mounts, so it is safe to loosen this restriction on setting xattrs. The exception to this logic is that writing xattrs to a mounted filesystem may also cause the LSM inode_post_setxattr or inode_setsecurity callbacks to be invoked. SELinux will deny the xattr update by virtue of applying mountpoint labeling to unprivileged userns mounts, and Smack will deny the writes for any user without global CAP_MAC_ADMIN, so loosening the capability check in commoncap is safe in this respect as well. Signed-off-by: Seth Forshee <seth.forshee@canonical.com> Acked-by: Serge Hallyn <serge@hallyn.com> Acked-by: Christian Brauner <christian@brauner.io> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r--security/commoncap.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index 1ce701fcb3f3..f4c33abd9959 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -919,6 +919,8 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
919int cap_inode_setxattr(struct dentry *dentry, const char *name, 919int cap_inode_setxattr(struct dentry *dentry, const char *name,
920 const void *value, size_t size, int flags) 920 const void *value, size_t size, int flags)
921{ 921{
922 struct user_namespace *user_ns = dentry->d_sb->s_user_ns;
923
922 /* Ignore non-security xattrs */ 924 /* Ignore non-security xattrs */
923 if (strncmp(name, XATTR_SECURITY_PREFIX, 925 if (strncmp(name, XATTR_SECURITY_PREFIX,
924 sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) 926 sizeof(XATTR_SECURITY_PREFIX) - 1) != 0)
@@ -931,7 +933,7 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name,
931 if (strcmp(name, XATTR_NAME_CAPS) == 0) 933 if (strcmp(name, XATTR_NAME_CAPS) == 0)
932 return 0; 934 return 0;
933 935
934 if (!capable(CAP_SYS_ADMIN)) 936 if (!ns_capable(user_ns, CAP_SYS_ADMIN))
935 return -EPERM; 937 return -EPERM;
936 return 0; 938 return 0;
937} 939}
@@ -949,6 +951,8 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name,
949 */ 951 */
950int cap_inode_removexattr(struct dentry *dentry, const char *name) 952int cap_inode_removexattr(struct dentry *dentry, const char *name)
951{ 953{
954 struct user_namespace *user_ns = dentry->d_sb->s_user_ns;
955
952 /* Ignore non-security xattrs */ 956 /* Ignore non-security xattrs */
953 if (strncmp(name, XATTR_SECURITY_PREFIX, 957 if (strncmp(name, XATTR_SECURITY_PREFIX,
954 sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) 958 sizeof(XATTR_SECURITY_PREFIX) - 1) != 0)
@@ -964,7 +968,7 @@ int cap_inode_removexattr(struct dentry *dentry, const char *name)
964 return 0; 968 return 0;
965 } 969 }
966 970
967 if (!capable(CAP_SYS_ADMIN)) 971 if (!ns_capable(user_ns, CAP_SYS_ADMIN))
968 return -EPERM; 972 return -EPERM;
969 return 0; 973 return 0;
970} 974}