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

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
...@@ -2792,6 +2792,7 @@ extern int do_pipe_flags(int *, int); ...@@ -2792,6 +2792,7 @@ extern int do_pipe_flags(int *, int);
id(KEXEC_IMAGE, kexec-image) \ id(KEXEC_IMAGE, kexec-image) \
id(KEXEC_INITRAMFS, kexec-initramfs) \ id(KEXEC_INITRAMFS, kexec-initramfs) \
id(POLICY, security-policy) \ id(POLICY, security-policy) \
id(X509_CERTIFICATE, x509-certificate) \
id(MAX_ID, ) id(MAX_ID, )
#define __fid_enumify(ENUM, dummy) READING_ ## ENUM, #define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
......
...@@ -112,21 +112,25 @@ int __init integrity_init_keyring(const unsigned int id) ...@@ -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) int __init integrity_load_x509(const unsigned int id, const char *path)
{ {
key_ref_t key; key_ref_t key;
char *data; void *data;
loff_t size;
int rc; int rc;
if (!keyring[id]) if (!keyring[id])
return -EINVAL; return -EINVAL;
rc = integrity_read_file(path, &data); rc = kernel_read_file_from_path(path, &data, &size, 0,
if (rc < 0) READING_X509_CERTIFICATE);
if (rc < 0) {
pr_err("Unable to open file: %s (%d)", path, rc);
return rc; return rc;
}
key = key_create_or_update(make_key_ref(keyring[id], 1), key = key_create_or_update(make_key_ref(keyring[id], 1),
"asymmetric", "asymmetric",
NULL, NULL,
data, data,
rc, size,
((KEY_POS_ALL & ~KEY_POS_SETATTR) | ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ), KEY_USR_VIEW | KEY_USR_READ),
KEY_ALLOC_NOT_IN_QUOTA); KEY_ALLOC_NOT_IN_QUOTA);
...@@ -139,6 +143,6 @@ int __init integrity_load_x509(const unsigned int id, const char *path) ...@@ -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_to_ptr(key)->description, path);
key_ref_put(key); key_ref_put(key);
} }
kfree(data); vfree(data);
return 0; return 0;
} }
...@@ -199,55 +199,6 @@ int integrity_kernel_read(struct file *file, loff_t offset, ...@@ -199,55 +199,6 @@ int integrity_kernel_read(struct file *file, loff_t offset,
return ret; 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 * integrity_load_keys - load integrity keys hook
* *
......
...@@ -405,6 +405,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, ...@@ -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 */ if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
return 0; return 0;
/* permit signed certs */
if (!file && read_id == READING_X509_CERTIFICATE)
return 0;
if (!file || !buf || size == 0) { /* should never happen */ if (!file || !buf || size == 0) { /* should never happen */
if (ima_appraise & IMA_APPRAISE_ENFORCE) if (ima_appraise & IMA_APPRAISE_ENFORCE)
return -EACCES; return -EACCES;
......
...@@ -120,8 +120,6 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode); ...@@ -120,8 +120,6 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
int integrity_kernel_read(struct file *file, loff_t offset, int integrity_kernel_read(struct file *file, loff_t offset,
void *addr, unsigned long count); void *addr, unsigned long count);
int __init integrity_read_file(const char *path, char **data);
#define INTEGRITY_KEYRING_EVM 0 #define INTEGRITY_KEYRING_EVM 0
#define INTEGRITY_KEYRING_IMA 1 #define INTEGRITY_KEYRING_IMA 1
#define INTEGRITY_KEYRING_MODULE 2 #define INTEGRITY_KEYRING_MODULE 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment