[RFC 2/2] evm: Add kernel parameter to disable EVM

Song Liu song at kernel.org
Tue Dec 17 20:25:25 UTC 2024


This patch provides kernel parameter 'evm=' that disables EVM.
This will reduce memory consumption by the EVM when it is not needed.
Specifically, this saves one evm_iint_cache per inode in the system.

Originally-by: Dmitry Kasatkin <dmitry.kasatkin at gmail.com>
Signed-off-by: Song Liu <song at kernel.org>
---
 security/integrity/evm/evm.h       |  6 ++++++
 security/integrity/evm/evm_main.c  | 22 ++++++++++++++--------
 security/integrity/evm/evm_secfs.c |  3 ++-
 3 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index 51aba5a54275..64428c35e4cf 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -17,6 +17,10 @@
 
 #include "../integrity.h"
 
+#define EVM_MODE_OFF	0
+#define EVM_MODE_ON	1
+#define EVM_MODE_FIX	2
+
 #define EVM_INIT_HMAC	0x0001
 #define EVM_INIT_X509	0x0002
 #define EVM_ALLOW_METADATA_WRITES	0x0004
@@ -26,6 +30,8 @@
 #define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \
 		       EVM_ALLOW_METADATA_WRITES)
 
+extern int evm_mode;
+
 struct xattr_list {
 	struct list_head list;
 	char *name;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 377e57e9084f..738c38f8190d 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -72,17 +72,19 @@ static struct xattr_list evm_config_default_xattrnames[] = {
 
 LIST_HEAD(evm_config_xattrnames);
 
-static int evm_fixmode __ro_after_init;
-static int __init evm_set_fixmode(char *str)
+int evm_mode __ro_after_init = EVM_MODE_ON;
+
+static int __init evm_setup(char *str)
 {
-	if (strncmp(str, "fix", 3) == 0)
-		evm_fixmode = 1;
+	if (strncmp(str, "off", 3) == 0)
+		evm_mode = EVM_MODE_OFF;
+	else if (strncmp(str, "fix", 3) == 0)
+		evm_mode = EVM_MODE_FIX;
 	else
 		pr_err("invalid \"%s\" mode", str);
-
-	return 1;
+	return 0;
 }
-__setup("evm=", evm_set_fixmode);
+__setup("evm=", evm_setup);
 
 static void __init evm_init_config(void)
 {
@@ -441,7 +443,7 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
 {
 	struct inode *inode = d_backing_inode(dentry);
 
-	if (!evm_key_loaded() || !S_ISREG(inode->i_mode) || evm_fixmode)
+	if (!evm_key_loaded() || !S_ISREG(inode->i_mode) || evm_mode == EVM_MODE_FIX)
 		return INTEGRITY_PASS;
 	return evm_verify_hmac(dentry, NULL, NULL, 0);
 }
@@ -1117,6 +1119,9 @@ static int __init init_evm(void)
 	int error;
 	struct list_head *pos, *q;
 
+	if (evm_mode == EVM_MODE_OFF)
+		return 0;
+
 	evm_init_config();
 
 	error = integrity_init_keyring(INTEGRITY_KEYRING_EVM);
@@ -1178,6 +1183,7 @@ DEFINE_LSM(evm) = {
 	.name = "evm",
 	.init = init_evm_lsm,
 	.order = LSM_ORDER_LAST,
+	.enabled = &evm_mode,
 	.blobs = &evm_blob_sizes,
 };
 
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index 9b907c2fee60..65f896cb838e 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -69,7 +69,8 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf,
 	unsigned int i;
 	int ret;
 
-	if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP_COMPLETE))
+	if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP_COMPLETE) ||
+	    evm_mode == EVM_MODE_OFF)
 		return -EPERM;
 
 	ret = kstrtouint_from_user(buf, count, 0, &i);
-- 
2.43.5




More information about the Linux-security-module-archive mailing list