diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 43 |
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 | ||
3127 | static 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 | |||
3148 | static bool has_cap_mac_admin(bool audit) | 3127 | static 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 | ||
3283 | static int selinux_inode_removexattr(struct dentry *dentry, const char *name) | 3269 | static 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. */ |