Skip to content

Commit da0acd7

Browse files
committed
Merge tag 'modules-for-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux
Pull module updates from Jessica Yu: "Summary of modules changes for the 5.3 merge window: - Code fixes and cleanups - Fix bug where set_memory_x() wasn't being called when rodata=n - Fix bug where -EEXIST was being returned for going modules - Allow arches to override module_exit_section()" * tag 'modules-for-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux: modules: fix compile error if don't have strict module rwx ARM: module: recognize unwind exit sections module: allow arch overrides for .exit section names modules: fix BUG when load module with rodata=n kernel/module: Fix mem leak in module_add_modinfo_attrs kernel: module: Use struct_size() helper kernel/module.c: Only return -EEXIST for modules that have finished loading
2 parents 818e95c + 93651f8 commit da0acd7

File tree

3 files changed

+53
-19
lines changed

3 files changed

+53
-19
lines changed

arch/arm/kernel/module.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ void *module_alloc(unsigned long size)
5555
}
5656
#endif
5757

58+
bool module_exit_section(const char *name)
59+
{
60+
return strstarts(name, ".exit") ||
61+
strstarts(name, ".ARM.extab.exit") ||
62+
strstarts(name, ".ARM.exidx.exit");
63+
}
64+
5865
int
5966
apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
6067
unsigned int relindex, struct module *module)

include/linux/moduleloader.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ void *module_alloc(unsigned long size);
2929
/* Free memory returned from module_alloc. */
3030
void module_memfree(void *module_region);
3131

