On Tue, 2019-12-24 at 10:01 -0800, Lakshmi Ramasubramanian wrote: > 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. > > Signed-off-by: Lakshmi Ramasubramanian <nramas@xxxxxxxxxxxxxxxxxxx> Thanks. This patch is now queued in next-integrity-testing. Mimi > --- > 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(-) > > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h > index 97f8a4078483..c483215a9ee5 100644 > --- a/security/integrity/ima/ima.h > +++ b/security/integrity/ima/ima.h > @@ -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 */ > diff --git a/security/integrity/ima/ima_asymmetric_keys.c b/security/integrity/ima/ima_asymmetric_keys.c > index 4124f10ff0c2..9ea2233c911a 100644 > --- a/security/integrity/ima/ima_asymmetric_keys.c > +++ b/security/integrity/ima/ima_asymmetric_keys.c > @@ -11,6 +11,7 @@ > > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > +#include <linux/timer.h> > #include <keys/asymmetric-type.h> > #include "ima.h" > > @@ -26,6 +27,36 @@ static bool ima_process_keys; > static DEFINE_MUTEX(ima_keys_mutex); > static LIST_HEAD(ima_keys); > > +/* > + * If custom IMA policy is not loaded then keys queued up > + * for measurement should be freed. This timer is used > + * for handling this scenario. > + */ > +static long ima_key_queue_timeout = 300000; /* 5 Minutes */ > +static struct timer_list ima_key_queue_timer; > +static bool timer_expired; > + > +/* > + * This timer callback function frees keys that may still be > + * queued up in case custom IMA policy was not loaded. > + */ > +static void ima_timer_handler(struct timer_list *timer) > +{ > + timer_expired = true; > + ima_process_queued_keys(); > +} > + > +/* > + * This function sets up a timer to free queued keys in case > + * custom IMA policy was never loaded. > + */ > +void ima_init_key_queue(void) > +{ > + timer_setup(&ima_key_queue_timer, ima_timer_handler, 0); > + mod_timer(&ima_key_queue_timer, > + jiffies + msecs_to_jiffies(ima_key_queue_timeout)); > +} > + > static void ima_free_key_entry(struct ima_key_entry *entry) > { > if (entry) { > @@ -120,10 +151,15 @@ void ima_process_queued_keys(void) > if (!process) > return; > > + del_timer(&ima_key_queue_timer); > + > list_for_each_entry_safe(entry, tmp, &ima_keys, list) { > - process_buffer_measurement(entry->payload, entry->payload_len, > - entry->keyring_name, KEY_CHECK, 0, > - entry->keyring_name); > + if (!timer_expired) > + process_buffer_measurement(entry->payload, > + entry->payload_len, > + entry->keyring_name, > + KEY_CHECK, 0, > + entry->keyring_name); > list_del(&entry->list); > ima_free_key_entry(entry); > } > diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c > index 5d55ade5f3b9..195cb4079b2b 100644 > --- a/security/integrity/ima/ima_init.c > +++ b/security/integrity/ima/ima_init.c > @@ -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; > }