Commit a7d3d039 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Mimi Zohar
Browse files

integrity: use kernel_read_file_from_path() to read x509 certs



The CONFIG_IMA_LOAD_X509 and CONFIG_EVM_LOAD_X509 options permit
loading x509 signed certificates onto the trusted keyrings without
verifying the x509 certificate file's signature.

This patch replaces the call to the integrity_read_file() specific
function with the common kernel_read_file_from_path() function.
To avoid verifying the file signature, this patch defines
READING_X509_CERTFICATE.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
parent f3cc6b25
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2792,6 +2792,7 @@ extern int do_pipe_flags(int *, int);
	id(KEXEC_IMAGE, kexec-image)		\
	id(KEXEC_INITRAMFS, kexec-initramfs)	\
	id(POLICY, security-policy)		\
	id(X509_CERTIFICATE, x509-certificate)	\
	id(MAX_ID, )

#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
+9 −5
Original line number Diff line number Diff line
@@ -112,21 +112,25 @@ int __init integrity_init_keyring(const unsigned int id)
int __init integrity_load_x509(const unsigned int id, const char *path)
{
	key_ref_t key;
	char *data;
	void *data;
	loff_t size;
	int rc;

	if (!keyring[id])
		return -EINVAL;

	rc = integrity_read_file(path, &data);
	if (rc < 0)
	rc = kernel_read_file_from_path(path, &data, &size, 0,
					READING_X509_CERTIFICATE);
	if (rc < 0) {
		pr_err("Unable to open file: %s (%d)", path, rc);
		return rc;
	}

	key = key_create_or_update(make_key_ref(keyring[id], 1),
				   "asymmetric",
				   NULL,
				   data,
				   rc,
				   size,
				   ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
				    KEY_USR_VIEW | KEY_USR_READ),
				   KEY_ALLOC_NOT_IN_QUOTA);
@@ -139,6 +143,6 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
			  key_ref_to_ptr(key)->description, path);
		key_ref_put(key);
	}
	kfree(data);
	vfree(data);
	return 0;
}
+0 −49
Original line number Diff line number Diff line
@@ -199,55 +199,6 @@ int integrity_kernel_read(struct file *file, loff_t offset,
	return ret;
}

/*
 * integrity_read_file - read entire file content into the buffer
 *
 * This is function opens a file, allocates the buffer of required
 * size, read entire file content to the buffer and closes the file
 *
 * It is used only by init code.
 *
 */
int __init integrity_read_file(const char *path, char **data)
{
	struct file *file;
	loff_t size;
	char *buf;
	int rc = -EINVAL;

	if (!path || !*path)
		return -EINVAL;

	file = filp_open(path, O_RDONLY, 0);
	if (IS_ERR(file)) {
		rc = PTR_ERR(file);
		pr_err("Unable to open file: %s (%d)", path, rc);
		return rc;
	}

	size = i_size_read(file_inode(file));
	if (size <= 0)
		goto out;

	buf = kmalloc(size, GFP_KERNEL);
	if (!buf) {
		rc = -ENOMEM;
		goto out;
	}

	rc = integrity_kernel_read(file, 0, buf, size);
	if (rc == size) {
		*data = buf;
	} else {
		kfree(buf);
		if (rc >= 0)
			rc = -EIO;
	}
out:
	fput(file);
	return rc;
}

/*
 * integrity_load_keys - load integrity keys hook
 *
+4 −0
Original line number Diff line number Diff line
@@ -405,6 +405,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
	if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
		return 0;

	/* permit signed certs */
	if (!file && read_id == READING_X509_CERTIFICATE)
		return 0;

	if (!file || !buf || size == 0) { /* should never happen */
		if (ima_appraise & IMA_APPRAISE_ENFORCE)
			return -EACCES;
+0 −2
Original line number Diff line number Diff line
@@ -120,8 +120,6 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
int integrity_kernel_read(struct file *file, loff_t offset,
			  void *addr, unsigned long count);

int __init integrity_read_file(const char *path, char **data);

#define INTEGRITY_KEYRING_EVM		0
#define INTEGRITY_KEYRING_IMA		1
#define INTEGRITY_KEYRING_MODULE	2