module: Don't ignore errors from set_memory_XX()

set_memory_ro(), set_memory_nx(), set_memory_x() and other helpers
can fail and return an error. In that case the memory might not be
protected as expected and the module loading has to be aborted to
avoid security issues.

Check return value of all calls to set_memory_XX() and handle
error if any.

Add a check to not call set_memory_XX() on NULL pointers as some
architectures may not like it allthough numpages is always 0 in that
case. This also avoid a useless call to set_vm_flush_reset_perms().

Link: https://github.com/KSPP/linux/issues/7
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
This commit is contained in:
Christophe Leroy
2024-02-16 09:14:27 +01:00
committed by Luis Chamberlain
parent 157285397f
commit d1909c0221
3 changed files with 56 additions and 23 deletions

View File

@@ -2571,7 +2571,9 @@ static noinline int do_init_module(struct module *mod)
/* Switch to core kallsyms now init is done: kallsyms may be walking! */
rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
#endif
module_enable_rodata_ro(mod, true);
ret = module_enable_rodata_ro(mod, true);
if (ret)
goto fail_mutex_unlock;
mod_tree_remove_init(mod);
module_arch_freeing_init(mod);
for_class_mod_mem_type(type, init) {
@@ -2609,6 +2611,8 @@ static noinline int do_init_module(struct module *mod)
return 0;
fail_mutex_unlock:
mutex_unlock(&module_mutex);
fail_free_freeinit:
kfree(freeinit);
fail:
@@ -2736,9 +2740,15 @@ static int complete_formation(struct module *mod, struct load_info *info)
module_bug_finalize(info->hdr, info->sechdrs, mod);
module_cfi_finalize(info->hdr, info->sechdrs, mod);
module_enable_rodata_ro(mod, false);
module_enable_data_nx(mod);
module_enable_text_rox(mod);
err = module_enable_rodata_ro(mod, false);
if (err)
goto out_strict_rwx;
err = module_enable_data_nx(mod);
if (err)
goto out_strict_rwx;
err = module_enable_text_rox(mod);
if (err)
goto out_strict_rwx;
/*
* Mark state as coming so strong_try_module_get() ignores us,
@@ -2749,6 +2759,8 @@ static int complete_formation(struct module *mod, struct load_info *info)
return 0;
out_strict_rwx:
module_bug_cleanup(mod);
out:
mutex_unlock(&module_mutex);
return err;