Skip to content

Commit 0fd9cc6

Browse files
committed
Merge tag 'modules-for-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux
Pull module updates from Jessica Yu: "The most important change would be Christoph Hellwig's patch implementing proprietary taint inheritance, in an effort to discourage the creation of GPL "shim" modules that interface between GPL symbols and proprietary symbols. Summary: - Have modules that use symbols from proprietary modules inherit the TAINT_PROPRIETARY_MODULE taint, in an effort to prevent GPL shim modules that are used to circumvent _GPL exports. These are modules that claim to be GPL licensed while also using symbols from proprietary modules. Such modules will be rejected while non-GPL modules will inherit the proprietary taint. - Module export space cleanup. Unexport symbols that are unused outside of module.c or otherwise used in only built-in code" * tag 'modules-for-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux: modules: inherit TAINT_PROPRIETARY_MODULE modules: return licensing information from find_symbol modules: rename the licence field in struct symsearch to license modules: unexport __module_address modules: unexport __module_text_address modules: mark each_symbol_section static modules: mark find_symbol static modules: mark ref_module static modules: linux/moduleparam.h: drop duplicated word in a comment
2 parents 32b2ee5 + 262e6ae commit 0fd9cc6

File tree

3 files changed

+47
-41
lines changed

3 files changed

+47
-41
lines changed

include/linux/module.h

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ struct module {
389389
unsigned int num_gpl_syms;
390390
const struct kernel_symbol *gpl_syms;
391391
const s32 *gpl_crcs;
392+
bool using_gplonly_symbols;
392393

393394
#ifdef CONFIG_UNUSED_SYMBOLS
394395
/* unused exported symbols. */
@@ -582,34 +583,14 @@ struct module *find_module(const char *name);
582583
struct symsearch {
583584
const struct kernel_symbol *start, *stop;
584585
const s32 *crcs;
585-
enum {
586+
enum mod_license {
586587
NOT_GPL_ONLY,
587588
GPL_ONLY,
588589
WILL_BE_GPL_ONLY,
589-
} licence;
590+
} license;
590591
bool unused;
591592
};
592593

593-
/*
594-
* Search for an exported symbol by name.
595-
*
596-
* Must be called with module_mutex held or preemption disabled.
597-
*/
598-
const struct kernel_symbol *find_symbol(const char *name,
599-
struct module **owner,
600-
const s32 **crc,
601-
bool gplok,
602-
bool warn);
603-
604-
/*
605-
* Walk the exported symbol table
606-
*
607-
* Must be called with module_mutex held or preemption disabled.
608-
*/
609-
bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
610-
struct module *owner,
611-
void *data), void *data);
612-
613594
/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
614595
symnum out of range. */
615596
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
@@ -657,7 +638,6 @@ static inline void __module_get(struct module *module)
657638
#define symbol_put_addr(p) do { } while (0)
658639

659640
#endif /* CONFIG_MODULE_UNLOAD */
660-
int ref_module(struct module *a, struct module *b);
661641

662642
/* This is a #define so the string doesn't get put in every .o file */
663643
#define module_name(mod) \

include/linux/moduleparam.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ struct kparam_array
108108
* ".") the kernel commandline parameter. Note that - is changed to _, so
109109
* the user can use "foo-bar=1" even for variable "foo_bar".
110110
*
111-
* @perm is 0 if the the variable is not to appear in sysfs, or 0444
111+
* @perm is 0 if the variable is not to appear in sysfs, or 0444
112112
* for world-readable, 0644 for root-writable, etc. Note that if it
113113
* is writable, you may need to use kernel_param_lock() around
114114
* accesses (esp. charp, which can be kfreed when it changes).

kernel/module.c

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ static bool each_symbol_in_section(const struct symsearch *arr,
422422
}
423423

