Skip to contentSkip to conversation

IMA: Deferred measurement of keys

PATCH Superseded Lakshmi Ramasubramanian 2 participants 6 messages Jan 9, 2020

Subsystems (5)

v8 of 9 Superseded Latest is v9 →

lore
Share & tools
lore
#0 lore raw

v8 cover IMA: Deferred measurement of keys

The IMA subsystem supports measuring asymmetric keys when the key is created or updated[1]. But keys created or updated before a custom IMA policy is loaded are currently not measured. This includes keys added, for instance, to either the .ima or .builtin_trusted_keys keyrings, which happens early in the boot process.

Measuring the early boot keys, by design, requires loading
a custom IMA policy. This change adds support for queuing keys created or updated before a custom IMA policy is loaded.
The queued keys are processed when a custom policy is loaded. Keys created or updated after a custom policy is loaded are measured immediately (not queued). In the case when a custom policy is not loaded within 5 minutes of IMA initialization, the queued keys are freed.

[1] https://lore.kernel.org/linux-integrity/[email protected]/

Testing performed:

* Ran kernel self-test following the instructions given in
https://www.kernel.org/doc/Documentation/kselftest.txt
* Ran the lkp-tests using the job script provided by kernel test robot <[email protected]>
* Booted the kernel with this change.
* Added .builtin_trusted_keys in "keyrings=" option in the IMA policy and verified the keys added to this keyring are measured.
* Specified only func=KEY_CHECK and not "keyrings=" option, and verified the keys added to builtin_trusted_keys keyring are processed.
* Added keys at runtime and verified they are measured if the IMA policy permitted.
=> For example, added keys to .ima keyring and verified.

Changelog:

v8

=> Rebased the changes to linux-next
=> Need to apply the following patch first
https://lore.kernel.org/linux-integrity/[email protected]/

v7

=> Updated cover letter per Mimi's suggestions. => Updated "Reported-by" tag to be specific about
the issues fixed in the patch.

v6

=> Replaced mutex with a spinlock to sychronize access to
queued keys. This fixes the problem reported by "kernel test robot <[email protected]>"
https://lore.kernel.org/linux-integrity/[email protected]/T/#t
=> Changed ima_queue_key() to a static function. This fixes
the issue reported by "kbuild test robot <[email protected]>"
https://lore.kernel.org/linux-integrity/[email protected]/
=> Added the patch to free the queued keys if a custom IMA policy
was not loaded to this patch set.

v5

=> Removed temp keys list in ima_process_queued_keys()

v4

=> Check and set ima_process_keys flag with mutex held.

v3

=> Defined ima_process_keys flag to be static. => Set ima_process_keys with ima_keys_mutex held. => Added a comment in ima_process_queued_keys() function
to state the use of temporary list for keys.

v2

=> Rebased the changes to v5.5-rc1
=> Updated function names, variable names, and code comments
to be less verbose.

v1

=> Code cleanup

v0

=> Based changes on v5.4-rc8
=> The following patchsets should be applied in that order

     https://lore.kernel.org/linux-integrity/[email protected]
     https://lore.kernel.org/linux-integrity/[email protected]/

=> Added functions to queue and dequeue keys, and process
the queued keys when custom IMA policies are applied.

Lakshmi Ramasubramanian (3):
IMA: Define workqueue for early boot key measurements
IMA: Call workqueue functions to measure queued keys
IMA: Defined timer to free queued keys

 security/integrity/ima/ima.h                 |  17 ++
 security/integrity/ima/ima_asymmetric_keys.c | 159 +++++++++++++++++++
 security/integrity/ima/ima_init.c            |   8 +-
 security/integrity/ima/ima_policy.c          |   3 +
 4 files changed, 186 insertions(+), 1 deletion(-)
Signature · 1 line
2.17.1
#1 lore raw

PATCH v8 1/3 IMA: Define workqueue for early boot key measurements

Measuring keys requires a custom IMA policy to be loaded. Keys created or updated before a custom IMA policy is loaded should be queued and the keys should be processed after a custom policy is loaded.

This patch defines workqueue for queuing keys when a custom IMA policy has not yet been loaded.

A flag namely ima_process_keys is used to check if the key should be queued or should be processed immediately.

function called from invalid context

ima_queued_key() should be static

---
 security/integrity/ima/ima.h                 |  15 +++
 security/integrity/ima/ima_asymmetric_keys.c | 115 +++++++++++++++++++
 2 files changed, 130 insertions(+)
security/integrity/ima/ima.h +15 -0
index f06238e41a7c..c7fdf3d66b98 100644
@@ -205,6 +205,21 @@ extern const char *const func_tokens[];
 
 struct modsig;
 
+#ifdef CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS
+/*
+ * To track keys that need to be measured.
+ */
+struct ima_key_entry {
+	struct list_head list;
+	void *payload;
+	size_t payload_len;
+	char *keyring_name;
+};
+void ima_process_queued_keys(void);
+#else
+static inline void ima_process_queued_keys(void) {}
+#endif /* CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS */
+
 /* LIM API function definitions */
 int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid,
 		   int mask, enum ima_hooks func, int *pcr,
