Commit 4834177e authored by Tyler Hicks's avatar Tyler Hicks Committed by Mimi Zohar
Browse files

ima: Support additional conditionals in the KEXEC_CMDLINE hook function



Take the properties of the kexec kernel's inode and the current task
ownership into consideration when matching a KEXEC_CMDLINE operation to
the rules in the IMA policy. This allows for some uniformity when
writing IMA policy rules for KEXEC_KERNEL_CHECK, KEXEC_INITRAMFS_CHECK,
and KEXEC_CMDLINE operations.

Prior to this patch, it was not possible to write a set of rules like
this:

 dont_measure func=KEXEC_KERNEL_CHECK obj_type=foo_t
 dont_measure func=KEXEC_INITRAMFS_CHECK obj_type=foo_t
 dont_measure func=KEXEC_CMDLINE obj_type=foo_t
 measure func=KEXEC_KERNEL_CHECK
 measure func=KEXEC_INITRAMFS_CHECK
 measure func=KEXEC_CMDLINE

The inode information associated with the kernel being loaded by a
kexec_kernel_load(2) syscall can now be included in the decision to
measure or not

Additonally, the uid, euid, and subj_* conditionals can also now be
used in KEXEC_CMDLINE rules. There was no technical reason as to why
those conditionals weren't being considered previously other than
ima_match_rules() didn't have a valid inode to use so it immediately
bailed out for KEXEC_CMDLINE operations rather than going through the
full list of conditional comparisons.

Signed-off-by: default avatarTyler Hicks <tyhicks@linux.microsoft.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: kexec@lists.infradead.org
Reviewed-by: default avatarLakshmi Ramasubramanian <nramas@linux.microsoft.com>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 592b24cb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ 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 int ima_file_hash(struct file *file, char *buf, size_t buf_size);
extern void ima_kexec_cmdline(const void *buf, int size);
extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);

#ifdef CONFIG_IMA_KEXEC
extern void ima_add_kexec_buffer(struct kimage *image);
@@ -103,7 +103,7 @@ static inline int ima_file_hash(struct file *file, char *buf, size_t buf_size)
	return -EOPNOTSUPP;
}

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

#ifndef CONFIG_IMA_KEXEC
+1 −1
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
			goto out;
		}

		ima_kexec_cmdline(image->cmdline_buf,
		ima_kexec_cmdline(kernel_fd, image->cmdline_buf,
				  image->cmdline_buf_len - 1);
	}

+1 −1
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file,
			   struct evm_ima_xattr_data *xattr_value,
			   int xattr_len, const struct modsig *modsig, int pcr,
			   struct ima_template_desc *template_desc);
void process_buffer_measurement(const void *buf, int size,
void process_buffer_measurement(struct inode *inode, const void *buf, int size,
				const char *eventname, enum ima_hooks func,
				int pcr, const char *keyring);
void ima_audit_measurement(struct integrity_iint_cache *iint,
+1 −1
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ err_out:

/**
 * ima_get_action - appraise & measure decision based on policy.
 * @inode: pointer to inode to measure
 * @inode: pointer to the inode associated with the object being validated
 * @cred: pointer to credentials structure to validate
 * @secid: secid of the task being validated
 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC,
+1 −1
Original line number Diff line number Diff line
@@ -328,7 +328,7 @@ int ima_check_blacklist(struct integrity_iint_cache *iint,

		rc = is_binary_blacklisted(digest, digestsize);
		if ((rc == -EPERM) && (iint->flags & IMA_MEASURE))
			process_buffer_measurement(digest, digestsize,
			process_buffer_measurement(NULL, digest, digestsize,
						   "blacklisted-hash", NONE,
						   pcr, NULL);
	}
Loading