424424
/* Returns true as soon as fn returns true, otherwise false. */
425-
bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
425+
static bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
426426
struct module *owner,
427427
void *data),
428428
void *data)
@@ -484,7 +484,6 @@ bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
484484
}
485485
return false;
486486
}
487-
EXPORT_SYMBOL_GPL(each_symbol_section);
488487

489488
struct find_symbol_arg {
490489
/* Input */
@@ -496,6 +495,7 @@ struct find_symbol_arg {
496495
struct module *owner;
497496
const s32 *crc;
498497
const struct kernel_symbol *sym;
498+
enum mod_license license;
499499
};
500500

501501
static bool check_exported_symbol(const struct symsearch *syms,
@@ -505,9 +505,9 @@ static bool check_exported_symbol(const struct symsearch *syms,
505505
struct find_symbol_arg *fsa = data;
506506

507507
if (!fsa->gplok) {
508-
if (syms->licence == GPL_ONLY)
508+
if (syms->license == GPL_ONLY)
509509
return false;
510-
if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) {
510+
if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) {
511511
pr_warn("Symbol %s is being used by a non-GPL module, "
512512
"which will not be allowed in the future\n",
513513
fsa->name);
@@ -529,6 +529,7 @@ static bool check_exported_symbol(const struct symsearch *syms,
529529
fsa->owner = owner;
530530
fsa->crc = symversion(syms->crcs, symnum);
531531
fsa->sym = &syms->start[symnum];
532+
fsa->license = syms->license;
532533
return true;
533534
}
534535

@@ -585,9 +586,10 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
585586

586587
/* Find an exported symbol and return it, along with, (optional) crc and
587588
* (optional) module which owns it. Needs preempt disabled or module_mutex. */
588-
const struct kernel_symbol *find_symbol(const char *name,
589+
static const struct kernel_symbol *find_symbol(const char *name,
589590
struct module **owner,
590591
const s32 **crc,
592+
enum mod_license *license,
591593
bool gplok,
592594
bool warn)
593595
{
@@ -602,13 +604,14 @@ const struct kernel_symbol *find_symbol(const char *name,
602604
*owner = fsa.owner;
603605
if (crc)
604606
*crc = fsa.crc;
607+
if (license)
608+
*license = fsa.license;
605609
return fsa.sym;
606610
}
607611

608612
pr_debug("Failed to find symbol %s\n", name);
609613
return NULL;
610614
}
611-
EXPORT_SYMBOL_GPL(find_symbol);
612615

613616
/*
614617
* Search for module by name: must hold module_mutex (or preempt disabled
@@ -869,7 +872,7 @@ static int add_module_usage(struct module *a, struct module *b)
869872
}
870873

871874
/* Module a uses b: caller needs module_mutex() */
872-
int ref_module(struct module *a, struct module *b)
875+
static int ref_module(struct module *a, struct module *b)
873876
{
874877
int err;
875878

@@ -888,7 +891,6 @@ int ref_module(struct module *a, struct module *b)
888891
}
889892
return 0;
890893
}
891-
EXPORT_SYMBOL_GPL(ref_module);
892894

893895
/* Clear the unload stuff of the module. */
894896
static void module_unload_free(struct module *mod)
@@ -1077,7 +1079,7 @@ void __symbol_put(const char *symbol)
10771079
struct module *owner;
10781080

10791081
preempt_disable();
1080-
if (!find_symbol(symbol, &owner, NULL, true, false))
1082+
if (!find_symbol(symbol, &owner, NULL, NULL, true, false))
10811083
BUG();
10821084
module_put(owner);
10831085
preempt_enable();
@@ -1169,11 +1171,10 @@ static inline void module_unload_free(struct module *mod)
11691171
{
11701172
}
11711173

1172-
int ref_module(struct module *a, struct module *b)
1174+
static int ref_module(struct module *a, struct module *b)
11731175
{
11741176
return strong_try_module_get(b);
11751177
}
1176-
EXPORT_SYMBOL_GPL(ref_module);
11771178

11781179
static inline int module_unload_init(struct module *mod)
11791180
{
@@ -1356,7 +1357,7 @@ static inline int check_modstruct_version(const struct load_info *info,
13561357
* locking is necessary -- use preempt_disable() to placate lockdep.
13571358
*/
13581359
preempt_disable();
1359-
if (!find_symbol("module_layout", NULL, &crc, true, false)) {
1360+
if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) {
13601361
preempt_enable();
13611362
BUG();
13621363
}
@@ -1430,6 +1431,24 @@ static int verify_namespace_is_imported(const struct load_info *info,
14301431
return 0;
14311432
}
14321433

1434+
static bool inherit_taint(struct module *mod, struct module *owner)
1435+
{
1436+
if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints))
1437+
return true;
1438+
1439+
if (mod->using_gplonly_symbols) {
1440+
pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n",
1441+
mod->name, owner->name);
1442+
return false;
1443+
}
1444+
1445+
if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) {
1446+
pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n",
1447+
mod->name, owner->name);
1448+
set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints);
1449+
}
1450+
return true;
1451+
}
14331452

