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: Christoph Hellwig <hch@lst.de> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
This commit is contained in:
committed by
Mimi Zohar
parent
f3cc6b25dc
commit
a7d3d0392a
@@ -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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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);
|
|||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user