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

Commit b0935123 authored by Prakhar Srivastava's avatar Prakhar Srivastava Committed by Mimi Zohar
Browse files

IMA: Define a new hook to measure the kexec boot command line arguments



Currently during soft reboot(kexec_file_load) boot command line
arguments are not measured. Define hooks needed to measure kexec
command line arguments during soft reboot(kexec_file_load).

- A new ima hook ima_kexec_cmdline is defined to be called by the
kexec code.
- A new function process_buffer_measurement is defined to measure
the buffer hash into the IMA measurement list.
- A new func policy KEXEC_CMDLINE is defined to control the
 measurement.

Signed-off-by: default avatarPrakhar Srivastava <prsriva02@gmail.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 19453ce0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ Description:
		base: 	func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK]
				[FIRMWARE_CHECK]
				[KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK]
				[KEXEC_CMDLINE]
			mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND]
			       [[^]MAY_EXEC]
			fsmagic:= hex value
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
			      enum kernel_read_file_id id);
extern void ima_post_path_mknod(struct dentry *dentry);
extern void ima_kexec_cmdline(const void *buf, int size);

#ifdef CONFIG_IMA_KEXEC
extern void ima_add_kexec_buffer(struct kimage *image);
@@ -92,6 +93,7 @@ static inline void ima_post_path_mknod(struct dentry *dentry)
	return;
}

static inline void ima_kexec_cmdline(const void *buf, int size) {}
#endif /* CONFIG_IMA */

#ifndef CONFIG_IMA_KEXEC
+1 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ static inline unsigned long ima_hash_key(u8 *digest)
	hook(KEXEC_KERNEL_CHECK)	\
	hook(KEXEC_INITRAMFS_CHECK)	\
	hook(POLICY_CHECK)		\
	hook(KEXEC_CMDLINE)		\
	hook(MAX_CHECK)
#define __ima_hook_enumify(ENUM)	ENUM,

+1 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
 *		subj=, obj=, type=, func=, mask=, fsmagic=
 *	subj,obj, and type: are LSM specific.
 *	func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK
 *	| KEXEC_CMDLINE
 *	mask: contains the permission mask
 *	fsmagic: hex value
 *
+72 −0
Original line number Diff line number Diff line
@@ -609,6 +609,78 @@ int ima_load_data(enum kernel_load_data_id id)
	return 0;
}

/*
 * process_buffer_measurement - Measure the buffer to ima log.
 * @buf: pointer to the buffer that needs to be added to the log.
 * @size: size of buffer(in bytes).
 * @eventname: event name to be used for the buffer entry.
 * @cred: a pointer to a credentials structure for user validation.
 * @secid: the secid of the task to be validated.
 *
 * Based on policy, the buffer is measured into the ima log.
 */
static void process_buffer_measurement(const void *buf, int size,
				       const char *eventname,
				       const struct cred *cred, u32 secid)
{
	int ret = 0;
	struct ima_template_entry *entry = NULL;
	struct integrity_iint_cache iint = {};
	struct ima_event_data event_data = {.iint = &iint,
					    .filename = eventname};
	struct ima_template_desc *template_desc = NULL;
	struct {
		struct ima_digest_data hdr;
		char digest[IMA_MAX_DIGEST_SIZE];
	} hash = {};
	int violation = 0;
	int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
	int action = 0;

	action = ima_get_action(NULL, cred, secid, 0, KEXEC_CMDLINE, &pcr,
				&template_desc);
	if (!(action & IMA_MEASURE))
		return;

	iint.ima_hash = &hash.hdr;
	iint.ima_hash->algo = ima_hash_algo;
	iint.ima_hash->length = hash_digest_size[ima_hash_algo];

	ret = ima_calc_buffer_hash(buf, size, iint.ima_hash);
	if (ret < 0)
		goto out;

	ret = ima_alloc_init_template(&event_data, &entry, template_desc);
	if (ret < 0)
		goto out;

	ret = ima_store_template(entry, violation, NULL, buf, pcr);

	if (ret < 0)
		ima_free_template_entry(entry);

out:
	return;
}

/**
 * ima_kexec_cmdline - measure kexec cmdline boot args
 * @buf: pointer to buffer
 * @size: size of buffer
 *
 * Buffers can only be measured, not appraised.
 */
void ima_kexec_cmdline(const void *buf, int size)
{
	u32 secid;

	if (buf && size != 0) {
		security_task_getsecid(current, &secid);
		process_buffer_measurement(buf, size, "kexec-cmdline",
					   current_cred(), secid);
	}
}

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