14341453
/* Resolve a symbol for this module. I.e. if we find one, record usage. */
14351454
static const struct kernel_symbol *resolve_symbol(struct module *mod,
@@ -1440,6 +1459,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
14401459
struct module *owner;
14411460
const struct kernel_symbol *sym;
14421461
const s32 *crc;
1462+
enum mod_license license;
14431463
int err;
14441464

14451465
/*
@@ -1449,11 +1469,19 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
14491469
*/
14501470
sched_annotate_sleep();
14511471
mutex_lock(&module_mutex);
1452-
sym = find_symbol(name, &owner, &crc,
1472+
sym = find_symbol(name, &owner, &crc, &license,
14531473
!(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
14541474
if (!sym)
14551475
goto unlock;
14561476

1477+
if (license == GPL_ONLY)
1478+
mod->using_gplonly_symbols = true;
1479+
1480+
if (!inherit_taint(mod, owner)) {
1481+
sym = NULL;
1482+
goto getname;
1483+
}
1484+
14571485
if (!check_version(info, name, mod, crc)) {
14581486
sym = ERR_PTR(-EINVAL);
14591487
goto getname;
@@ -2236,7 +2264,7 @@ void *__symbol_get(const char *symbol)
22362264
const struct kernel_symbol *sym;
22372265

22382266
preempt_disable();
2239-
sym = find_symbol(symbol, &owner, NULL, true, true);
2267+
sym = find_symbol(symbol, &owner, NULL, NULL, true, true);
22402268
if (sym && strong_try_module_get(owner))
22412269
sym = NULL;
22422270
preempt_enable();
@@ -2272,7 +2300,7 @@ static int verify_exported_symbols(struct module *mod)
22722300
for (i = 0; i < ARRAY_SIZE(arr); i++) {
22732301
for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
22742302
if (find_symbol(kernel_symbol_name(s), &owner, NULL,
2275-
true, false)) {
2303+
NULL, true, false)) {
22762304
pr_err("%s: exports duplicate symbol %s"
22772305
" (owned by %s)\n",
22782306
mod->name, kernel_symbol_name(s),
@@ -4489,7 +4517,6 @@ struct module *__module_address(unsigned long addr)
44894517
}
44904518
return mod;
44914519
}
4492-
EXPORT_SYMBOL_GPL(__module_address);
44934520

44944521
/*
44954522
* is_module_text_address - is this address inside module code?
@@ -4528,7 +4555,6 @@ struct module *__module_text_address(unsigned long addr)
45284555
}
45294556
return mod;
45304557
}
4531-
EXPORT_SYMBOL_GPL(__module_text_address);
45324558

45334559
/* Don't grab lock, we're oopsing. */
45344560
void print_modules(void)

0 commit comments

Comments
 (0)