forked from mirrors/linux
		
	ima: support for kexec image and initramfs
Add IMA policy support for measuring/appraising the kexec image and
initramfs. Two new IMA policy identifiers KEXEC_KERNEL_CHECK and
KEXEC_INITRAMFS_CHECK are defined.
Example policy rules:
measure func=KEXEC_KERNEL_CHECK
appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig
measure func=KEXEC_INITRAMFS_CHECK
appraise func=KEXEC_INITRAMFS_CHECK appraise_type=imasig
Moving the enumeration to the vfs layer simplified the patches, allowing
the IMA changes, for the most part, to be separated from the other
changes.  Unfortunately, passing either a kernel_read_file_id or a
ima_hooks enumeration within IMA is messy.
Option 1: duplicate kernel_read_file enumeration in ima_hooks
enum kernel_read_file_id {
	...
        READING_KEXEC_IMAGE,
        READING_KEXEC_INITRAMFS,
        READING_MAX_ID
enum ima_hooks {
	...
	KEXEC_KERNEL_CHECK
	KEXEC_INITRAMFS_CHECK
Option 2: define ima_hooks as extension of kernel_read_file
eg: enum ima_hooks {
        FILE_CHECK = READING_MAX_ID,
        MMAP_CHECK,
In order to pass both kernel_read_file_id and ima_hooks values, we
would need to specify a struct containing a union.
struct caller_id {
        union {
                enum ima_hooks func_id;
                enum kernel_read_file_id read_id;
        };
};
Option 3: incorportate the ima_hooks enumeration into kernel_read_file_id,
perhaps changing the enumeration name.
For now, duplicate the new READING_KEXEC_IMAGE/INITRAMFS in the ima_hooks.
Changelog v4:
- replaced switch statement with a kernel_read_file_id to an ima_hooks
id mapping array - Dmitry
- renamed ima_hook tokens KEXEC_CHECK and INITRAMFS_CHECK to
KEXEC_KERNEL_CHECK and KEXEC_INITRAMFS_CHECK respectively - Dave Young
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Acked-by: Petko Manolov <petkan@mip-labs.com>
Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
Cc: Dave Young <dyoung@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									b804defe42
								
							
						
					
					
						commit
						d9ddf077bb
					
				
					 4 changed files with 28 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -27,6 +27,7 @@ Description:
 | 
			
		|||
 | 
			
		||||
		base: 	func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
 | 
			
		||||
				[FIRMWARE_CHECK]
 | 
			
		||||
				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
 | 
			
		||||
			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
 | 
			
		||||
			       [[^]MAY_EXEC]
 | 
			
		||||
			fsmagic:= hex value
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,6 +147,8 @@ enum ima_hooks {
 | 
			
		|||
	POST_SETATTR,
 | 
			
		||||
	MODULE_CHECK,
 | 
			
		||||
	FIRMWARE_CHECK,
 | 
			
		||||
	KEXEC_KERNEL_CHECK,
 | 
			
		||||
	KEXEC_INITRAMFS_CHECK,
 | 
			
		||||
	MAX_CHECK
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -339,6 +339,13 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int read_idmap[READING_MAX_ID] = {
 | 
			
		||||
	[READING_FIRMWARE] = FIRMWARE_CHECK,
 | 
			
		||||
	[READING_MODULE] = MODULE_CHECK,
 | 
			
		||||
	[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
 | 
			
		||||
	[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ima_post_read_file - in memory collect/appraise/audit measurement
 | 
			
		||||
 * @file: pointer to the file to be measured/appraised/audit
 | 
			
		||||
| 
						 | 
				
			
			@ -355,7 +362,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
 | 
			
		|||
int ima_post_read_file(struct file *file, void *buf, loff_t size,
 | 
			
		||||
		       enum kernel_read_file_id read_id)
 | 
			
		||||
{
 | 
			
		||||
	enum ima_hooks func = FILE_CHECK;
 | 
			
		||||
	enum ima_hooks func;
 | 
			
		||||
 | 
			
		||||
	if (!file && read_id == READING_FIRMWARE) {
 | 
			
		||||
		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
 | 
			
		||||
| 
						 | 
				
			
			@ -373,11 +380,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 | 
			
		|||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (read_id == READING_FIRMWARE)
 | 
			
		||||
		func = FIRMWARE_CHECK;
 | 
			
		||||
	else if (read_id == READING_MODULE)
 | 
			
		||||
		func = MODULE_CHECK;
 | 
			
		||||
 | 
			
		||||
	func = read_idmap[read_id] ?: FILE_CHECK;
 | 
			
		||||
	return process_measurement(file, buf, size, MAY_READ, func, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -612,6 +612,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
 | 
			
		|||
				entry->func = MMAP_CHECK;
 | 
			
		||||
			else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
 | 
			
		||||
				entry->func = BPRM_CHECK;
 | 
			
		||||
			else if (strcmp(args[0].from, "KEXEC_KERNEL_CHECK") ==
 | 
			
		||||
				 0)
 | 
			
		||||
				entry->func = KEXEC_KERNEL_CHECK;
 | 
			
		||||
			else if (strcmp(args[0].from, "KEXEC_INITRAMFS_CHECK")
 | 
			
		||||
				 == 0)
 | 
			
		||||
				entry->func = KEXEC_INITRAMFS_CHECK;
 | 
			
		||||
			else
 | 
			
		||||
				result = -EINVAL;
 | 
			
		||||
			if (!result)
 | 
			
		||||
| 
						 | 
				
			
			@ -855,7 +861,8 @@ static char *mask_tokens[] = {
 | 
			
		|||
 | 
			
		||||
enum {
 | 
			
		||||
	func_file = 0, func_mmap, func_bprm,
 | 
			
		||||
	func_module, func_firmware, func_post
 | 
			
		||||
	func_module, func_firmware, func_post,
 | 
			
		||||
	func_kexec_kernel, func_kexec_initramfs
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static char *func_tokens[] = {
 | 
			
		||||
| 
						 | 
				
			
			@ -864,6 +871,8 @@ static char *func_tokens[] = {
 | 
			
		|||
	"BPRM_CHECK",
 | 
			
		||||
	"MODULE_CHECK",
 | 
			
		||||
	"FIRMWARE_CHECK",
 | 
			
		||||
	"KEXEC_KERNEL_CHECK",
 | 
			
		||||
	"KEXEC_INITRAMFS_CHECK",
 | 
			
		||||
	"POST_SETATTR"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -929,6 +938,12 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
 | 
			
		|||
	case POST_SETATTR:
 | 
			
		||||
		seq_printf(m, pt(Opt_func), ft(func_post));
 | 
			
		||||
		break;
 | 
			
		||||
	case KEXEC_KERNEL_CHECK:
 | 
			
		||||
		seq_printf(m, pt(Opt_func), ft(func_kexec_kernel));
 | 
			
		||||
		break;
 | 
			
		||||
	case KEXEC_INITRAMFS_CHECK:
 | 
			
		||||
		seq_printf(m, pt(Opt_func), ft(func_kexec_initramfs));
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		snprintf(tbuf, sizeof(tbuf), "%d", func);
 | 
			
		||||
		seq_printf(m, pt(Opt_func), tbuf);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue