summaryrefslogtreecommitdiff
path: root/security/integrity/evm/evm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/evm/evm_main.c')
-rw-r--r--security/integrity/evm/evm_main.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index c9b6e2a43478..ff9a939dad8e 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -21,6 +21,7 @@
#include <linux/evm.h>
#include <linux/magic.h>
#include <linux/posix_acl_xattr.h>
+#include <linux/lsm_hooks.h>
#include <crypto/hash.h>
#include <crypto/hash_info.h>
@@ -305,7 +306,7 @@ static int evm_protected_xattr_common(const char *req_xattr_name,
return found;
}
-static int evm_protected_xattr(const char *req_xattr_name)
+int evm_protected_xattr(const char *req_xattr_name)
{
return evm_protected_xattr_common(req_xattr_name, false);
}
@@ -866,23 +867,47 @@ void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
/*
* evm_inode_init_security - initializes security.evm HMAC value
*/
-int evm_inode_init_security(struct inode *inode,
- const struct xattr *lsm_xattr,
- struct xattr *evm_xattr)
+int evm_inode_init_security(struct inode *inode, struct inode *dir,
+ const struct qstr *qstr, struct xattr *xattrs,
+ int *xattr_count)
{
struct evm_xattr *xattr_data;
+ struct xattr *xattr, *evm_xattr;
+ bool evm_protected_xattrs = false;
int rc;
- if (!(evm_initialized & EVM_INIT_HMAC) ||
- !evm_protected_xattr(lsm_xattr->name))
+ if (!(evm_initialized & EVM_INIT_HMAC) || !xattrs)
return 0;
+ /*
+ * security_inode_init_security() makes sure that the xattrs array is
+ * contiguous, there is enough space for security.evm, and that there is
+ * a terminator at the end of the array.
+ */
+ for (xattr = xattrs; xattr->name; xattr++) {
+ if (evm_protected_xattr(xattr->name))
+ evm_protected_xattrs = true;
+ }
+
+ /* EVM xattr not needed. */
+ if (!evm_protected_xattrs)
+ return 0;
+
+ evm_xattr = lsm_get_xattr_slot(xattrs, xattr_count);
+ /*
+ * Array terminator (xattr name = NULL) must be the first non-filled
+ * xattr slot.
+ */
+ WARN_ONCE(evm_xattr != xattr,
+ "%s: xattrs terminator is not the first non-filled slot\n",
+ __func__);
+
xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
if (!xattr_data)
return -ENOMEM;
xattr_data->data.type = EVM_XATTR_HMAC;
- rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
+ rc = evm_init_hmac(inode, xattrs, xattr_data->digest);
if (rc < 0)
goto out;