diff options
Diffstat (limited to 'security/integrity/evm/evm_main.c')
-rw-r--r-- | security/integrity/evm/evm_main.c | 39 |
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; |