1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
266dbc325SMimi Zohar /*
366dbc325SMimi Zohar  * Copyright (C) 2005-2010 IBM Corporation
466dbc325SMimi Zohar  *
566dbc325SMimi Zohar  * Author:
666dbc325SMimi Zohar  * Mimi Zohar <zohar@us.ibm.com>
766dbc325SMimi Zohar  * Kylene Hall <kjhall@us.ibm.com>
866dbc325SMimi Zohar  *
966dbc325SMimi Zohar  * File: evm_main.c
1066dbc325SMimi Zohar  *	implements evm_inode_setxattr, evm_inode_post_setxattr,
1166dbc325SMimi Zohar  *	evm_inode_removexattr, and evm_verifyxattr
1266dbc325SMimi Zohar  */
1366dbc325SMimi Zohar 
143aafb1fbSPaul Gortmaker #include <linux/init.h>
1566dbc325SMimi Zohar #include <linux/crypto.h>
169b97b6cdSMimi Zohar #include <linux/audit.h>
1766dbc325SMimi Zohar #include <linux/xattr.h>
1866dbc325SMimi Zohar #include <linux/integrity.h>
193e1be52dSMimi Zohar #include <linux/evm.h>
2050d34394SIngo Molnar #include <linux/magic.h>
2150d34394SIngo Molnar 
22d46eb369SDmitry Kasatkin #include <crypto/hash.h>
235feeb611SMatthew Garrett #include <crypto/hash_info.h>
24613317bdSRyan Ware #include <crypto/algapi.h>
2566dbc325SMimi Zohar #include "evm.h"
2666dbc325SMimi Zohar 
2766dbc325SMimi Zohar int evm_initialized;
2866dbc325SMimi Zohar 
2917d7b0afSHernán Gonzalez static const char * const integrity_status_msg[] = {
3050b97748SMatthew Garrett 	"pass", "pass_immutable", "fail", "no_label", "no_xattrs", "unknown"
319b97b6cdSMimi Zohar };
32d3b33679SDmitry Kasatkin int evm_hmac_attrs;
3366dbc325SMimi Zohar 
34fa516b66SMatthew Garrett static struct xattr_list evm_config_default_xattrnames[] = {
3566dbc325SMimi Zohar #ifdef CONFIG_SECURITY_SELINUX
3621af7663SMatthew Garrett 	{.name = XATTR_NAME_SELINUX},
3766dbc325SMimi Zohar #endif
3866dbc325SMimi Zohar #ifdef CONFIG_SECURITY_SMACK
3921af7663SMatthew Garrett 	{.name = XATTR_NAME_SMACK},
403e38df56SDmitry Kasatkin #ifdef CONFIG_EVM_EXTRA_SMACK_XATTRS
4121af7663SMatthew Garrett 	{.name = XATTR_NAME_SMACKEXEC},
4221af7663SMatthew Garrett 	{.name = XATTR_NAME_SMACKTRANSMUTE},
4321af7663SMatthew Garrett 	{.name = XATTR_NAME_SMACKMMAP},
443e38df56SDmitry Kasatkin #endif
4566dbc325SMimi Zohar #endif
46096b8546SMatthew Garrett #ifdef CONFIG_SECURITY_APPARMOR
4721af7663SMatthew Garrett 	{.name = XATTR_NAME_APPARMOR},
48096b8546SMatthew Garrett #endif
492fe5d6deSMimi Zohar #ifdef CONFIG_IMA_APPRAISE
5021af7663SMatthew Garrett 	{.name = XATTR_NAME_IMA},
512fe5d6deSMimi Zohar #endif
5221af7663SMatthew Garrett 	{.name = XATTR_NAME_CAPS},
5366dbc325SMimi Zohar };
5466dbc325SMimi Zohar 
5521af7663SMatthew Garrett LIST_HEAD(evm_config_xattrnames);
5621af7663SMatthew Garrett 
577102ebcdSMimi Zohar static int evm_fixmode;
587102ebcdSMimi Zohar static int __init evm_set_fixmode(char *str)
597102ebcdSMimi Zohar {
607102ebcdSMimi Zohar 	if (strncmp(str, "fix", 3) == 0)
617102ebcdSMimi Zohar 		evm_fixmode = 1;
627fe2bb7eSBruno Meneguele 	else
637fe2bb7eSBruno Meneguele 		pr_err("invalid \"%s\" mode", str);
647fe2bb7eSBruno Meneguele 
657102ebcdSMimi Zohar 	return 0;
667102ebcdSMimi Zohar }
677102ebcdSMimi Zohar __setup("evm=", evm_set_fixmode);
687102ebcdSMimi Zohar 
69d3b33679SDmitry Kasatkin static void __init evm_init_config(void)
70d3b33679SDmitry Kasatkin {
7121af7663SMatthew Garrett 	int i, xattrs;
7221af7663SMatthew Garrett 
7321af7663SMatthew Garrett 	xattrs = ARRAY_SIZE(evm_config_default_xattrnames);
7421af7663SMatthew Garrett 
7521af7663SMatthew Garrett 	pr_info("Initialising EVM extended attributes:\n");
7621af7663SMatthew Garrett 	for (i = 0; i < xattrs; i++) {
7721af7663SMatthew Garrett 		pr_info("%s\n", evm_config_default_xattrnames[i].name);
7821af7663SMatthew Garrett 		list_add_tail(&evm_config_default_xattrnames[i].list,
7921af7663SMatthew Garrett 			      &evm_config_xattrnames);
8021af7663SMatthew Garrett 	}
8121af7663SMatthew Garrett 
82d3b33679SDmitry Kasatkin #ifdef CONFIG_EVM_ATTR_FSUUID
83d3b33679SDmitry Kasatkin 	evm_hmac_attrs |= EVM_ATTR_FSUUID;
84d3b33679SDmitry Kasatkin #endif
85d3b33679SDmitry Kasatkin 	pr_info("HMAC attrs: 0x%x\n", evm_hmac_attrs);
86d3b33679SDmitry Kasatkin }
87d3b33679SDmitry Kasatkin 
88ae1ba167SMatthew Garrett static bool evm_key_loaded(void)
89ae1ba167SMatthew Garrett {
90ae1ba167SMatthew Garrett 	return (bool)(evm_initialized & EVM_KEY_MASK);
91ae1ba167SMatthew Garrett }
92ae1ba167SMatthew Garrett 
93*4a804b8aSRoberto Sassu /*
94*4a804b8aSRoberto Sassu  * This function determines whether or not it is safe to ignore verification
95*4a804b8aSRoberto Sassu  * errors, based on the ability of EVM to calculate HMACs. If the HMAC key
96*4a804b8aSRoberto Sassu  * is not loaded, and it cannot be loaded in the future due to the
97*4a804b8aSRoberto Sassu  * EVM_SETUP_COMPLETE initialization flag, allowing an operation despite the
98*4a804b8aSRoberto Sassu  * attrs/xattrs being found invalid will not make them valid.
99*4a804b8aSRoberto Sassu  */
100*4a804b8aSRoberto Sassu static bool evm_hmac_disabled(void)
101*4a804b8aSRoberto Sassu {
102*4a804b8aSRoberto Sassu 	if (evm_initialized & EVM_INIT_HMAC)
103*4a804b8aSRoberto Sassu 		return false;
104*4a804b8aSRoberto Sassu 
105*4a804b8aSRoberto Sassu 	if (!(evm_initialized & EVM_SETUP_COMPLETE))
106*4a804b8aSRoberto Sassu 		return false;
107*4a804b8aSRoberto Sassu 
108*4a804b8aSRoberto Sassu 	return true;
109*4a804b8aSRoberto Sassu }
110*4a804b8aSRoberto Sassu 
11115647eb3SDmitry Kasatkin static int evm_find_protected_xattrs(struct dentry *dentry)
11215647eb3SDmitry Kasatkin {
113c6f493d6SDavid Howells 	struct inode *inode = d_backing_inode(dentry);
11421af7663SMatthew Garrett 	struct xattr_list *xattr;
11515647eb3SDmitry Kasatkin 	int error;
11615647eb3SDmitry Kasatkin 	int count = 0;
11715647eb3SDmitry Kasatkin 
1185d6c3191SAndreas Gruenbacher 	if (!(inode->i_opflags & IOP_XATTR))
11915647eb3SDmitry Kasatkin 		return -EOPNOTSUPP;
12015647eb3SDmitry Kasatkin 
121770f6058SMadhuparna Bhowmik 	list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) {
12221af7663SMatthew Garrett 		error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0);
12315647eb3SDmitry Kasatkin 		if (error < 0) {
12415647eb3SDmitry Kasatkin 			if (error == -ENODATA)
12515647eb3SDmitry Kasatkin 				continue;
12615647eb3SDmitry Kasatkin 			return error;
12715647eb3SDmitry Kasatkin 		}
12815647eb3SDmitry Kasatkin 		count++;
12915647eb3SDmitry Kasatkin 	}
13015647eb3SDmitry Kasatkin 
13115647eb3SDmitry Kasatkin 	return count;
13215647eb3SDmitry Kasatkin }
13315647eb3SDmitry Kasatkin 
13466dbc325SMimi Zohar /*
13566dbc325SMimi Zohar  * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
13666dbc325SMimi Zohar  *
13766dbc325SMimi Zohar  * Compute the HMAC on the dentry's protected set of extended attributes
1387102ebcdSMimi Zohar  * and compare it against the stored security.evm xattr.
1397102ebcdSMimi Zohar  *
1407102ebcdSMimi Zohar  * For performance:
1417102ebcdSMimi Zohar  * - use the previoulsy retrieved xattr value and length to calculate the
14266dbc325SMimi Zohar  *   HMAC.)
1437102ebcdSMimi Zohar  * - cache the verification result in the iint, when available.
14466dbc325SMimi Zohar  *
14566dbc325SMimi Zohar  * Returns integrity status
14666dbc325SMimi Zohar  */
14766dbc325SMimi Zohar static enum integrity_status evm_verify_hmac(struct dentry *dentry,
14866dbc325SMimi Zohar 					     const char *xattr_name,
14966dbc325SMimi Zohar 					     char *xattr_value,
15066dbc325SMimi Zohar 					     size_t xattr_value_len,
15166dbc325SMimi Zohar 					     struct integrity_iint_cache *iint)
15266dbc325SMimi Zohar {
15315647eb3SDmitry Kasatkin 	struct evm_ima_xattr_data *xattr_data = NULL;
1545feeb611SMatthew Garrett 	struct signature_v2_hdr *hdr;
155566be59aSMimi Zohar 	enum integrity_status evm_status = INTEGRITY_PASS;
1565feeb611SMatthew Garrett 	struct evm_digest digest;
15770946c4aSSascha Hauer 	struct inode *inode;
15815647eb3SDmitry Kasatkin 	int rc, xattr_len;
15966dbc325SMimi Zohar 
16050b97748SMatthew Garrett 	if (iint && (iint->evm_status == INTEGRITY_PASS ||
16150b97748SMatthew Garrett 		     iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
16224e0198eSDmitry Kasatkin 		return iint->evm_status;
16366dbc325SMimi Zohar 
1646d38ca01SDmitry Kasatkin 	/* if status is not PASS, try to check again - against -ENOMEM */
1656d38ca01SDmitry Kasatkin 
16615647eb3SDmitry Kasatkin 	/* first need to know the sig type */
167c7c7a1a1STycho Andersen 	rc = vfs_getxattr_alloc(&init_user_ns, dentry, XATTR_NAME_EVM,
168c7c7a1a1STycho Andersen 				(char **)&xattr_data, 0, GFP_NOFS);
16915647eb3SDmitry Kasatkin 	if (rc <= 0) {
1701f100979SDmitry Kasatkin 		evm_status = INTEGRITY_FAIL;
1711f100979SDmitry Kasatkin 		if (rc == -ENODATA) {
17215647eb3SDmitry Kasatkin 			rc = evm_find_protected_xattrs(dentry);
17315647eb3SDmitry Kasatkin 			if (rc > 0)
17415647eb3SDmitry Kasatkin 				evm_status = INTEGRITY_NOLABEL;
17515647eb3SDmitry Kasatkin 			else if (rc == 0)
17615647eb3SDmitry Kasatkin 				evm_status = INTEGRITY_NOXATTRS; /* new file */
1771f100979SDmitry Kasatkin 		} else if (rc == -EOPNOTSUPP) {
1781f100979SDmitry Kasatkin 			evm_status = INTEGRITY_UNKNOWN;
17915647eb3SDmitry Kasatkin 		}
180566be59aSMimi Zohar 		goto out;
181566be59aSMimi Zohar 	}
18266dbc325SMimi Zohar 
183b1aaab22SDmitry Kasatkin 	xattr_len = rc;
18415647eb3SDmitry Kasatkin 
18515647eb3SDmitry Kasatkin 	/* check value type */
18615647eb3SDmitry Kasatkin 	switch (xattr_data->type) {
18715647eb3SDmitry Kasatkin 	case EVM_XATTR_HMAC:
188650b29dbSThiago Jung Bauermann 		if (xattr_len != sizeof(struct evm_xattr)) {
189b4bfec7fSSeth Forshee 			evm_status = INTEGRITY_FAIL;
190b4bfec7fSSeth Forshee 			goto out;
191b4bfec7fSSeth Forshee 		}
1925feeb611SMatthew Garrett 
1935feeb611SMatthew Garrett 		digest.hdr.algo = HASH_ALGO_SHA1;
19415647eb3SDmitry Kasatkin 		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
1955feeb611SMatthew Garrett 				   xattr_value_len, &digest);
19615647eb3SDmitry Kasatkin 		if (rc)
19715647eb3SDmitry Kasatkin 			break;
198650b29dbSThiago Jung Bauermann 		rc = crypto_memneq(xattr_data->data, digest.digest,
1995feeb611SMatthew Garrett 				   SHA1_DIGEST_SIZE);
20015647eb3SDmitry Kasatkin 		if (rc)
20115647eb3SDmitry Kasatkin 			rc = -EINVAL;
20215647eb3SDmitry Kasatkin 		break;
20315647eb3SDmitry Kasatkin 	case EVM_IMA_XATTR_DIGSIG:
20450b97748SMatthew Garrett 	case EVM_XATTR_PORTABLE_DIGSIG:
205455b6c91SRoberto Sassu 		/* accept xattr with non-empty signature field */
206455b6c91SRoberto Sassu 		if (xattr_len <= sizeof(struct signature_v2_hdr)) {
207455b6c91SRoberto Sassu 			evm_status = INTEGRITY_FAIL;
208455b6c91SRoberto Sassu 			goto out;
209455b6c91SRoberto Sassu 		}
210455b6c91SRoberto Sassu 
2115feeb611SMatthew Garrett 		hdr = (struct signature_v2_hdr *)xattr_data;
2125feeb611SMatthew Garrett 		digest.hdr.algo = hdr->hash_algo;
21315647eb3SDmitry Kasatkin 		rc = evm_calc_hash(dentry, xattr_name, xattr_value,
2145feeb611SMatthew Garrett 				   xattr_value_len, xattr_data->type, &digest);
21515647eb3SDmitry Kasatkin 		if (rc)
21615647eb3SDmitry Kasatkin 			break;
21715647eb3SDmitry Kasatkin 		rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
218b1aaab22SDmitry Kasatkin 					(const char *)xattr_data, xattr_len,
2195feeb611SMatthew Garrett 					digest.digest, digest.hdr.length);
22015647eb3SDmitry Kasatkin 		if (!rc) {
22170946c4aSSascha Hauer 			inode = d_backing_inode(dentry);
22270946c4aSSascha Hauer 
22350b97748SMatthew Garrett 			if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) {
22450b97748SMatthew Garrett 				if (iint)
22550b97748SMatthew Garrett 					iint->flags |= EVM_IMMUTABLE_DIGSIG;
22650b97748SMatthew Garrett 				evm_status = INTEGRITY_PASS_IMMUTABLE;
22770946c4aSSascha Hauer 			} else if (!IS_RDONLY(inode) &&
22870946c4aSSascha Hauer 				   !(inode->i_sb->s_readonly_remount) &&
22970946c4aSSascha Hauer 				   !IS_IMMUTABLE(inode)) {
230c2baec7fSDmitry Kasatkin 				evm_update_evmxattr(dentry, xattr_name,
231c2baec7fSDmitry Kasatkin 						    xattr_value,
23215647eb3SDmitry Kasatkin 						    xattr_value_len);
23315647eb3SDmitry Kasatkin 			}
23450b97748SMatthew Garrett 		}
23515647eb3SDmitry Kasatkin 		break;
23615647eb3SDmitry Kasatkin 	default:
23715647eb3SDmitry Kasatkin 		rc = -EINVAL;
23815647eb3SDmitry Kasatkin 		break;
23915647eb3SDmitry Kasatkin 	}
24015647eb3SDmitry Kasatkin 
24115647eb3SDmitry Kasatkin 	if (rc)
24215647eb3SDmitry Kasatkin 		evm_status = (rc == -ENODATA) ?
24315647eb3SDmitry Kasatkin 				INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
2447102ebcdSMimi Zohar out:
2457102ebcdSMimi Zohar 	if (iint)
2467102ebcdSMimi Zohar 		iint->evm_status = evm_status;
24715647eb3SDmitry Kasatkin 	kfree(xattr_data);
2487102ebcdSMimi Zohar 	return evm_status;
24966dbc325SMimi Zohar }
25066dbc325SMimi Zohar 
25166dbc325SMimi Zohar static int evm_protected_xattr(const char *req_xattr_name)
25266dbc325SMimi Zohar {
25366dbc325SMimi Zohar 	int namelen;
25466dbc325SMimi Zohar 	int found = 0;
25521af7663SMatthew Garrett 	struct xattr_list *xattr;
25666dbc325SMimi Zohar 
25766dbc325SMimi Zohar 	namelen = strlen(req_xattr_name);
258770f6058SMadhuparna Bhowmik 	list_for_each_entry_lockless(xattr, &evm_config_xattrnames, list) {
25921af7663SMatthew Garrett 		if ((strlen(xattr->name) == namelen)
26021af7663SMatthew Garrett 		    && (strncmp(req_xattr_name, xattr->name, namelen) == 0)) {
26166dbc325SMimi Zohar 			found = 1;
26266dbc325SMimi Zohar 			break;
26366dbc325SMimi Zohar 		}
264cb723180SMimi Zohar 		if (strncmp(req_xattr_name,
26521af7663SMatthew Garrett 			    xattr->name + XATTR_SECURITY_PREFIX_LEN,
266cb723180SMimi Zohar 			    strlen(req_xattr_name)) == 0) {
267cb723180SMimi Zohar 			found = 1;
268cb723180SMimi Zohar 			break;
269cb723180SMimi Zohar 		}
27066dbc325SMimi Zohar 	}
27121af7663SMatthew Garrett 
27266dbc325SMimi Zohar 	return found;
27366dbc325SMimi Zohar }
27466dbc325SMimi Zohar 
27566dbc325SMimi Zohar /**
27666dbc325SMimi Zohar  * evm_verifyxattr - verify the integrity of the requested xattr
27766dbc325SMimi Zohar  * @dentry: object of the verify xattr
27866dbc325SMimi Zohar  * @xattr_name: requested xattr
27966dbc325SMimi Zohar  * @xattr_value: requested xattr value
28066dbc325SMimi Zohar  * @xattr_value_len: requested xattr value length
28166dbc325SMimi Zohar  *
28266dbc325SMimi Zohar  * Calculate the HMAC for the given dentry and verify it against the stored
28366dbc325SMimi Zohar  * security.evm xattr. For performance, use the xattr value and length
28466dbc325SMimi Zohar  * previously retrieved to calculate the HMAC.
28566dbc325SMimi Zohar  *
28666dbc325SMimi Zohar  * Returns the xattr integrity status.
28766dbc325SMimi Zohar  *
28866dbc325SMimi Zohar  * This function requires the caller to lock the inode's i_mutex before it
28966dbc325SMimi Zohar  * is executed.
29066dbc325SMimi Zohar  */
29166dbc325SMimi Zohar enum integrity_status evm_verifyxattr(struct dentry *dentry,
29266dbc325SMimi Zohar 				      const char *xattr_name,
2932960e6cbSDmitry Kasatkin 				      void *xattr_value, size_t xattr_value_len,
2942960e6cbSDmitry Kasatkin 				      struct integrity_iint_cache *iint)
29566dbc325SMimi Zohar {
296ae1ba167SMatthew Garrett 	if (!evm_key_loaded() || !evm_protected_xattr(xattr_name))
29766dbc325SMimi Zohar 		return INTEGRITY_UNKNOWN;
29866dbc325SMimi Zohar 
2992960e6cbSDmitry Kasatkin 	if (!iint) {
300c6f493d6SDavid Howells 		iint = integrity_iint_find(d_backing_inode(dentry));
30166dbc325SMimi Zohar 		if (!iint)
30266dbc325SMimi Zohar 			return INTEGRITY_UNKNOWN;
3032960e6cbSDmitry Kasatkin 	}
3042960e6cbSDmitry Kasatkin 	return evm_verify_hmac(dentry, xattr_name, xattr_value,
30566dbc325SMimi Zohar 				 xattr_value_len, iint);
30666dbc325SMimi Zohar }
30766dbc325SMimi Zohar EXPORT_SYMBOL_GPL(evm_verifyxattr);
30866dbc325SMimi Zohar 
30966dbc325SMimi Zohar /*
3107102ebcdSMimi Zohar  * evm_verify_current_integrity - verify the dentry's metadata integrity
3117102ebcdSMimi Zohar  * @dentry: pointer to the affected dentry
3127102ebcdSMimi Zohar  *
3137102ebcdSMimi Zohar  * Verify and return the dentry's metadata integrity. The exceptions are
3147102ebcdSMimi Zohar  * before EVM is initialized or in 'fix' mode.
3157102ebcdSMimi Zohar  */
3167102ebcdSMimi Zohar static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
3177102ebcdSMimi Zohar {
318c6f493d6SDavid Howells 	struct inode *inode = d_backing_inode(dentry);
3197102ebcdSMimi Zohar 
320ae1ba167SMatthew Garrett 	if (!evm_key_loaded() || !S_ISREG(inode->i_mode) || evm_fixmode)
3217102ebcdSMimi Zohar 		return 0;
3227102ebcdSMimi Zohar 	return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
3237102ebcdSMimi Zohar }
3247102ebcdSMimi Zohar 
325a924ce0bSMimi Zohar /*
326a924ce0bSMimi Zohar  * evm_protect_xattr - protect the EVM extended attribute
327a924ce0bSMimi Zohar  *
328bf6d0f5dSMimi Zohar  * Prevent security.evm from being modified or removed without the
329bf6d0f5dSMimi Zohar  * necessary permissions or when the existing value is invalid.
330bf6d0f5dSMimi Zohar  *
331bf6d0f5dSMimi Zohar  * The posix xattr acls are 'system' prefixed, which normally would not
332bf6d0f5dSMimi Zohar  * affect security.evm.  An interesting side affect of writing posix xattr
333bf6d0f5dSMimi Zohar  * acls is their modifying of the i_mode, which is included in security.evm.
334bf6d0f5dSMimi Zohar  * For posix xattr acls only, permit security.evm, even if it currently
33550b97748SMatthew Garrett  * doesn't exist, to be updated unless the EVM signature is immutable.
336a924ce0bSMimi Zohar  */
337a924ce0bSMimi Zohar static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
338a924ce0bSMimi Zohar 			     const void *xattr_value, size_t xattr_value_len)
339a924ce0bSMimi Zohar {
340a924ce0bSMimi Zohar 	enum integrity_status evm_status;
341a924ce0bSMimi Zohar 
342a924ce0bSMimi Zohar 	if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
343a924ce0bSMimi Zohar 		if (!capable(CAP_SYS_ADMIN))
344a924ce0bSMimi Zohar 			return -EPERM;
345bf6d0f5dSMimi Zohar 	} else if (!evm_protected_xattr(xattr_name)) {
346bf6d0f5dSMimi Zohar 		if (!posix_xattr_acl(xattr_name))
347a924ce0bSMimi Zohar 			return 0;
348bf6d0f5dSMimi Zohar 		evm_status = evm_verify_current_integrity(dentry);
349bf6d0f5dSMimi Zohar 		if ((evm_status == INTEGRITY_PASS) ||
350566be59aSMimi Zohar 		    (evm_status == INTEGRITY_NOXATTRS))
351bf6d0f5dSMimi Zohar 			return 0;
3529b97b6cdSMimi Zohar 		goto out;
353bf6d0f5dSMimi Zohar 	}
354ae1ba167SMatthew Garrett 
355a924ce0bSMimi Zohar 	evm_status = evm_verify_current_integrity(dentry);
3563dcbad52SDmitry Kasatkin 	if (evm_status == INTEGRITY_NOXATTRS) {
3573dcbad52SDmitry Kasatkin 		struct integrity_iint_cache *iint;
3583dcbad52SDmitry Kasatkin 
359*4a804b8aSRoberto Sassu 		/* Exception if the HMAC is not going to be calculated. */
360*4a804b8aSRoberto Sassu 		if (evm_hmac_disabled())
361*4a804b8aSRoberto Sassu 			return 0;
362*4a804b8aSRoberto Sassu 
363c6f493d6SDavid Howells 		iint = integrity_iint_find(d_backing_inode(dentry));
3643dcbad52SDmitry Kasatkin 		if (iint && (iint->flags & IMA_NEW_FILE))
3653dcbad52SDmitry Kasatkin 			return 0;
3665101a185SMimi Zohar 
3675101a185SMimi Zohar 		/* exception for pseudo filesystems */
368fc64005cSAl Viro 		if (dentry->d_sb->s_magic == TMPFS_MAGIC
369fc64005cSAl Viro 		    || dentry->d_sb->s_magic == SYSFS_MAGIC)
3705101a185SMimi Zohar 			return 0;
3715101a185SMimi Zohar 
3725101a185SMimi Zohar 		integrity_audit_msg(AUDIT_INTEGRITY_METADATA,
3735101a185SMimi Zohar 				    dentry->d_inode, dentry->d_name.name,
3745101a185SMimi Zohar 				    "update_metadata",
3755101a185SMimi Zohar 				    integrity_status_msg[evm_status],
3765101a185SMimi Zohar 				    -EPERM, 0);
3773dcbad52SDmitry Kasatkin 	}
3789b97b6cdSMimi Zohar out:
379*4a804b8aSRoberto Sassu 	/* Exception if the HMAC is not going to be calculated. */
380*4a804b8aSRoberto Sassu 	if (evm_hmac_disabled() && (evm_status == INTEGRITY_NOLABEL ||
381*4a804b8aSRoberto Sassu 	    evm_status == INTEGRITY_UNKNOWN))
382*4a804b8aSRoberto Sassu 		return 0;
3839b97b6cdSMimi Zohar 	if (evm_status != INTEGRITY_PASS)
384c6f493d6SDavid Howells 		integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry),
3859b97b6cdSMimi Zohar 				    dentry->d_name.name, "appraise_metadata",
3869b97b6cdSMimi Zohar 				    integrity_status_msg[evm_status],
3879b97b6cdSMimi Zohar 				    -EPERM, 0);
388a924ce0bSMimi Zohar 	return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
389a924ce0bSMimi Zohar }
390a924ce0bSMimi Zohar 
39166dbc325SMimi Zohar /**
39266dbc325SMimi Zohar  * evm_inode_setxattr - protect the EVM extended attribute
39366dbc325SMimi Zohar  * @dentry: pointer to the affected dentry
39466dbc325SMimi Zohar  * @xattr_name: pointer to the affected extended attribute name
39566dbc325SMimi Zohar  * @xattr_value: pointer to the new extended attribute value
39666dbc325SMimi Zohar  * @xattr_value_len: pointer to the new extended attribute value length
39766dbc325SMimi Zohar  *
3982fb1c9a4SMimi Zohar  * Before allowing the 'security.evm' protected xattr to be updated,
3992fb1c9a4SMimi Zohar  * verify the existing value is valid.  As only the kernel should have
4002fb1c9a4SMimi Zohar  * access to the EVM encrypted key needed to calculate the HMAC, prevent
4012fb1c9a4SMimi Zohar  * userspace from writing HMAC value.  Writing 'security.evm' requires
4022fb1c9a4SMimi Zohar  * requires CAP_SYS_ADMIN privileges.
40366dbc325SMimi Zohar  */
40466dbc325SMimi Zohar int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
40566dbc325SMimi Zohar 		       const void *xattr_value, size_t xattr_value_len)
40666dbc325SMimi Zohar {
4072fb1c9a4SMimi Zohar 	const struct evm_ima_xattr_data *xattr_data = xattr_value;
4082fb1c9a4SMimi Zohar 
409ae1ba167SMatthew Garrett 	/* Policy permits modification of the protected xattrs even though
410ae1ba167SMatthew Garrett 	 * there's no HMAC key loaded
411ae1ba167SMatthew Garrett 	 */
412ae1ba167SMatthew Garrett 	if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
413ae1ba167SMatthew Garrett 		return 0;
414ae1ba167SMatthew Garrett 
4153b1deef6SDmitry Kasatkin 	if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
4163b1deef6SDmitry Kasatkin 		if (!xattr_value_len)
4173b1deef6SDmitry Kasatkin 			return -EINVAL;
41850b97748SMatthew Garrett 		if (xattr_data->type != EVM_IMA_XATTR_DIGSIG &&
41950b97748SMatthew Garrett 		    xattr_data->type != EVM_XATTR_PORTABLE_DIGSIG)
4202fb1c9a4SMimi Zohar 			return -EPERM;
4213b1deef6SDmitry Kasatkin 	}
422a924ce0bSMimi Zohar 	return evm_protect_xattr(dentry, xattr_name, xattr_value,
42366dbc325SMimi Zohar 				 xattr_value_len);
42466dbc325SMimi Zohar }
42566dbc325SMimi Zohar 
42666dbc325SMimi Zohar /**
42766dbc325SMimi Zohar  * evm_inode_removexattr - protect the EVM extended attribute
42866dbc325SMimi Zohar  * @dentry: pointer to the affected dentry
42966dbc325SMimi Zohar  * @xattr_name: pointer to the affected extended attribute name
43066dbc325SMimi Zohar  *
4317102ebcdSMimi Zohar  * Removing 'security.evm' requires CAP_SYS_ADMIN privileges and that
4327102ebcdSMimi Zohar  * the current value is valid.
43366dbc325SMimi Zohar  */
43466dbc325SMimi Zohar int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
43566dbc325SMimi Zohar {
436ae1ba167SMatthew Garrett 	/* Policy permits modification of the protected xattrs even though
437ae1ba167SMatthew Garrett 	 * there's no HMAC key loaded
438ae1ba167SMatthew Garrett 	 */
439ae1ba167SMatthew Garrett 	if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
440ae1ba167SMatthew Garrett 		return 0;
441ae1ba167SMatthew Garrett 
442a924ce0bSMimi Zohar 	return evm_protect_xattr(dentry, xattr_name, NULL, 0);
44366dbc325SMimi Zohar }
44466dbc325SMimi Zohar 
445523b74b1SDmitry Kasatkin static void evm_reset_status(struct inode *inode)
446523b74b1SDmitry Kasatkin {
447523b74b1SDmitry Kasatkin 	struct integrity_iint_cache *iint;
448523b74b1SDmitry Kasatkin 
449523b74b1SDmitry Kasatkin 	iint = integrity_iint_find(inode);
450523b74b1SDmitry Kasatkin 	if (iint)
451523b74b1SDmitry Kasatkin 		iint->evm_status = INTEGRITY_UNKNOWN;
452523b74b1SDmitry Kasatkin }
453523b74b1SDmitry Kasatkin 
45466dbc325SMimi Zohar /**
455e3ccfe1aSRoberto Sassu  * evm_revalidate_status - report whether EVM status re-validation is necessary
456e3ccfe1aSRoberto Sassu  * @xattr_name: pointer to the affected extended attribute name
457e3ccfe1aSRoberto Sassu  *
458e3ccfe1aSRoberto Sassu  * Report whether callers of evm_verifyxattr() should re-validate the
459e3ccfe1aSRoberto Sassu  * EVM status.
460e3ccfe1aSRoberto Sassu  *
461e3ccfe1aSRoberto Sassu  * Return true if re-validation is necessary, false otherwise.
462e3ccfe1aSRoberto Sassu  */
463e3ccfe1aSRoberto Sassu bool evm_revalidate_status(const char *xattr_name)
464e3ccfe1aSRoberto Sassu {
465e3ccfe1aSRoberto Sassu 	if (!evm_key_loaded())
466e3ccfe1aSRoberto Sassu 		return false;
467e3ccfe1aSRoberto Sassu 
468e3ccfe1aSRoberto Sassu 	/* evm_inode_post_setattr() passes NULL */
469e3ccfe1aSRoberto Sassu 	if (!xattr_name)
470e3ccfe1aSRoberto Sassu 		return true;
471e3ccfe1aSRoberto Sassu 
472e3ccfe1aSRoberto Sassu 	if (!evm_protected_xattr(xattr_name) && !posix_xattr_acl(xattr_name) &&
473e3ccfe1aSRoberto Sassu 	    strcmp(xattr_name, XATTR_NAME_EVM))
474e3ccfe1aSRoberto Sassu 		return false;
475e3ccfe1aSRoberto Sassu 
476e3ccfe1aSRoberto Sassu 	return true;
477e3ccfe1aSRoberto Sassu }
478e3ccfe1aSRoberto Sassu 
479e3ccfe1aSRoberto Sassu /**
48066dbc325SMimi Zohar  * evm_inode_post_setxattr - update 'security.evm' to reflect the changes
48166dbc325SMimi Zohar  * @dentry: pointer to the affected dentry
48266dbc325SMimi Zohar  * @xattr_name: pointer to the affected extended attribute name
48366dbc325SMimi Zohar  * @xattr_value: pointer to the new extended attribute value
48466dbc325SMimi Zohar  * @xattr_value_len: pointer to the new extended attribute value length
48566dbc325SMimi Zohar  *
48666dbc325SMimi Zohar  * Update the HMAC stored in 'security.evm' to reflect the change.
48766dbc325SMimi Zohar  *
48866dbc325SMimi Zohar  * No need to take the i_mutex lock here, as this function is called from
48966dbc325SMimi Zohar  * __vfs_setxattr_noperm().  The caller of which has taken the inode's
49066dbc325SMimi Zohar  * i_mutex lock.
49166dbc325SMimi Zohar  */
49266dbc325SMimi Zohar void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
49366dbc325SMimi Zohar 			     const void *xattr_value, size_t xattr_value_len)
49466dbc325SMimi Zohar {
495e3ccfe1aSRoberto Sassu 	if (!evm_revalidate_status(xattr_name))
49666dbc325SMimi Zohar 		return;
49766dbc325SMimi Zohar 
498523b74b1SDmitry Kasatkin 	evm_reset_status(dentry->d_inode);
499523b74b1SDmitry Kasatkin 
500e3ccfe1aSRoberto Sassu 	if (!strcmp(xattr_name, XATTR_NAME_EVM))
501e3ccfe1aSRoberto Sassu 		return;
502e3ccfe1aSRoberto Sassu 
503*4a804b8aSRoberto Sassu 	if (!(evm_initialized & EVM_INIT_HMAC))
504*4a804b8aSRoberto Sassu 		return;
505*4a804b8aSRoberto Sassu 
50666dbc325SMimi Zohar 	evm_update_evmxattr(dentry, xattr_name, xattr_value, xattr_value_len);
50766dbc325SMimi Zohar }
50866dbc325SMimi Zohar 
50966dbc325SMimi Zohar /**
51066dbc325SMimi Zohar  * evm_inode_post_removexattr - update 'security.evm' after removing the xattr
51166dbc325SMimi Zohar  * @dentry: pointer to the affected dentry
51266dbc325SMimi Zohar  * @xattr_name: pointer to the affected extended attribute name
51366dbc325SMimi Zohar  *
51466dbc325SMimi Zohar  * Update the HMAC stored in 'security.evm' to reflect removal of the xattr.
5157c51bb00SDmitry Kasatkin  *
5167c51bb00SDmitry Kasatkin  * No need to take the i_mutex lock here, as this function is called from
5177c51bb00SDmitry Kasatkin  * vfs_removexattr() which takes the i_mutex.
51866dbc325SMimi Zohar  */
51966dbc325SMimi Zohar void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
52066dbc325SMimi Zohar {
521e3ccfe1aSRoberto Sassu 	if (!evm_revalidate_status(xattr_name))
52266dbc325SMimi Zohar 		return;
52366dbc325SMimi Zohar 
524523b74b1SDmitry Kasatkin 	evm_reset_status(dentry->d_inode);
525523b74b1SDmitry Kasatkin 
526e3ccfe1aSRoberto Sassu 	if (!strcmp(xattr_name, XATTR_NAME_EVM))
527e3ccfe1aSRoberto Sassu 		return;
528e3ccfe1aSRoberto Sassu 
529*4a804b8aSRoberto Sassu 	if (!(evm_initialized & EVM_INIT_HMAC))
530*4a804b8aSRoberto Sassu 		return;
531*4a804b8aSRoberto Sassu 
53266dbc325SMimi Zohar 	evm_update_evmxattr(dentry, xattr_name, NULL, 0);
53366dbc325SMimi Zohar }
53466dbc325SMimi Zohar 
53566dbc325SMimi Zohar /**
536817b54aaSMimi Zohar  * evm_inode_setattr - prevent updating an invalid EVM extended attribute
537817b54aaSMimi Zohar  * @dentry: pointer to the affected dentry
53850b97748SMatthew Garrett  *
53950b97748SMatthew Garrett  * Permit update of file attributes when files have a valid EVM signature,
54050b97748SMatthew Garrett  * except in the case of them having an immutable portable signature.
541817b54aaSMimi Zohar  */
542817b54aaSMimi Zohar int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
543817b54aaSMimi Zohar {
544817b54aaSMimi Zohar 	unsigned int ia_valid = attr->ia_valid;
545817b54aaSMimi Zohar 	enum integrity_status evm_status;
546817b54aaSMimi Zohar 
547ae1ba167SMatthew Garrett 	/* Policy permits modification of the protected attrs even though
548ae1ba167SMatthew Garrett 	 * there's no HMAC key loaded
549ae1ba167SMatthew Garrett 	 */
550ae1ba167SMatthew Garrett 	if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
551ae1ba167SMatthew Garrett 		return 0;
552ae1ba167SMatthew Garrett 
553a924ce0bSMimi Zohar 	if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
554817b54aaSMimi Zohar 		return 0;
555817b54aaSMimi Zohar 	evm_status = evm_verify_current_integrity(dentry);
556566be59aSMimi Zohar 	if ((evm_status == INTEGRITY_PASS) ||
557*4a804b8aSRoberto Sassu 	    (evm_status == INTEGRITY_NOXATTRS) ||
558*4a804b8aSRoberto Sassu 	    (evm_hmac_disabled() && (evm_status == INTEGRITY_NOLABEL ||
559*4a804b8aSRoberto Sassu 	     evm_status == INTEGRITY_UNKNOWN)))
560566be59aSMimi Zohar 		return 0;
561c6f493d6SDavid Howells 	integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry),
5629b97b6cdSMimi Zohar 			    dentry->d_name.name, "appraise_metadata",
5639b97b6cdSMimi Zohar 			    integrity_status_msg[evm_status], -EPERM, 0);
564566be59aSMimi Zohar 	return -EPERM;
565817b54aaSMimi Zohar }
566817b54aaSMimi Zohar 
567817b54aaSMimi Zohar /**
56866dbc325SMimi Zohar  * evm_inode_post_setattr - update 'security.evm' after modifying metadata
56966dbc325SMimi Zohar  * @dentry: pointer to the affected dentry
57066dbc325SMimi Zohar  * @ia_valid: for the UID and GID status
57166dbc325SMimi Zohar  *
57266dbc325SMimi Zohar  * For now, update the HMAC stored in 'security.evm' to reflect UID/GID
57366dbc325SMimi Zohar  * changes.
57466dbc325SMimi Zohar  *
57566dbc325SMimi Zohar  * This function is called from notify_change(), which expects the caller
57666dbc325SMimi Zohar  * to lock the inode's i_mutex.
57766dbc325SMimi Zohar  */
57866dbc325SMimi Zohar void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
57966dbc325SMimi Zohar {
580e3ccfe1aSRoberto Sassu 	if (!evm_revalidate_status(NULL))
58166dbc325SMimi Zohar 		return;
58266dbc325SMimi Zohar 
583e3ccfe1aSRoberto Sassu 	evm_reset_status(dentry->d_inode);
584e3ccfe1aSRoberto Sassu 
585*4a804b8aSRoberto Sassu 	if (!(evm_initialized & EVM_INIT_HMAC))
586*4a804b8aSRoberto Sassu 		return;
587*4a804b8aSRoberto Sassu 
58866dbc325SMimi Zohar 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
58966dbc325SMimi Zohar 		evm_update_evmxattr(dentry, NULL, NULL, 0);
59066dbc325SMimi Zohar }
59166dbc325SMimi Zohar 
592cb723180SMimi Zohar /*
5939eea2904SRoberto Sassu  * evm_inode_init_security - initializes security.evm HMAC value
594cb723180SMimi Zohar  */
595cb723180SMimi Zohar int evm_inode_init_security(struct inode *inode,
596cb723180SMimi Zohar 				 const struct xattr *lsm_xattr,
597cb723180SMimi Zohar 				 struct xattr *evm_xattr)
598cb723180SMimi Zohar {
599650b29dbSThiago Jung Bauermann 	struct evm_xattr *xattr_data;
600cb723180SMimi Zohar 	int rc;
601cb723180SMimi Zohar 
6029eea2904SRoberto Sassu 	if (!(evm_initialized & EVM_INIT_HMAC) ||
6039eea2904SRoberto Sassu 	    !evm_protected_xattr(lsm_xattr->name))
6045a4730baSMimi Zohar 		return 0;
605cb723180SMimi Zohar 
606cb723180SMimi Zohar 	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
607cb723180SMimi Zohar 	if (!xattr_data)
608cb723180SMimi Zohar 		return -ENOMEM;
609cb723180SMimi Zohar 
610650b29dbSThiago Jung Bauermann 	xattr_data->data.type = EVM_XATTR_HMAC;
611cb723180SMimi Zohar 	rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
612cb723180SMimi Zohar 	if (rc < 0)
613cb723180SMimi Zohar 		goto out;
614cb723180SMimi Zohar 
615cb723180SMimi Zohar 	evm_xattr->value = xattr_data;
616cb723180SMimi Zohar 	evm_xattr->value_len = sizeof(*xattr_data);
6179548906bSTetsuo Handa 	evm_xattr->name = XATTR_EVM_SUFFIX;
618cb723180SMimi Zohar 	return 0;
619cb723180SMimi Zohar out:
620cb723180SMimi Zohar 	kfree(xattr_data);
621cb723180SMimi Zohar 	return rc;
622cb723180SMimi Zohar }
623cb723180SMimi Zohar EXPORT_SYMBOL_GPL(evm_inode_init_security);
624cb723180SMimi Zohar 
6252ce523ebSDmitry Kasatkin #ifdef CONFIG_EVM_LOAD_X509
6262ce523ebSDmitry Kasatkin void __init evm_load_x509(void)
6272ce523ebSDmitry Kasatkin {
62826ddabfeSDmitry Kasatkin 	int rc;
62926ddabfeSDmitry Kasatkin 
63026ddabfeSDmitry Kasatkin 	rc = integrity_load_x509(INTEGRITY_KEYRING_EVM, CONFIG_EVM_X509_PATH);
63126ddabfeSDmitry Kasatkin 	if (!rc)
63226ddabfeSDmitry Kasatkin 		evm_initialized |= EVM_INIT_X509;
6332ce523ebSDmitry Kasatkin }
6342ce523ebSDmitry Kasatkin #endif
6352ce523ebSDmitry Kasatkin 
63666dbc325SMimi Zohar static int __init init_evm(void)
63766dbc325SMimi Zohar {
63866dbc325SMimi Zohar 	int error;
63921af7663SMatthew Garrett 	struct list_head *pos, *q;
64066dbc325SMimi Zohar 
641d3b33679SDmitry Kasatkin 	evm_init_config();
642d3b33679SDmitry Kasatkin 
643f4dc3778SDmitry Kasatkin 	error = integrity_init_keyring(INTEGRITY_KEYRING_EVM);
644f4dc3778SDmitry Kasatkin 	if (error)
64521af7663SMatthew Garrett 		goto error;
646f4dc3778SDmitry Kasatkin 
64766dbc325SMimi Zohar 	error = evm_init_secfs();
64866dbc325SMimi Zohar 	if (error < 0) {
64920ee451fSJoe Perches 		pr_info("Error registering secfs\n");
65021af7663SMatthew Garrett 		goto error;
65121af7663SMatthew Garrett 	}
65221af7663SMatthew Garrett 
65321af7663SMatthew Garrett error:
65421af7663SMatthew Garrett 	if (error != 0) {
65521af7663SMatthew Garrett 		if (!list_empty(&evm_config_xattrnames)) {
656c8b37524SYueHaibing 			list_for_each_safe(pos, q, &evm_config_xattrnames)
65721af7663SMatthew Garrett 				list_del(pos);
65821af7663SMatthew Garrett 		}
65921af7663SMatthew Garrett 	}
66021af7663SMatthew Garrett 
661f4dc3778SDmitry Kasatkin 	return error;
66266dbc325SMimi Zohar }
66315647eb3SDmitry Kasatkin 
66466dbc325SMimi Zohar late_initcall(init_evm);
665