Skip to content

Commit 3a75ad1

Browse files
committed
Merge tag 'modules-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux
Pull modules updates from Jessica Yu: "Summary of modules changes for the 4.13 merge window: - Minor code cleanups - Avoid accessing mod struct prior to checking module struct version, from Kees - Fix racy atomic inc/dec logic of kmod_concurrent_max in kmod, from Luis" * tag 'modules-for-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux: module: make the modinfo name const kmod: reduce atomic operations on kmod_concurrent and simplify module: use list_for_each_entry_rcu() on find_module_all() kernel/module.c: suppress warning about unused nowarn variable module: Add module name to modinfo module: Pass struct load_info into symbol checks
2 parents 235b84f + 96b5b19 commit 3a75ad1

File tree

3 files changed

+73
-53
lines changed

3 files changed

+73
-53
lines changed

kernel/kmod.c

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@
4545

4646
#include <trace/events/module.h>
4747

48-
extern int max_threads;
49-
5048
#define CAP_BSET (void *)1
5149
#define CAP_PI (void *)2
5250

@@ -56,6 +54,20 @@ static DEFINE_SPINLOCK(umh_sysctl_lock);
5654
static DECLARE_RWSEM(umhelper_sem);
5755

5856
#ifdef CONFIG_MODULES
57+
/*
58+
* Assuming:
59+
*
60+
* threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,
61+
* (u64) THREAD_SIZE * 8UL);
62+
*
63+
* If you need less than 50 threads would mean we're dealing with systems
64+
* smaller than 3200 pages. This assuems you are capable of having ~13M memory,
65+
* and this would only be an be an upper limit, after which the OOM killer
66+
* would take effect. Systems like these are very unlikely if modules are
67+
* enabled.
68+
*/
69+
#define MAX_KMOD_CONCURRENT 50
70+
static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT);
5971

6072
/*
6173
modprobe_path is set via /proc/sys.
@@ -127,10 +139,7 @@ int __request_module(bool wait, const char *fmt, ...)
127139
{
128140
va_list args;
129141
char module_name[MODULE_NAME_LEN];
130-
unsigned int max_modprobes;
131142
int ret;
132-
static atomic_t kmod_concurrent = ATOMIC_INIT(0);
133-
#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
134143
static int kmod_loop_msg;
135144

136145
/*
@@ -154,40 +163,27 @@ int __request_module(bool wait, const char *fmt, ...)
154163
if (ret)
155164
return ret;
156165

157-
/* If modprobe needs a service that is in a module, we get a recursive
158-
* loop. Limit the number of running kmod threads to max_threads/2 or
159-
* MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
160-
* would be to run the parents of this process, counting how many times
161-
* kmod was invoked. That would mean accessing the internals of the
162-
* process tables to get the command line, proc_pid_cmdline is static
163-
* and it is not worth changing the proc code just to handle this case.
164-
* KAO.
165-
*
166-
* "trace the ppid" is simple, but will fail if someone's
167-
* parent exits. I think this is as good as it gets. --RR
168-
*/
169-
max_modprobes = min(max_threads/2, MAX_KMOD_CONCURRENT);
170-
atomic_inc(&kmod_concurrent);
171-
if (atomic_read(&kmod_concurrent) > max_modprobes) {
166+
if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) {
172167
/* We may be blaming an innocent here, but unlikely */
173168
if (kmod_loop_msg < 5) {
174169
printk(KERN_ERR
175170
"request_module: runaway loop modprobe %s\n",
176171
module_name);
177172
kmod_loop_msg++;
178173
}
179-
atomic_dec(&kmod_concurrent);
180174
return -ENOMEM;
181175
}
182176

183177
trace_module_request(module_name, wait, _RET_IP_);
184178

185179
ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
186180

187-
atomic_dec(&kmod_concurrent);
181+
atomic_inc(&kmod_concurrent_max);
182+
188183
return ret;
189184
}
190185
EXPORT_SYMBOL(__request_module);
186+
191187
#endif /* CONFIG_MODULES */
192188

193189
static void call_usermodehelper_freeinfo(struct subprocess_info *info)

kernel/module.c

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ int unregister_module_notifier(struct notifier_block *nb)
300300
EXPORT_SYMBOL(unregister_module_notifier);
301301

