From: Roberto Sassu <roberto.sa...@huawei.com>

Specify the 'digest_cache_measure' boot-time policy with 'ima_policy=' in
the kernel command line to add the following rule at the beginning of the
IMA policy, before other rules:

measure func=DIGEST_LIST_CHECK pcr=12

which will measure digest lists into PCR 12 (or the value in
CONFIG_IMA_DIGEST_CACHE_MEASURE_PCR_IDX).

'digest_cache_measure' also adds 'digest_cache=content pcr=12' to the other
measure rules, if they have a compatible IMA hook. The PCR value still
comes from CONFIG_IMA_DIGEST_CACHE_MEASURE_PCR_IDX.

Specify 'digest_cache_appraise' to add the following rule at the beginning,
before other rules:

appraise func=DIGEST_LIST_CHECK appraise_type=imasig|modsig

which will appraise digest lists with IMA signatures or module-style
appended signatures.

'digest_cache_appraise' also adds 'digest_cache=content' to the other
appraise rules, if they have a compatible IMA hook.

Signed-off-by: Roberto Sassu <roberto.sa...@huawei.com>
---
 .../admin-guide/kernel-parameters.txt         | 15 ++++++-
 security/integrity/ima/Kconfig                | 10 +++++
 security/integrity/ima/ima_policy.c           | 45 +++++++++++++++++++
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 31b3a25680d0..a79967fcba7d 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2011,7 +2011,8 @@
        ima_policy=     [IMA]
                        The builtin policies to load during IMA setup.
                        Format: "tcb | appraise_tcb | secure_boot |
-                                fail_securely | critical_data"
+                                fail_securely | critical_data |
+                                digest_cache_measure | digest_cache_appraise"
 
                        The "tcb" policy measures all programs exec'd, files
                        mmap'd for exec, and all files opened with the read
@@ -2033,6 +2034,18 @@
                        The "critical_data" policy measures kernel integrity
                        critical data.
 
+                       The "digest_cache_measure" policy measures digest lists
+                       into PCR 12 (can be changed with kernel config), enables
+                       the digest cache to be used for the other selected
+                       measure rules (if compatible), and measures the files
+                       with digest not found in the digest list into PCR 12
+                       (changeable).
+
+                       The "digest_cache_appraise" policy appraises digest
+                       lists with IMA signatures or module-style appended
+                       signatures, and enables the digest cache to be used for
+                       the other selected appraise rules (if compatible).
+
        ima_tcb         [IMA] Deprecated.  Use ima_policy= instead.
                        Load a policy which meets the needs of the Trusted
                        Computing Base.  This means IMA will measure all
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 475c32615006..6a481019fb6e 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -321,4 +321,14 @@ config IMA_DISABLE_HTABLE
        help
           This option disables htable to allow measurement of duplicate 
records.
 
+config IMA_DIGEST_CACHE_MEASURE_PCR_IDX
+       int
+       range 8 14
+       default 12
+       help
+         This option determines the TPM PCR register index that IMA uses to
+         maintain the integrity aggregate of the measurement list, when the
+         digest_cache LSM is used (different measurement style).  If unsure,
+         use the default 12.
+
 endif
diff --git a/security/integrity/ima/ima_policy.c 
b/security/integrity/ima/ima_policy.c
index 4ac83df8d255..04127f962ef4 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -254,6 +254,21 @@ static struct ima_rule_entry critical_data_rules[] 
__ro_after_init = {
        {.action = MEASURE, .func = CRITICAL_DATA, .flags = IMA_FUNC},
 };
 
+static struct ima_rule_entry measure_digest_cache_rule __ro_after_init = {
+#ifdef CONFIG_SECURITY_DIGEST_CACHE
+       .action = MEASURE, .func = DIGEST_LIST_CHECK,
+       .pcr = CONFIG_IMA_DIGEST_CACHE_MEASURE_PCR_IDX,
+       .flags = IMA_FUNC | IMA_PCR
+#endif
+};
+
+static struct ima_rule_entry appraise_digest_cache_rule __ro_after_init = {
+#ifdef CONFIG_SECURITY_DIGEST_CACHE
+       .action = APPRAISE, .func = DIGEST_LIST_CHECK,
+       .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED,
+#endif
+};
+
 /* An array of architecture specific rules */
 static struct ima_rule_entry *arch_policy_entry __ro_after_init;
 
@@ -278,6 +293,8 @@ static bool ima_use_appraise_tcb __initdata;
 static bool ima_use_secure_boot __initdata;
 static bool ima_use_critical_data __initdata;
 static bool ima_fail_unverifiable_sigs __ro_after_init;
+static bool ima_digest_cache_measure __ro_after_init;
+static bool ima_digest_cache_appraise __ro_after_init;
 static int __init policy_setup(char *str)
 {
        char *p;
@@ -295,6 +312,10 @@ static int __init policy_setup(char *str)
                        ima_use_critical_data = true;
                else if (strcmp(p, "fail_securely") == 0)
                        ima_fail_unverifiable_sigs = true;
+               else if (strcmp(p, "digest_cache_measure") == 0)
+                       ima_digest_cache_measure = true;
+               else if (strcmp(p, "digest_cache_appraise") == 0)
+                       ima_digest_cache_appraise = true;
                else
                        pr_err("policy \"%s\" not found", p);
        }
@@ -897,6 +918,20 @@ static void add_rules(struct ima_rule_entry *entries, int 
count,
        for (i = 0; i < count; i++) {
                struct ima_rule_entry *entry;
 
+               if (IS_ENABLED(CONFIG_SECURITY_DIGEST_CACHE) &&
+                   entries[i].action == MEASURE && ima_digest_cache_measure &&
+                   ima_digest_cache_func_allowed(&entries[i])) {
+                       entries[i].digest_cache_mask |= 
IMA_DIGEST_CACHE_MEASURE_CONTENT;
+                       entries[i].pcr = 
CONFIG_IMA_DIGEST_CACHE_MEASURE_PCR_IDX;
+                       entries[i].flags |= IMA_PCR;
+               }
+
+               if (IS_ENABLED(CONFIG_SECURITY_DIGEST_CACHE) &&
+                   entries[i].action == APPRAISE &&
+                   ima_digest_cache_appraise &&
+                   ima_digest_cache_func_allowed(&entries[i]))
+                       entries[i].digest_cache_mask |= 
IMA_DIGEST_CACHE_APPRAISE_CONTENT;
+
                if (policy_rule & IMA_DEFAULT_POLICY)
                        list_add_tail(&entries[i].list, &ima_default_rules);
 
@@ -971,6 +1006,16 @@ void __init ima_init_policy(void)
 {
        int build_appraise_entries, arch_entries;
 
+       /*
+        * We need to load digest cache rules at the beginning, to avoid dont_
+        * rules causing ours to not be reached.
+        */
+       if (ima_digest_cache_measure)
+               add_rules(&measure_digest_cache_rule, 1, IMA_DEFAULT_POLICY);
+
+       if (ima_digest_cache_appraise)
+               add_rules(&appraise_digest_cache_rule, 1, IMA_DEFAULT_POLICY);
+
        /* if !ima_policy, we load NO default rules */
        if (ima_policy)
                add_rules(dont_measure_rules, ARRAY_SIZE(dont_measure_rules),
-- 
2.34.1


Reply via email to