Skip to content

Commit ce0c1c9

Browse files
committed
Merge tag 'modules-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux
Pull modules updates from Luis Chamberlain: "Christophe Leroy did most of the work on this release, first with a few cleanups on CONFIG_STRICT_KERNEL_RWX and ending with error handling for when set_memory_XX() can fail. This is part of a larger effort to clean up all these callers which can fail, modules is just part of it" * tag 'modules-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: module: Don't ignore errors from set_memory_XX() lib/test_kmod: fix kernel-doc warnings powerpc: Simplify strict_kernel_rwx_enabled() modules: Remove #ifdef CONFIG_STRICT_MODULE_RWX around rodata_enabled init: Declare rodata_enabled and mark_rodata_ro() at all time module: Change module_enable_{nx/x/ro}() to more explicit names module: Use set_memory_rox()
2 parents 70ef654 + d1909c0 commit ce0c1c9

File tree

7 files changed

+73
-56
lines changed

7 files changed

+73
-56
lines changed

arch/powerpc/include/asm/mmu.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -330,17 +330,10 @@ static __always_inline bool early_radix_enabled(void)
330330
return early_mmu_has_feature(MMU_FTR_TYPE_RADIX);
331331
}
332332

333-
#ifdef CONFIG_STRICT_KERNEL_RWX
334333
static inline bool strict_kernel_rwx_enabled(void)
335334
{
336-
return rodata_enabled;
335+
return IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled;
337336
}
338-
#else
339-
static inline bool strict_kernel_rwx_enabled(void)
340-
{
341-
return false;
342-
}
343-
#endif
344337

