@@ -47,3 +47,38 @@ bool ima_digest_cache_get_check(struct dentry *dentry,
digest_cache_put(digest_cache);
return false;
}
+
+/**
+ * ima_digest_cache_store_verified_usage - Store verified usage in digest cache
+ * @file: Digest list file descriptor
+ * @iint: Inode integrity metadata
+ *
+ * Set digest cache verified usage in the digest cache associated to the
+ * digest list file descriptor. Verified usage is based on whether or not the
+ * digest list was measured/appraised, and is ANDed with the policy usage to
+ * make the final decision on whether a digest cache can be used for a specific
+ * IMA action.
+ */
+void ima_digest_cache_store_verified_usage(struct file *file,
+ struct ima_iint_cache *iint)
+{
+ u64 verified_usage = 0;
+ int rc;
+
+ if (iint->flags & IMA_MEASURED)
+ verified_usage |= IMA_DIGEST_CACHE_MEASURE_DATA;
+ if (iint->flags & IMA_APPRAISED_SUBMASK)
+ verified_usage |= IMA_DIGEST_CACHE_APPRAISE_DATA;
+
+ /*
+ * Set digest cache verified usage from integrity metadata flags for
+ * later use.
+ */
+ rc = digest_cache_verif_set(file, "ima", &verified_usage,
+ sizeof(verified_usage));
+
+ /* Ignore if fd doesn't have digest cache set (prefetching). */
+ if (rc && rc != -ENOENT)
+ pr_debug("Cannot set verified usage for %s, ret: %d, ignoring\n",
+ file_dentry(file)->d_name.name, rc);
+}
@@ -12,6 +12,8 @@
#ifdef CONFIG_INTEGRITY_DIGEST_CACHE
bool ima_digest_cache_get_check(struct dentry *dentry,
struct ima_iint_cache *iint);
+void ima_digest_cache_store_verified_usage(struct file *file,
+ struct ima_iint_cache *iint);
#else
static inline bool ima_digest_cache_get_check(struct dentry *dentry,
struct ima_iint_cache *iint)
@@ -19,4 +21,9 @@ static inline bool ima_digest_cache_get_check(struct dentry *dentry,
return false;
}
+static inline void
+ima_digest_cache_store_verified_usage(struct file *file,
+ struct ima_iint_cache *iint)
+{ }
+
#endif /* CONFIG_INTEGRITY_DIGEST_CACHE */
@@ -29,6 +29,7 @@
#include <linux/evm.h>
#include "ima.h"
+#include "ima_digest_cache.h"
#ifdef CONFIG_IMA_APPRAISE
int ima_appraise = IMA_APPRAISE_ENFORCE;
@@ -420,6 +421,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_verified_usage(file, iint);
mutex_unlock(&iint->mutex);
kfree(xattr_value);
ima_free_modsig(modsig);