diff options
-rw-r--r-- | security/selinux/hooks.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4be156334b22..91b666aec452 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2754,9 +2754,7 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name) | |||
2754 | } | 2754 | } |
2755 | 2755 | ||
2756 | /* | 2756 | /* |
2757 | * Copy the in-core inode security context value to the user. If the | 2757 | * Copy the inode security context value to the user. |
2758 | * getxattr() prior to this succeeded, check to see if we need to | ||
2759 | * canonicalize the value to be finally returned to the user. | ||
2760 | * | 2758 | * |
2761 | * Permission check is handled by selinux_inode_getxattr hook. | 2759 | * Permission check is handled by selinux_inode_getxattr hook. |
2762 | */ | 2760 | */ |
@@ -2765,12 +2763,33 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
2765 | u32 size; | 2763 | u32 size; |
2766 | int error; | 2764 | int error; |
2767 | char *context = NULL; | 2765 | char *context = NULL; |
2766 | struct task_security_struct *tsec = current->security; | ||
2768 | struct inode_security_struct *isec = inode->i_security; | 2767 | struct inode_security_struct *isec = inode->i_security; |
2769 | 2768 | ||
2770 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 2769 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
2771 | return -EOPNOTSUPP; | 2770 | return -EOPNOTSUPP; |
2772 | 2771 | ||
2773 | error = security_sid_to_context(isec->sid, &context, &size); | 2772 | /* |
2773 | * If the caller has CAP_MAC_ADMIN, then get the raw context | ||
2774 | * value even if it is not defined by current policy; otherwise, | ||
2775 | * use the in-core value under current policy. | ||
2776 | * Use the non-auditing forms of the permission checks since | ||
2777 | * getxattr may be called by unprivileged processes commonly | ||
2778 | * and lack of permission just means that we fall back to the | ||
2779 | * in-core context value, not a denial. | ||
2780 | */ | ||
2781 | error = secondary_ops->capable(current, CAP_MAC_ADMIN); | ||
2782 | if (!error) | ||
2783 | error = avc_has_perm_noaudit(tsec->sid, tsec->sid, | ||
2784 | SECCLASS_CAPABILITY2, | ||
2785 | CAPABILITY2__MAC_ADMIN, | ||
2786 | 0, | ||
2787 | NULL); | ||
2788 | if (!error) | ||
2789 | error = security_sid_to_context_force(isec->sid, &context, | ||
2790 | &size); | ||
2791 | else | ||
2792 | error = security_sid_to_context(isec->sid, &context, &size); | ||
2774 | if (error) | 2793 | if (error) |
2775 | return error; | 2794 | return error; |
2776 | error = size; | 2795 | error = size; |