mirror of
https://github.com/torvalds/linux.git
synced 2026-01-24 23:16:46 +00:00
ima: Access decompressed kernel module to verify appended signature
Currently, when in-kernel module decompression (CONFIG_MODULE_DECOMPRESS) is enabled, IMA has no way to verify the appended module signature as it can't decompress the module. Define a new kernel_read_file_id enumerate READING_MODULE_COMPRESSED so IMA can calculate the compressed kernel module data hash on READING_MODULE_COMPRESSED and defer appraising/measuring it until on READING_MODULE when the module has been decompressed. Before enabling in-kernel module decompression, a kernel module in initramfs can still be loaded with ima_policy=secure_boot. So adjust the kernel module rule in secure_boot policy to allow either an IMA signature OR an appended signature i.e. to use "appraise func=MODULE_CHECK appraise_type=imasig|modsig". Reported-by: Karel Srot <ksrot@redhat.com> Suggested-by: Mimi Zohar <zohar@linux.ibm.com> Suggested-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Coiby Xu <coxu@redhat.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
This commit is contained in:
@@ -3675,24 +3675,35 @@ static int idempotent_wait_for_completion(struct idempotent *u)
|
||||
|
||||
static int init_module_from_file(struct file *f, const char __user * uargs, int flags)
|
||||
{
|
||||
bool compressed = !!(flags & MODULE_INIT_COMPRESSED_FILE);
|
||||
struct load_info info = { };
|
||||
void *buf = NULL;
|
||||
int len;
|
||||
int err;
|
||||
|
||||
len = kernel_read_file(f, 0, &buf, INT_MAX, NULL, READING_MODULE);
|
||||
len = kernel_read_file(f, 0, &buf, INT_MAX, NULL,
|
||||
compressed ? READING_MODULE_COMPRESSED :
|
||||
READING_MODULE);
|
||||
if (len < 0) {
|
||||
mod_stat_inc(&failed_kreads);
|
||||
return len;
|
||||
}
|
||||
|
||||
if (flags & MODULE_INIT_COMPRESSED_FILE) {
|
||||
int err = module_decompress(&info, buf, len);
|
||||
if (compressed) {
|
||||
err = module_decompress(&info, buf, len);
|
||||
vfree(buf); /* compressed data is no longer needed */
|
||||
if (err) {
|
||||
mod_stat_inc(&failed_decompress);
|
||||
mod_stat_add_long(len, &invalid_decompress_bytes);
|
||||
return err;
|
||||
}
|
||||
err = security_kernel_post_read_file(f, (char *)info.hdr, info.len,
|
||||
READING_MODULE);
|
||||
if (err) {
|
||||
mod_stat_inc(&failed_kreads);
|
||||
free_copy(&info, flags);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
info.hdr = buf;
|
||||
info.len = len;
|
||||
|
||||
Reference in New Issue
Block a user