32+
/* Determines if the section name is an exit section (that is only used during
33+
* module unloading)
34+
*/
35+
bool module_exit_section(const char *name);
36+
3237
/*
3338
* Apply the given relocation to the (simplified) ELF. Return -error
3439
* or 0.

kernel/module.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,8 +1492,7 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
14921492
for (i = 0; i < info->hdr->e_shnum; i++)
14931493
if (!sect_empty(&info->sechdrs[i]))
14941494
nloaded++;
1495-
size[0] = ALIGN(sizeof(*sect_attrs)
1496-
+ nloaded * sizeof(sect_attrs->attrs[0]),
1495+
size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
14971496
sizeof(sect_attrs->grp.attrs[0]));
14981497
size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
14991498
sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
@@ -1697,6 +1696,8 @@ static int add_usage_links(struct module *mod)
16971696
return ret;
16981697
}
16991698

1699+
static void module_remove_modinfo_attrs(struct module *mod, int end);
1700+
17001701
static int module_add_modinfo_attrs(struct module *mod)
17011702
{
17021703
struct module_attribute *attr;
@@ -1711,24 +1712,34 @@ static int module_add_modinfo_attrs(struct module *mod)
17111712
return -ENOMEM;
17121713

17131714
temp_attr = mod->modinfo_attrs;
1714-
for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
1715+
for (i = 0; (attr = modinfo_attrs[i]); i++) {
17151716
if (!attr->test || attr->test(mod)) {
17161717
memcpy(temp_attr, attr, sizeof(*temp_attr));
17171718
sysfs_attr_init(&temp_attr->attr);
17181719
error = sysfs_create_file(&mod->mkobj.kobj,
17191720
&temp_attr->attr);
1721+
if (error)
1722+
goto error_out;
17201723
++temp_attr;
17211724
}
17221725
}
1726+
1727+
return 0;
1728+
1729+
error_out:
1730+
if (i > 0)
1731+
module_remove_modinfo_attrs(mod, --i);
17231732
return error;
17241733
}
17251734

1726-
static void module_remove_modinfo_attrs(struct module *mod)
1735+
static void module_remove_modinfo_attrs(struct module *mod, int end)
17271736
{
17281737
struct module_attribute *attr;
17291738
int i;
17301739

17311740
for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
1741+
if (end >= 0 && i > end)
1742+
break;
17321743
/* pick a field to test for end of list */
17331744
if (!attr->attr.name)
17341745
break;
@@ -1816,7 +1827,7 @@ static int mod_sysfs_setup(struct module *mod,
18161827
return 0;
18171828

18181829
out_unreg_modinfo_attrs:
1819-
module_remove_modinfo_attrs(mod);
1830+
module_remove_modinfo_attrs(mod, -1);
18201831
out_unreg_param:
18211832
module_param_sysfs_remove(mod);
18221833
out_unreg_holders:
@@ -1852,7 +1863,7 @@ static void mod_sysfs_fini(struct module *mod)
18521863
{
18531864
}
18541865

1855-
static void module_remove_modinfo_attrs(struct module *mod)
1866+
static void module_remove_modinfo_attrs(struct module *mod, int end)
18561867
{
18571868
}
18581869

@@ -1868,14 +1879,14 @@ static void init_param_lock(struct module *mod)
18681879
static void mod_sysfs_teardown(struct module *mod)
18691880
{
18701881
del_usage_links(mod);
1871-
module_remove_modinfo_attrs(mod);
1882+
module_remove_modinfo_attrs(mod, -1);
18721883
module_param_sysfs_remove(mod);
18731884
kobject_put(mod->mkobj.drivers_dir);
18741885
kobject_put(mod->holders_dir);
18751886
mod_sysfs_fini(mod);
18761887
}
18771888

1878-
#ifdef CONFIG_STRICT_MODULE_RWX
1889+
#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX
18791890
/*
18801891
* LKM RO/NX protection: protect module's text/ro-data
18811892
* from modification and any data from execution.
@@ -1898,6 +1909,7 @@ static void frob_text(const struct module_layout *layout,
18981909
layout->text_size >> PAGE_SHIFT);
18991910
}
19001911

1912+
#ifdef CONFIG_STRICT_MODULE_RWX
19011913
static void frob_rodata(const struct module_layout *layout,
19021914
int (*set_memory)(unsigned long start, int num_pages))
19031915
{
@@ -1949,13 +1961,9 @@ void module_enable_ro(const struct module *mod, bool after_init)
19491961
set_vm_flush_reset_perms(mod->core_layout.base);
19501962
set_vm_flush_reset_perms(mod->init_layout.base);
19511963
frob_text(&mod->core_layout, set_memory_ro);
1952-
frob_text(&mod->core_layout, set_memory_x);
19531964

19541965
frob_rodata(&mod->core_layout, set_memory_ro);
1955-
19561966
frob_text(&mod->init_layout, set_memory_ro);
1957-
frob_text(&mod->init_layout, set_memory_x);
1958-
19591967
frob_rodata(&mod->init_layout, set_memory_ro);
19601968

19611969
if (after_init)
@@ -2014,9 +2022,19 @@ void set_all_modules_text_ro(void)
20142022
}
20152023
mutex_unlock(&module_mutex);
20162024
}
2017-
#else
2025+
#else /* !CONFIG_STRICT_MODULE_RWX */
20182026
static void module_enable_nx(const struct module *mod) { }
2019-
#endif
2027+
#endif /* CONFIG_STRICT_MODULE_RWX */
2028+
static void module_enable_x(const struct module *mod)
2029+
{
2030+
frob_text(&mod->core_layout, set_memory_x);
2031+
frob_text(&mod->init_layout, set_memory_x);
2032+
}
2033+
#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
2034+
static void module_enable_nx(const struct module *mod) { }
2035+
static void module_enable_x(const struct module *mod) { }
2036+
#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */
2037+
20202038

20212039
#ifdef CONFIG_LIVEPATCH
20222040
/*
@@ -2723,6 +2741,11 @@ void * __weak module_alloc(unsigned long size)
27232741
return vmalloc_exec(size);
27242742
}
27252743

2744+
bool __weak module_exit_section(const char *name)
2745+
{
2746+
return strstarts(name, ".exit");
2747+
}
2748+
27262749
#ifdef CONFIG_DEBUG_KMEMLEAK
27272750
static void kmemleak_load_module(const struct module *mod,
27282751
const struct load_info *info)
@@ -2912,7 +2935,7 @@ static int rewrite_section_headers(struct load_info *info, int flags)
29122935

29132936
#ifndef CONFIG_MODULE_UNLOAD
29142937
/* Don't load .exit sections */
2915-
if (strstarts(info->secstrings+shdr->sh_name, ".exit"))
2938+
if (module_exit_section(info->secstrings+shdr->sh_name))
29162939
shdr->sh_flags &= ~(unsigned long)SHF_ALLOC;
29172940
#endif
29182941
}
@@ -3390,8 +3413,7 @@ static bool finished_loading(const char *name)
33903413
sched_annotate_sleep();
33913414
mutex_lock(&module_mutex);
33923415
mod = find_module_all(name, strlen(name), true);
3393-
ret = !mod || mod->state == MODULE_STATE_LIVE
3394-
|| mod->state == MODULE_STATE_GOING;
3416+
ret = !mod || mod->state == MODULE_STATE_LIVE;
33953417
mutex_unlock(&module_mutex);
33963418

33973419
return ret;
@@ -3581,8 +3603,7 @@ static int add_unformed_module(struct module *mod)
35813603
mutex_lock(&module_mutex);
35823604
old = find_module_all(mod->name, strlen(mod->name), true);
35833605
if (old != NULL) {
3584-
if (old->state == MODULE_STATE_COMING
3585-
|| old->state == MODULE_STATE_UNFORMED) {
3606+
if (old->state != MODULE_STATE_LIVE) {
35863607
/* Wait in case it fails to load. */
35873608
mutex_unlock(&module_mutex);
35883609
err = wait_event_interruptible(module_wq,
@@ -3621,6 +3642,7 @@ static int complete_formation(struct module *mod, struct load_info *info)
36213642

36223643
module_enable_ro(mod, false);
36233644
module_enable_nx(mod);
3645+
module_enable_x(mod);
36243646

36253647
/* Mark state as coming so strong_try_module_get() ignores us,
36263648
* but kallsyms etc. can see us. */

0 commit comments

Comments
 (0)