Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a9196d7 authored by Mimi Zohar's avatar Mimi Zohar Committed by Kees Cook
Browse files

ima: add support for measuring and appraising firmware



The "security: introduce kernel_fw_from_file hook" patch defined a
new security hook to evaluate any loaded firmware that wasn't built
into the kernel.

This patch defines ima_fw_from_file(), which is called from the new
security hook, to measure and/or appraise the loaded firmware's
integrity.

Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent 6593d924
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ Description:
			option:	[[appraise_type=]] [permit_directio]

		base: 	func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
				[FIRMWARE_CHECK]
			mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
			fsmagic:= hex value
			fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
@@ -57,7 +58,8 @@ Description:
			measure func=BPRM_CHECK
			measure func=FILE_MMAP mask=MAY_EXEC
			measure func=FILE_CHECK mask=MAY_READ uid=0
			measure func=MODULE_CHECK uid=0
			measure func=MODULE_CHECK
			measure func=FIRMWARE_CHECK
			appraise fowner=0

		The default policy measures all executables in bprm_check,
+6 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ extern int ima_file_check(struct file *file, int mask);
extern void ima_file_free(struct file *file);
extern int ima_file_mmap(struct file *file, unsigned long prot);
extern int ima_module_check(struct file *file);
extern int ima_fw_from_file(struct file *file, char *buf, size_t size);

#else
static inline int ima_bprm_check(struct linux_binprm *bprm)
@@ -46,6 +47,11 @@ static inline int ima_module_check(struct file *file)
	return 0;
}

static inline int ima_fw_from_file(struct file *file, char *buf, size_t size)
{
	return 0;
}

#endif /* CONFIG_IMA */

#ifdef CONFIG_IMA_APPRAISE
+2 −1
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode);
struct integrity_iint_cache *integrity_iint_find(struct inode *inode);

/* IMA policy related functions */
enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, POST_SETATTR };
enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK, FIRMWARE_CHECK, POST_SETATTR };

int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
		     int flags);
@@ -171,6 +171,7 @@ void ima_delete_rules(void);
#define IMA_APPRAISE_ENFORCE	0x01
#define IMA_APPRAISE_FIX	0x02
#define IMA_APPRAISE_MODULES	0x04
#define IMA_APPRAISE_FIRMWARE	0x08

#ifdef CONFIG_IMA_APPRAISE
int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
+8 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint,
		return iint->ima_bprm_status;
	case MODULE_CHECK:
		return iint->ima_module_status;
	case FIRMWARE_CHECK:
		return iint->ima_firmware_status;
	case FILE_CHECK:
	default:
		return iint->ima_file_status;
@@ -94,6 +96,9 @@ static void ima_set_cache_status(struct integrity_iint_cache *iint,
	case MODULE_CHECK:
		iint->ima_module_status = status;
		break;
	case FIRMWARE_CHECK:
		iint->ima_firmware_status = status;
		break;
	case FILE_CHECK:
	default:
		iint->ima_file_status = status;
@@ -113,6 +118,9 @@ static void ima_cache_flags(struct integrity_iint_cache *iint, int func)
	case MODULE_CHECK:
		iint->flags |= (IMA_MODULE_APPRAISED | IMA_APPRAISED);
		break;
	case FIRMWARE_CHECK:
		iint->flags |= (IMA_FIRMWARE_APPRAISED | IMA_APPRAISED);
		break;
	case FILE_CHECK:
	default:
		iint->flags |= (IMA_FILE_APPRAISED | IMA_APPRAISED);
+11 −0
Original line number Diff line number Diff line
@@ -319,6 +319,17 @@ int ima_module_check(struct file *file)
	return process_measurement(file, NULL, MAY_EXEC, MODULE_CHECK);
}

int ima_fw_from_file(struct file *file, char *buf, size_t size)
{
	if (!file) {
		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
		    (ima_appraise & IMA_APPRAISE_ENFORCE))
			return -EACCES;	/* INTEGRITY_UNKNOWN */
		return 0;
	}
	return process_measurement(file, NULL, MAY_EXEC, FIRMWARE_CHECK);
}

static int __init init_ima(void)
{
	int error;
Loading