Commit e20a9b92 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull integrity subsystem updates from Mimi Zohar:
 "Just three patches here. Other integrity changes are being upstreamed
  via EFI (defines a common EFI secure and trusted boot IMA policy) and
  BPF LSM (exporting the IMA file cache hash info based on inode).

  The three patches included here:

   - bug fix: fail calculating the file hash, when a file not opened for
     read and the attempt to re-open it for read fails.

   - defer processing the "ima_appraise" boot command line option to
     avoid enabling different modes (e.g. fix, log) to when the secure
     boot flag is available on arm.

   - defines "ima-buf" as the default IMA buffer measurement template in
     preparation for the builtin integrity "critical data" policy"

* tag 'integrity-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: Don't modify file descriptor mode on the fly
  ima: select ima-buf template for buffer measurement
  ima: defer arch_ima_get_secureboot() call to IMA init time
parents ca5b877b 207cdd56
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -32,6 +32,12 @@ extern int ima_file_hash(struct file *file, char *buf, size_t buf_size);
extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size);
extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size);

#ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
extern void ima_appraise_parse_cmdline(void);
#else
static inline void ima_appraise_parse_cmdline(void) {}
#endif

#ifdef CONFIG_IMA_KEXEC
extern void ima_add_kexec_buffer(struct kimage *image);
#endif
+1 −0
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ int template_desc_init_fields(const char *template_fmt,
			      const struct ima_template_field ***fields,
			      int *num_fields);
struct ima_template_desc *ima_template_desc_current(void);
struct ima_template_desc *ima_template_desc_buf(void);
struct ima_template_desc *lookup_template_desc(const char *name);
bool ima_template_has_modsig(const struct ima_template_desc *ima_template);
int ima_restore_measurement_entry(struct ima_template_entry *entry);
+11 −6
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * Author:
 * Mimi Zohar <zohar@us.ibm.com>
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/file.h>
#include <linux/fs.h>
@@ -16,12 +17,19 @@

#include "ima.h"

static int __init default_appraise_setup(char *str)
{
#ifdef CONFIG_IMA_APPRAISE_BOOTPARAM
static char *ima_appraise_cmdline_default __initdata;
core_param(ima_appraise, ima_appraise_cmdline_default, charp, 0);

void __init ima_appraise_parse_cmdline(void)
{
	const char *str = ima_appraise_cmdline_default;
	bool sb_state = arch_ima_get_secureboot();
	int appraisal_state = ima_appraise;

	if (!str)
		return;

	if (strncmp(str, "off", 3) == 0)
		appraisal_state = 0;
	else if (strncmp(str, "log", 3) == 0)
@@ -42,11 +50,8 @@ static int __init default_appraise_setup(char *str)
	} else {
		ima_appraise = appraisal_state;
	}
#endif
	return 1;
}

__setup("ima_appraise=", default_appraise_setup);
#endif

/*
 * is_ima_appraise_enabled - return appraise status
+5 −15
Original line number Diff line number Diff line
@@ -537,7 +537,7 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
	loff_t i_size;
	int rc;
	struct file *f = file;
	bool new_file_instance = false, modified_mode = false;
	bool new_file_instance = false;

	/*
	 * For consistency, fail file's opened with the O_DIRECT flag on
@@ -555,19 +555,11 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
				O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
		flags |= O_RDONLY;
		f = dentry_open(&file->f_path, flags, file->f_cred);
		if (IS_ERR(f)) {
			/*
			 * Cannot open the file again, lets modify f_mode
			 * of original and continue
			 */
			pr_info_ratelimited("Unable to reopen file for reading.\n");
			f = file;
			f->f_mode |= FMODE_READ;
			modified_mode = true;
		} else {
		if (IS_ERR(f))
			return PTR_ERR(f);

		new_file_instance = true;
	}
	}

	i_size = i_size_read(file_inode(f));

@@ -581,8 +573,6 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
out:
	if (new_file_instance)
		fput(f);
	else if (modified_mode)
		f->f_mode &= ~FMODE_READ;
	return rc;
}

+10 −15
Original line number Diff line number Diff line
@@ -413,7 +413,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
 */
int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot)
{
	struct ima_template_desc *template;
	struct ima_template_desc *template = NULL;
	struct file *file = vma->vm_file;
	char filename[NAME_MAX];
	char *pathbuf = NULL;
@@ -832,7 +832,7 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size,
					    .filename = eventname,
					    .buf = buf,
					    .buf_len = size};
	struct ima_template_desc *template = NULL;
	struct ima_template_desc *template;
	struct {
		struct ima_digest_data hdr;
		char digest[IMA_MAX_DIGEST_SIZE];
@@ -844,6 +844,13 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size,
	if (!ima_policy_flag)
		return;

	template = ima_template_desc_buf();
	if (!template) {
		ret = -EINVAL;
		audit_cause = "ima_template_desc_buf";
		goto out;
	}

	/*
	 * Both LSM hooks and auxilary based buffer measurements are
	 * based on policy.  To avoid code duplication, differentiate
@@ -862,19 +869,6 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size,
	if (!pcr)
		pcr = CONFIG_IMA_MEASURE_PCR_IDX;

	if (!template) {
		template = lookup_template_desc("ima-buf");
		ret = template_desc_init_fields(template->fmt,
						&(template->fields),
						&(template->num_fields));
		if (ret < 0) {
			pr_err("template %s init failed, result: %d\n",
			       (strlen(template->name) ?
				template->name : template->fmt), ret);
			return;
		}
	}

	iint.ima_hash = &hash.hdr;
	iint.ima_hash->algo = ima_hash_algo;
	iint.ima_hash->length = hash_digest_size[ima_hash_algo];
@@ -934,6 +928,7 @@ static int __init init_ima(void)
{
	int error;

	ima_appraise_parse_cmdline();
	ima_init_template_list();
	hash_setup(CONFIG_IMA_DEFAULT_HASH);
	error = ima_init();
Loading