summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2014-05-11 04:05:23 (GMT)
committerMimi Zohar <zohar@linux.vnet.ibm.com>2014-06-12 21:58:07 (GMT)
commit2fb1c9a4f2dbc2f0bd2431c7fa64d0b5483864e4 (patch)
treee4a1c5fd8871eaba1b2bb0b65405d9cb0d4bd6f6
parent14503eb99414ceffe348b82982d5770b745f6626 (diff)
downloadlinux-2fb1c9a4f2dbc2f0bd2431c7fa64d0b5483864e4.tar.xz
evm: prohibit userspace writing 'security.evm' HMAC value
Calculating the 'security.evm' HMAC value requires access to the EVM encrypted key. Only the kernel should have access to it. This patch prevents userspace tools(eg. setfattr, cp --preserve=xattr) from setting/modifying the 'security.evm' HMAC value directly. Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Cc: <stable@vger.kernel.org>
-rw-r--r--security/integrity/evm/evm_main.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 73baf71..3bcb80d 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -300,12 +300,20 @@ out:
* @xattr_value: pointer to the new extended attribute value
* @xattr_value_len: pointer to the new extended attribute value length
*
- * Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
- * the current value is valid.
+ * Before allowing the 'security.evm' protected xattr to be updated,
+ * verify the existing value is valid. As only the kernel should have
+ * access to the EVM encrypted key needed to calculate the HMAC, prevent
+ * userspace from writing HMAC value. Writing 'security.evm' requires
+ * requires CAP_SYS_ADMIN privileges.
*/
int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
const void *xattr_value, size_t xattr_value_len)
{
+ const struct evm_ima_xattr_data *xattr_data = xattr_value;
+
+ if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0)
+ && (xattr_data->type == EVM_XATTR_HMAC))
+ return -EPERM;
return evm_protect_xattr(dentry, xattr_name, xattr_value,
xattr_value_len);
}