@@ -34,7 +34,7 @@ Description:
[FIRMWARE_CHECK]
[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
[KEXEC_CMDLINE] [KEY_CHECK] [CRITICAL_DATA]
- [SETXATTR_CHECK]
+ [SETXATTR_CHECK] [TRUSTED_FOR_CHECK]
mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
[[^]MAY_EXEC]
fsmagic:= hex value
@@ -202,6 +202,7 @@ static inline unsigned int ima_hash_key(u8 *digest)
hook(KEY_CHECK, key) \
hook(CRITICAL_DATA, critical_data) \
hook(SETXATTR_CHECK, setxattr_check) \
+ hook(TRUSTED_FOR_CHECK, trusted_for_check) \
hook(MAX_CHECK, none)
#define __ima_hook_enumify(ENUM, str) ENUM,
@@ -26,6 +26,7 @@
#include <linux/ima.h>
#include <linux/iversion.h>
#include <linux/fs.h>
+#include <uapi/linux/trusted-for.h>
#include "ima.h"
@@ -519,6 +520,28 @@ int ima_file_check(struct file *file, int mask)
}
EXPORT_SYMBOL_GPL(ima_file_check);
+/**
+ * ima_trusted_for - based on policy, measure/appraise/audit measurement
+ * @file: pointer to the file to be measured/appraised/audit
+ * @usage: limit enumeration to TRUSTED_FOR_EXECUTION
+ *
+ * Measure/appraise/audit files being executed by an interpreter.
+ *
+ * On success return 0. On integrity appraisal error, assuming the file
+ * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
+ */
+int ima_trusted_for(struct file *file, const enum trusted_for_usage usage)
+{
+ u32 secid;
+
+ if (usage != TRUSTED_FOR_EXECUTION)
+ return 0;
+
+ security_task_getsecid_subj(current, &secid);
+ return process_measurement(file, current_cred(), secid, NULL,
+ 0, MAY_EXEC, TRUSTED_FOR_CHECK);
+}
+
static int __ima_inode_hash(struct inode *inode, char *buf, size_t buf_size)
{
struct integrity_iint_cache *iint;
@@ -1210,6 +1210,7 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
case POST_SETATTR:
case FIRMWARE_CHECK:
case POLICY_CHECK:
+ case TRUSTED_FOR_CHECK:
if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
IMA_UID | IMA_FOWNER | IMA_FSUUID |
IMA_INMASK | IMA_EUID | IMA_PCR |
@@ -1423,6 +1424,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
/* PATH_CHECK is for backwards compat */
else if (strcmp(args[0].from, "PATH_CHECK") == 0)
entry->func = FILE_CHECK;
+ else if (strcmp(args[0].from, "TRUSTED_FOR_CHECK") == 0)
+ entry->func = TRUSTED_FOR_CHECK;
else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
entry->func = MODULE_CHECK;
else if (strcmp(args[0].from, "FIRMWARE_CHECK") == 0)
A major interpreter integrity gap exists which allows files read by the interpreter to be executed without measuring the file or verifying the file's signature. The kernel has no knowledge about the file being read by the interpreter. Only the interpreter knows the context(eg. data, execute) and must be trusted to provide that information accurately. To close this integrity gap, define an ima_trusted_for hook to allow IMA to measure the file and verify the file's signature based on policy. Sample policy rules: measure func=TRUSTED_FOR_CHECK appraise func=TRUSTED_FOR_CHECK Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> --- Mickaƫl, here is the first LSM/integrity instantiation of the trusted_for hook. Documentation/ABI/testing/ima_policy | 2 +- security/integrity/ima/ima.h | 1 + security/integrity/ima/ima_main.c | 23 +++++++++++++++++++++++ security/integrity/ima/ima_policy.c | 3 +++ 4 files changed, 28 insertions(+), 1 deletion(-)