IMA: Deferred measurement of keys
Subsystems (5)
v7 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:
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
PATCH v7 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
@@ -205,6 +205,21 @@ extern const char *const func_tokens[];struct modsig ; +#ifdef CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE +/* +* 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_ASYMMETRIC_PUBLIC_KEY_SUBTYPE */ +/* 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
PATCH v7 2/3 IMA: Call workqueue functions to measure queued keys
In reply to Lakshmi RamasubramanianMeasuring 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
@@ -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
@@ -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
PATCH v7 3/3 IMA: Defined timer to free queued keys
In reply to Lakshmi Ramasubramaniankeys 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
--- 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
@@ -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_ASYMMETRIC_PUBLIC_KEY_SUBTYPE */ /* 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
@@ -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