302302
struct load_info {
303+
const char *name;
303304
Elf_Ehdr *hdr;
304305
unsigned long len;
305306
Elf_Shdr *sechdrs;
@@ -600,7 +601,7 @@ static struct module *find_module_all(const char *name, size_t len,
600601

601602
module_assert_mutex_or_preempt();
602603

603-
list_for_each_entry(mod, &modules, list) {
604+
list_for_each_entry_rcu(mod, &modules, list) {
604605
if (!even_unformed && mod->state == MODULE_STATE_UNFORMED)
605606
continue;
606607
if (strlen(mod->name) == len && !memcmp(mod->name, name, len))
@@ -1273,12 +1274,13 @@ static u32 resolve_rel_crc(const s32 *crc)
12731274
return *(u32 *)((void *)crc + *crc);
12741275
}
12751276

1276-
static int check_version(Elf_Shdr *sechdrs,
1277-
unsigned int versindex,
1277+
static int check_version(const struct load_info *info,
12781278
const char *symname,
12791279
struct module *mod,
12801280
const s32 *crc)
12811281
{
1282+
Elf_Shdr *sechdrs = info->sechdrs;
1283+
unsigned int versindex = info->index.vers;
12821284
unsigned int i, num_versions;
12831285
struct modversion_info *versions;
12841286

@@ -1312,17 +1314,16 @@ static int check_version(Elf_Shdr *sechdrs,
13121314
}
13131315

13141316
/* Broken toolchain. Warn once, then let it go.. */
1315-
pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
1317+
pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
13161318
return 1;
13171319

13181320
bad_version:
13191321
pr_warn("%s: disagrees about version of symbol %s\n",
1320-
mod->name, symname);
1322+
info->name, symname);
13211323
return 0;
13221324
}
13231325

1324-
static inline int check_modstruct_version(Elf_Shdr *sechdrs,
1325-
unsigned int versindex,
1326+
static inline int check_modstruct_version(const struct load_info *info,
13261327
struct module *mod)
13271328
{
13281329
const s32 *crc;
@@ -1338,8 +1339,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
13381339
BUG();
13391340
}
13401341
preempt_enable();
1341-
return check_version(sechdrs, versindex,
1342-
VMLINUX_SYMBOL_STR(module_layout), mod, crc);
1342+
return check_version(info, VMLINUX_SYMBOL_STR(module_layout),
1343+
mod, crc);
13431344
}
13441345

13451346
/* First part is kernel version, which we ignore if module has crcs. */
@@ -1353,17 +1354,15 @@ static inline int same_magic(const char *amagic, const char *bmagic,
13531354
return strcmp(amagic, bmagic) == 0;
13541355
}
13551356
#else
1356-
static inline int check_version(Elf_Shdr *sechdrs,
1357-
unsigned int versindex,
1357+
static inline int check_version(const struct load_info *info,
13581358
const char *symname,
13591359
struct module *mod,
13601360
const s32 *crc)
13611361
{
13621362
return 1;
13631363
}
13641364

1365-
static inline int check_modstruct_version(Elf_Shdr *sechdrs,
1366-
unsigned int versindex,
1365+
static inline int check_modstruct_version(const struct load_info *info,
13671366
struct module *mod)
13681367
{
13691368
return 1;
@@ -1399,7 +1398,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
13991398
if (!sym)
14001399
goto unlock;
14011400

1402-
if (!check_version(info->sechdrs, info->index.vers, name, mod, crc)) {
1401+
if (!check_version(info, name, mod, crc)) {
14031402
sym = ERR_PTR(-EINVAL);
14041403
goto getname;
14051404
}
@@ -1662,31 +1661,36 @@ static inline void remove_notes_attrs(struct module *mod)
16621661
}
16631662
#endif /* CONFIG_KALLSYMS */
16641663

1665-
static void add_usage_links(struct module *mod)
1664+
static void del_usage_links(struct module *mod)
16661665
{
16671666
#ifdef CONFIG_MODULE_UNLOAD
16681667
struct module_use *use;
1669-
int nowarn;
16701668

16711669
mutex_lock(&module_mutex);
1672-
list_for_each_entry(use, &mod->target_list, target_list) {
1673-
nowarn = sysfs_create_link(use->target->holders_dir,
1674-
&mod->mkobj.kobj, mod->name);
1675-
}
1670+
list_for_each_entry(use, &mod->target_list, target_list)
1671+
sysfs_remove_link(use->target->holders_dir, mod->name);
16761672
mutex_unlock(&module_mutex);
16771673
#endif
16781674
}
16791675

1680-
static void del_usage_links(struct module *mod)
1676+
static int add_usage_links(struct module *mod)
16811677
{
1678+
int ret = 0;
16821679
#ifdef CONFIG_MODULE_UNLOAD
16831680
struct module_use *use;
16841681

16851682
mutex_lock(&module_mutex);
1686-
list_for_each_entry(use, &mod->target_list, target_list)
1687-
sysfs_remove_link(use->target->holders_dir, mod->name);
1683+
list_for_each_entry(use, &mod->target_list, target_list) {
1684+
ret = sysfs_create_link(use->target->holders_dir,
1685+
&mod->mkobj.kobj, mod->name);
1686+
if (ret)
1687+
break;
1688+
}
16881689
mutex_unlock(&module_mutex);
1690+
if (ret)
1691+
del_usage_links(mod);
16891692
#endif
1693+
return ret;
16901694
}
16911695

16921696
static int module_add_modinfo_attrs(struct module *mod)
@@ -1797,13 +1801,18 @@ static int mod_sysfs_setup(struct module *mod,
17971801
if (err)
17981802
goto out_unreg_param;
17991803

1800-
add_usage_links(mod);
1804+
err = add_usage_links(mod);
1805+
if (err)
1806+
goto out_unreg_modinfo_attrs;
1807+
18011808
add_sect_attrs(mod, info);
18021809
add_notes_attrs(mod, info);
18031810

18041811
kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
18051812
return 0;
18061813

1814+
out_unreg_modinfo_attrs:
1815+
module_remove_modinfo_attrs(mod);
18071816
out_unreg_param:
18081817
module_param_sysfs_remove(mod);
18091818
out_unreg_holders:
@@ -2910,9 +2919,15 @@ static int rewrite_section_headers(struct load_info *info, int flags)
29102919
info->index.vers = 0; /* Pretend no __versions section! */
29112920
else
29122921
info->index.vers = find_sec(info, "__versions");
2922+
info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
2923+
29132924
info->index.info = find_sec(info, ".modinfo");
2925+
if (!info->index.info)
2926+
info->name = "(missing .modinfo section)";
2927+
else
2928+
info->name = get_modinfo(info, "name");
29142929
info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC;
2915-
info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC;
2930+
29162931
return 0;
29172932
}
29182933

@@ -2952,21 +2967,29 @@ static struct module *setup_load_info(struct load_info *info, int flags)
29522967

29532968
info->index.mod = find_sec(info, ".gnu.linkonce.this_module");
29542969
if (!info->index.mod) {
2955-
pr_warn("No module found in object\n");
2970+
pr_warn("%s: No module found in object\n",
2971+
info->name ?: "(missing .modinfo name field)");
29562972
return ERR_PTR(-ENOEXEC);
29572973
}
29582974
/* This is temporary: point mod into copy of data. */
29592975
mod = (void *)info->sechdrs[info->index.mod].sh_addr;
29602976

2977+
/*
2978+
* If we didn't load the .modinfo 'name' field, fall back to
2979+
* on-disk struct mod 'name' field.
2980+
*/
2981+
if (!info->name)
2982+
info->name = mod->name;
2983+
29612984
if (info->index.sym == 0) {
2962-
pr_warn("%s: module has no symbols (stripped?)\n", mod->name);
2985+
pr_warn("%s: module has no symbols (stripped?)\n", info->name);
29632986
return ERR_PTR(-ENOEXEC);
29642987
}
29652988

29662989
info->index.pcpu = find_pcpusec(info);
29672990

29682991
/* Check module struct version now, before we try to use module. */
2969-
if (!check_modstruct_version(info->sechdrs, info->index.vers, mod))
2992+
if (!check_modstruct_version(info, mod))
29702993
return ERR_PTR(-ENOEXEC);
29712994

29722995
return mod;
@@ -2987,7 +3010,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
29873010
return err;
29883011
} else if (!same_magic(modmagic, vermagic, info->index.vers)) {
29893012
pr_err("%s: version magic '%s' should be '%s'\n",
2990-
mod->name, modmagic, vermagic);
3013+
info->name, modmagic, vermagic);
29913014
return -ENOEXEC;
29923015
}
29933016

@@ -3237,7 +3260,7 @@ int __weak module_frob_arch_sections(Elf_Ehdr *hdr,
32373260

32383261
/* module_blacklist is a comma-separated list of module names */
32393262
static char *module_blacklist;
3240-
static bool blacklisted(char *module_name)
3263+
static bool blacklisted(const char *module_name)
32413264
{
32423265
const char *p;
32433266
size_t len;
@@ -3267,7 +3290,7 @@ static struct module *layout_and_allocate(struct load_info *info, int flags)
32673290
if (IS_ERR(mod))
32683291
return mod;
32693292

3270-
if (blacklisted(mod->name))
3293+
if (blacklisted(info->name))
32713294
return ERR_PTR(-EPERM);
32723295

32733296
err = check_modinfo(mod, info, flags);

scripts/mod/modpost.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,7 @@ static void add_header(struct buffer *b, struct module *mod)
21262126
buf_printf(b, "#include <linux/compiler.h>\n");
21272127
buf_printf(b, "\n");
21282128
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
2129+
buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
21292130
buf_printf(b, "\n");
21302131
buf_printf(b, "__visible struct module __this_module\n");
21312132
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");

0 commit comments

Comments
 (0)