@@ -90,3 +90,34 @@ void ima_digest_cache_update_allowed_usage(struct file *file,
out:
digest_cache_put(digest_cache);
}
+
+static int ima_digest_cache_change(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct ima_iint_cache *iint;
+ struct digest_cache_event_data *event_data = data;
+
+ if (event != DIGEST_CACHE_RESET)
+ return NOTIFY_DONE;
+
+ iint = ima_iint_find(event_data->inode);
+ if (!iint) {
+ pr_debug("Integrity metadata not found for inode %lu\n",
+ event_data->inode->i_ino);
+ return NOTIFY_OK;
+ }
+
+ set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags);
+ pr_debug("Integrity metadata of inode %lu successfully reset\n",
+ event_data->inode->i_ino);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block digest_cache_notifier = {
+ .notifier_call = ima_digest_cache_change,
+};
+
+int ima_digest_cache_register_notifier(void)
+{
+ return digest_cache_register_notifier(&digest_cache_notifier);
+}
@@ -15,6 +15,7 @@ void ima_digest_cache_store_allowed_usage(struct file *file,
void ima_digest_cache_update_allowed_usage(struct file *file,
struct ima_iint_cache *iint,
u64 *allowed_usage);
+int ima_digest_cache_register_notifier(void);
#else
static inline void
ima_digest_cache_store_allowed_usage(struct file *file,
@@ -27,4 +28,9 @@ ima_digest_cache_update_allowed_usage(struct file *file,
u64 *allowed_usage)
{ }
+static inline int ima_digest_cache_register_notifier(void)
+{
+ return 0;
+}
+
#endif /* CONFIG_SECURITY_DIGEST_CACHE */
@@ -1159,8 +1159,17 @@ static int __init init_ima(void)
return error;
error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
- if (error)
+ if (error) {
pr_warn("Couldn't register LSM notifier, error %d\n", error);
+ return error;
+ }
+
+ error = ima_digest_cache_register_notifier();
+ if (error) {
+ pr_warn("Couldn't register digest cache notifier, error %d\n",
+ error);
+ unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
+ }
if (!error)
ima_update_policy_flags();