@@ -14,6 +14,7 @@ ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o
ima-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o
ima-$(CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS) += ima_asymmetric_keys.o
ima-$(CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS) += ima_queue_keys.o
+ima-$(CONFIG_SECURITY_DIGEST_CACHE) += ima_digest_cache.o
ifeq ($(CONFIG_EFI),y)
ima-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_efi.o
new file mode 100644
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ *
+ * Integrate with the digest_cache LSM.
+ */
+
+#include <linux/digest_cache.h>
+
+#include "ima_digest_cache.h"
+
+/**
+ * ima_digest_cache_store_allowed_usage - Store allowed usage in digest cache
+ * @file: Digest list file descriptor
+ * @iint: Inode integrity metadata
+ *
+ * Set digest cache allowed usage in the digest cache associated to the
+ * digest list file descriptor. Allowed usage is based on whether or not the
+ * digest list was measured/appraised.
+ */
+void ima_digest_cache_store_allowed_usage(struct file *file,
+ struct ima_iint_cache *iint)
+{
+ u64 allowed_usage = 0;
+ int rc;
+
+ if (iint->flags & IMA_MEASURED)
+ allowed_usage |= IMA_DIGEST_CACHE_MEASURE_DATA;
+ if (iint->flags & IMA_APPRAISED_SUBMASK)
+ allowed_usage |= IMA_DIGEST_CACHE_APPRAISE_DATA;
+
+ /*
+ * Set digest cache allowed usage from integrity metadata flags for
+ * later use.
+ */
+ rc = digest_cache_verif_set(file, "ima", &allowed_usage,
+ sizeof(allowed_usage));
+
+ /* Ignore if fd doesn't have digest cache set (prefetching). */
+ if (rc && rc != -ENOENT)
+ pr_debug("Cannot set verification mask for %s, ret: %d, ignoring\n",
+ file_dentry(file)->d_name.name, rc);
+}
new file mode 100644
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2024 Huawei Technologies Duesseldorf GmbH
+ *
+ * Author: Roberto Sassu <roberto.sassu@huawei.com>
+ *
+ * Header file of ima_digest_cache.c.
+ */
+
+#include "ima.h"
+
+#ifdef CONFIG_SECURITY_DIGEST_CACHE
+void ima_digest_cache_store_allowed_usage(struct file *file,
+ struct ima_iint_cache *iint);
+#else
+static inline void
+ima_digest_cache_store_allowed_usage(struct file *file,
+ struct ima_iint_cache *iint)
+{ }
+
+#endif /* CONFIG_SECURITY_DIGEST_CACHE */
@@ -28,6 +28,7 @@
#include <linux/iversion.h>
#include "ima.h"
+#include "ima_digest_cache.h"
#ifdef CONFIG_IMA_APPRAISE
int ima_appraise = IMA_APPRAISE_ENFORCE;
@@ -399,6 +400,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
if ((mask & MAY_WRITE) && test_bit(IMA_DIGSIG, &iint->atomic_flags) &&
!(iint->flags & IMA_NEW_FILE))
rc = -EACCES;
+ if (!rc && func == DIGEST_LIST_CHECK)
+ ima_digest_cache_store_allowed_usage(file, iint);
mutex_unlock(&iint->mutex);
kfree(xattr_value);
ima_free_modsig(modsig);