security/integrity/ima/ima_asymmetric_keys.c +115 -0

121 lines not on this page · raw message

Signature · 1 line
2.17.1
#2 lore raw

PATCH v8 2/3 IMA: Call workqueue functions to measure queued keys

In reply to Lakshmi Ramasubramanian

Measuring keys requires a custom IMA policy to be loaded. Keys should be queued for measurement if a custom IMA policy is not yet loaded. Keys queued for measurement, if any, should be processed when a custom IMA policy is loaded.

This patch updates the IMA hook function ima_post_key_create_or_update() to queue the key if a custom IMA policy has not yet been loaded. And, ima_update_policy() function, which is called when
a custom IMA policy is loaded, is updated to process queued keys.

---
 security/integrity/ima/ima_asymmetric_keys.c | 8 ++++++++
 security/integrity/ima/ima_policy.c          | 3 +++
 2 files changed, 11 insertions(+)
security/integrity/ima/ima_asymmetric_keys.c +8 -0
index 1d56f003f1a7..eb71cbf224c1 100644
@@ -145,6 +145,8 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key,
 				   const void *payload, size_t payload_len,
 				   unsigned long flags, bool create)
 {
+	bool queued = false;
+
 	/* Only asymmetric keys are handled by this hook. */
 	if (key->type != &key_type_asymmetric)
 		return;
@@ -152,6 +154,12 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key,
 	if (!payload || (payload_len = 0))
 		return;
 
+	if (!ima_process_keys)
+		queued = ima_queue_key(keyring, payload, payload_len);
+
+	if (queued)
+		return;
+
 	/*
 	 * keyring->description points to the name of the keyring
 	 * (such as ".builtin_trusted_keys", ".ima", etc.) to
security/integrity/ima/ima_policy.c +3 -0
index 8f2ca487753b..1bdda05d963b 100644
@@ -807,6 +807,9 @@ void ima_update_policy(void)
 		kfree(arch_policy_entry);
 	}
 	ima_update_policy_flag();
+
+	/* Custom IMA policy has been loaded */
+	ima_process_queued_keys();
 }
 
 /* Keep the enumeration in sync with the policy_tokens! */
Signature · 1 line
2.17.1
#3 lore raw

PATCH v8 3/3 IMA: Defined timer to free queued keys

In reply to Lakshmi Ramasubramanian

keys queued for measurement should be freed if a custom IMA policy was not loaded. Otherwise, the keys will remain queued forever consuming kernel memory.

This patch defines a timer to handle the above scenario. The timer is setup to expire 5 minutes after IMA initialization is completed.

If a custom IMA policy is loaded before the timer expires, the timer is removed and any queued keys are processed for measurement. But if a custom policy was not loaded, on timer expiration queued keys are just freed.

function called from invalid context

ima_init_key_queue() function.

---
 security/integrity/ima/ima.h                 |  2 +
 security/integrity/ima/ima_asymmetric_keys.c | 42 ++++++++++++++++++--
 security/integrity/ima/ima_init.c            |  8 +++-
 3 files changed, 48 insertions(+), 4 deletions(-)
security/integrity/ima/ima.h +2 -0
index c7fdf3d66b98..6bb3152b3e24 100644
@@ -216,8 +216,10 @@ struct ima_key_entry {
 	char *keyring_name;
 };
 void ima_process_queued_keys(void);
+void ima_init_key_queue(void);
 #else
 static inline void ima_process_queued_keys(void) {}
+static inline void ima_init_key_queue(void) {}
 #endif /* CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS */
 
 /* LIM API function definitions */
security/integrity/ima/ima_asymmetric_keys.c +39 -3

61 lines not on this page · raw message

security/integrity/ima/ima_init.c +7 -1
index 5d55ade5f3b9..195cb4079b2b 100644
@@ -131,5 +131,11 @@ int __init ima_init(void)
 
 	ima_init_policy();
 
-	return ima_fs_init();
+	rc = ima_fs_init();
+	if (rc != 0)
+		return rc;
+
+	ima_init_key_queue();
+
+	return rc;
 }
Signature · 1 line
2.17.1
#5 lore raw
Quoted 10 lines · Mimi Zohar
Quoted 7 lines · Lakshmi Ramasubramanian

Changelog:

v8

=> Rebased the changes to linux-next
=> Need to apply the following patch first
https://lore.kernel.org/linux-integrity/[email protected]/

Quoted 6 lines

Unless you made some other changes, the previous version of this patch set is already in next-integrity-testing.  There's no reason to re- post these patches again, and definitely not against linux-next.

Mimi

The change was to integrate the changes from the patch for the CONFIG issue:

https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git/commit/?h=next-integrity-testing&idPa2506e069fc71f4be1bbcc2c5534bf58ed94ab

The following commit needs to be updated to use the new config CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS instead of CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE

https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git/commit/?h=next-integrity-testing&idá64a1695a5705c24c897b0bc7e9b97abb0830c8

Please let me know if I can clone next-integrity-testing and make the above update. I'll post the updated patch today.

thanks,
-lakshmi