|
@@ -2754,9 +2754,7 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Copy the in-core inode security context value to the user. If the
|
|
|
|
- * getxattr() prior to this succeeded, check to see if we need to
|
|
|
|
- * canonicalize the value to be finally returned to the user.
|
|
|
|
|
|
+ * Copy the inode security context value to the user.
|
|
*
|
|
*
|
|
* Permission check is handled by selinux_inode_getxattr hook.
|
|
* Permission check is handled by selinux_inode_getxattr hook.
|
|
*/
|
|
*/
|
|
@@ -2765,12 +2763,33 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
|
|
u32 size;
|
|
u32 size;
|
|
int error;
|
|
int error;
|
|
char *context = NULL;
|
|
char *context = NULL;
|
|
|
|
+ struct task_security_struct *tsec = current->security;
|
|
struct inode_security_struct *isec = inode->i_security;
|
|
struct inode_security_struct *isec = inode->i_security;
|
|
|
|
|
|
if (strcmp(name, XATTR_SELINUX_SUFFIX))
|
|
if (strcmp(name, XATTR_SELINUX_SUFFIX))
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
- error = security_sid_to_context(isec->sid, &context, &size);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * If the caller has CAP_MAC_ADMIN, then get the raw context
|
|
|
|
+ * value even if it is not defined by current policy; otherwise,
|
|
|
|
+ * use the in-core value under current policy.
|
|
|
|
+ * Use the non-auditing forms of the permission checks since
|
|
|
|
+ * getxattr may be called by unprivileged processes commonly
|
|
|
|
+ * and lack of permission just means that we fall back to the
|
|
|
|
+ * in-core context value, not a denial.
|
|
|
|
+ */
|
|
|
|
+ error = secondary_ops->capable(current, CAP_MAC_ADMIN);
|
|
|
|
+ if (!error)
|
|
|
|
+ error = avc_has_perm_noaudit(tsec->sid, tsec->sid,
|
|
|
|
+ SECCLASS_CAPABILITY2,
|
|
|
|
+ CAPABILITY2__MAC_ADMIN,
|
|
|
|
+ 0,
|
|
|
|
+ NULL);
|
|
|
|
+ if (!error)
|
|
|
|
+ error = security_sid_to_context_force(isec->sid, &context,
|
|
|
|
+ &size);
|
|
|
|
+ else
|
|
|
|
+ error = security_sid_to_context(isec->sid, &context, &size);
|
|
if (error)
|
|
if (error)
|
|
return error;
|
|
return error;
|
|
error = size;
|
|
error = size;
|