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;  |