Data provided by security modules need to be measured. A new IMA policy is required for handling this measurement. Define a new IMA policy func namely LSM_STATE to measure data provided by security modules. Update ima_match_rules() to check for LSM_STATE and ima_parse_rule() to handle LSM_STATE. Signed-off-by: Lakshmi Ramasubramanian <nramas@xxxxxxxxxxxxxxxxxxx> --- Documentation/ABI/testing/ima_policy | 6 +++++- security/integrity/ima/ima.h | 1 + security/integrity/ima/ima_api.c | 2 +- security/integrity/ima/ima_policy.c | 28 +++++++++++++++++++++++----- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index cd572912c593..355bc3eade33 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -29,7 +29,7 @@ Description: base: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK] [FIRMWARE_CHECK] [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] - [KEXEC_CMDLINE] [KEY_CHECK] + [KEXEC_CMDLINE] [KEY_CHECK] [LSM_STATE] mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] [[^]MAY_EXEC] fsmagic:= hex value @@ -125,3 +125,7 @@ Description: keys added to .builtin_trusted_keys or .ima keyring: measure func=KEY_CHECK keyrings=.builtin_trusted_keys|.ima + + Example of measure rule using LSM_STATE to measure LSM data: + + measure func=LSM_STATE diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index df93ac258e01..58c62269028a 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -200,6 +200,7 @@ static inline unsigned int ima_hash_key(u8 *digest) hook(POLICY_CHECK) \ hook(KEXEC_CMDLINE) \ hook(KEY_CHECK) \ + hook(LSM_STATE) \ hook(MAX_CHECK) #define __ima_hook_enumify(ENUM) ENUM, diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index bf22de8b7ce0..0cebd2404dcf 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -176,7 +176,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * subj=, obj=, type=, func=, mask=, fsmagic= * subj,obj, and type: are LSM specific. * func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK - * | KEXEC_CMDLINE | KEY_CHECK + * | KEXEC_CMDLINE | KEY_CHECK | LSM_STATE * mask: contains the permission mask * fsmagic: hex value * diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index e493063a3c34..1a6ee09e6993 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -417,15 +417,31 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, const char *keyring) { int i; + int funcmatch = 0; - if ((func == KEXEC_CMDLINE) || (func == KEY_CHECK)) { + switch (func) { + case KEXEC_CMDLINE: + case KEY_CHECK: + case LSM_STATE: if ((rule->flags & IMA_FUNC) && (rule->func == func)) { if (func == KEY_CHECK) - return ima_match_keyring(rule, keyring, cred); - return true; - } - return false; + funcmatch = ima_match_keyring(rule, keyring, + cred) ? 1 : -1; + else + funcmatch = 1; + } else + funcmatch = -1; + + break; + + default: + funcmatch = 0; + break; } + + if (funcmatch) + return (funcmatch == 1) ? true : false; + if ((rule->flags & IMA_FUNC) && (rule->func != func && func != POST_SETATTR)) return false; @@ -1068,6 +1084,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->func = KEXEC_CMDLINE; else if (strcmp(args[0].from, "KEY_CHECK") == 0) entry->func = KEY_CHECK; + else if (strcmp(args[0].from, "LSM_STATE") == 0) + entry->func = LSM_STATE; else result = -EINVAL; if (!result) -- 2.27.0