345338
static inline bool strict_module_rwx_enabled(void)
346339
{

include/linux/init.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,8 @@ extern initcall_entry_t __initcall_end[];
168168

169169
extern struct file_system_type rootfs_fs_type;
170170

171-
#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
172171
extern bool rodata_enabled;
173-
#endif
174-
#ifdef CONFIG_STRICT_KERNEL_RWX
175172
void mark_rodata_ro(void);
176-
#endif
177173

178174
extern void (*late_time_init)(void);
179175

init/main.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,10 +1401,9 @@ static int __init set_debug_rodata(char *str)
14011401
early_param("rodata", set_debug_rodata);
14021402
#endif
14031403

1404-
#ifdef CONFIG_STRICT_KERNEL_RWX
14051404
static void mark_readonly(void)
14061405
{
1407-
if (rodata_enabled) {
1406+
if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled) {
14081407
/*
14091408
* load_module() results in W+X mappings, which are cleaned
14101409
* up with call_rcu(). Let's make sure that queued work is
@@ -1414,20 +1413,14 @@ static void mark_readonly(void)
14141413
rcu_barrier();
14151414
mark_rodata_ro();
14161415
rodata_test();
1417-
} else
1416+
} else if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) {
14181417
pr_info("Kernel memory protection disabled.\n");
1418+
} else if (IS_ENABLED(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX)) {
1419+
pr_warn("Kernel memory protection not selected by kernel config.\n");
1420+
} else {
1421+
pr_warn("This architecture does not have kernel memory protection.\n");
1422+
}
14191423
}
1420-
#elif defined(CONFIG_ARCH_HAS_STRICT_KERNEL_RWX)
1421-
static inline void mark_readonly(void)
1422-
{
1423-
pr_warn("Kernel memory protection not selected by kernel config.\n");
1424-
}
1425-
#else
1426-
static inline void mark_readonly(void)
1427-
{
1428-
pr_warn("This architecture does not have kernel memory protection.\n");
1429-
}
1430-
#endif
14311424

14321425
void __weak free_initmem(void)
14331426
{

kernel/module/internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,9 @@ static inline struct module *mod_find(unsigned long addr, struct mod_tree_root *
322322
}
323323
#endif /* CONFIG_MODULES_TREE_LOOKUP */
324324

325-
void module_enable_ro(const struct module *mod, bool after_init);
326-
void module_enable_nx(const struct module *mod);
327-
void module_enable_x(const struct module *mod);
325+
int module_enable_rodata_ro(const struct module *mod, bool after_init);
326+
int module_enable_data_nx(const struct module *mod);
327+
int module_enable_text_rox(const struct module *mod);
328328
int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
329329
char *secstrings, struct module *mod);
330330

kernel/module/main.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,7 +2571,9 @@ static noinline int do_init_module(struct module *mod)
25712571
/* Switch to core kallsyms now init is done: kallsyms may be walking! */
25722572
rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
25732573
#endif
2574-
module_enable_ro(mod, true);
2574+
ret = module_enable_rodata_ro(mod, true);
2575+
if (ret)
2576+
goto fail_mutex_unlock;
25752577
mod_tree_remove_init(mod);
25762578
module_arch_freeing_init(mod);
25772579
for_class_mod_mem_type(type, init) {
@@ -2609,6 +2611,8 @@ static noinline int do_init_module(struct module *mod)
26092611

26102612
return 0;
26112613

2614+
fail_mutex_unlock:
2615+
mutex_unlock(&module_mutex);
26122616
fail_free_freeinit:
26132617
kfree(freeinit);
26142618
fail:
@@ -2736,9 +2740,15 @@ static int complete_formation(struct module *mod, struct load_info *info)
27362740
module_bug_finalize(info->hdr, info->sechdrs, mod);
27372741
module_cfi_finalize(info->hdr, info->sechdrs, mod);
27382742

2739-
module_enable_ro(mod, false);
2740-
module_enable_nx(mod);
2741-
module_enable_x(mod);
2743+
err = module_enable_rodata_ro(mod, false);
2744+
if (err)
2745+
goto out_strict_rwx;
2746+
err = module_enable_data_nx(mod);
2747+
if (err)
2748+
goto out_strict_rwx;
2749+
err = module_enable_text_rox(mod);
2750+
if (err)
2751+
goto out_strict_rwx;
27422752

27432753
/*
27442754
* 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)
27492759

27502760
return 0;
27512761

2762+
out_strict_rwx:
2763+
module_bug_cleanup(mod);
27522764
out:
27532765
mutex_unlock(&module_mutex);
27542766
return err;

kernel/module/strict_rwx.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@
1111
#include <linux/set_memory.h>
1212
#include "internal.h"
1313

14-
static void module_set_memory(const struct module *mod, enum mod_mem_type type,
15-
int (*set_memory)(unsigned long start, int num_pages))
14+
static int module_set_memory(const struct module *mod, enum mod_mem_type type,
15+
int (*set_memory)(unsigned long start, int num_pages))
1616
{
1717
const struct module_memory *mod_mem = &mod->mem[type];
1818

19+
if (!mod_mem->base)
20+
return 0;
21+
1922
set_vm_flush_reset_perms(mod_mem->base);
20-
set_memory((unsigned long)mod_mem->base, mod_mem->size >> PAGE_SHIFT);
23+
return set_memory((unsigned long)mod_mem->base, mod_mem->size >> PAGE_SHIFT);
2124
}
2225

2326
/*
@@ -26,37 +29,53 @@ static void module_set_memory(const struct module *mod, enum mod_mem_type type,
2629
* CONFIG_STRICT_MODULE_RWX because they are needed regardless of whether we
2730
* are strict.
2831
*/
29-
void module_enable_x(const struct module *mod)
32+
int module_enable_text_rox(const struct module *mod)
3033
{
31-
for_class_mod_mem_type(type, text)
32-
module_set_memory(mod, type, set_memory_x);
34+
for_class_mod_mem_type(type, text) {
35+
int ret;
36+
37+
if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
38+
ret = module_set_memory(mod, type, set_memory_rox);
39+
else
40+
ret = module_set_memory(mod, type, set_memory_x);
41+
if (ret)
42+
return ret;
43+
}
44+
return 0;
3345
}
3446

35-
void module_enable_ro(const struct module *mod, bool after_init)
47+
int module_enable_rodata_ro(const struct module *mod, bool after_init)
3648
{
37-
if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
38-
return;
39-
#ifdef CONFIG_STRICT_MODULE_RWX
40-
if (!rodata_enabled)
41-
return;
42-
#endif
49+
int ret;
50+
51+
if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX) || !rodata_enabled)
52+
return 0;
4353

44-
module_set_memory(mod, MOD_TEXT, set_memory_ro);
45-
module_set_memory(mod, MOD_INIT_TEXT, set_memory_ro);
46-
module_set_memory(mod, MOD_RODATA, set_memory_ro);
47-
module_set_memory(mod, MOD_INIT_RODATA, set_memory_ro);
54+
ret = module_set_memory(mod, MOD_RODATA, set_memory_ro);
55+
if (ret)
56+
return ret;
57+
ret = module_set_memory(mod, MOD_INIT_RODATA, set_memory_ro);
58+
if (ret)
59+
return ret;
4860

4961
if (after_init)
50-
module_set_memory(mod, MOD_RO_AFTER_INIT, set_memory_ro);
62+
return module_set_memory(mod, MOD_RO_AFTER_INIT, set_memory_ro);
63+
64+
return 0;
5165
}
5266

53-
void module_enable_nx(const struct module *mod)
67+
int module_enable_data_nx(const struct module *mod)
5468
{
5569
if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
56-
return;
70+
return 0;
5771

58-
for_class_mod_mem_type(type, data)
59-
module_set_memory(mod, type, set_memory_nx);
72+
for_class_mod_mem_type(type, data) {
73+
int ret = module_set_memory(mod, type, set_memory_nx);
74+
75+
if (ret)
76+
return ret;
77+
}
78+
return 0;
6079
}
6180

6281
int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,

lib/test_kmod.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ static int num_test_devs;
5858
* @need_mod_put for your tests case.
5959
*/
6060
enum kmod_test_case {
61+
/* private: */
6162
__TEST_KMOD_INVALID = 0,
63+
/* public: */
6264

6365
TEST_KMOD_DRIVER,
6466
TEST_KMOD_FS_TYPE,
6567

68+
/* private: */
6669
__TEST_KMOD_MAX,
6770
};
6871

@@ -82,6 +85,7 @@ struct kmod_test_device;
8285
* @ret_sync: return value if request_module() is used, sync request for
8386
* @TEST_KMOD_DRIVER
8487
* @fs_sync: return value of get_fs_type() for @TEST_KMOD_FS_TYPE
88+
* @task_sync: kthread's task_struct or %NULL if not running
8589
* @thread_idx: thread ID
8690
* @test_dev: test device test is being performed under
8791
* @need_mod_put: Some tests (get_fs_type() is one) requires putting the module
@@ -108,7 +112,7 @@ struct kmod_test_device_info {
108112
* @dev: pointer to misc_dev's own struct device
109113
* @config_mutex: protects configuration of test
110114
* @trigger_mutex: the test trigger can only be fired once at a time
111-
* @thread_lock: protects @done count, and the @info per each thread
115+
* @thread_mutex: protects @done count, and the @info per each thread
112116
* @done: number of threads which have completed or failed
113117
* @test_is_oom: when we run out of memory, use this to halt moving forward
114118
* @kthreads_done: completion used to signal when all work is done

0 commit comments

Comments
 (0)