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@xxxxxxxxx> Signed-off-by: Song Liu <song@xxxxxxxxxx> --- 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