Skip to content

Commit 55fcb92

Browse files
Siddharth Nayyarsamitolvanen
authored andcommitted
module: use kflagstab instead of *_gpl sections
Read kflagstab section for vmlinux and modules to determine whether kernel symbols are GPL only. This patch eliminates the need for fragmenting the ksymtab for infering the value of GPL-only symbol flag, henceforth stop populating *_gpl versions of the ksymtab and kcrctab in modpost. Signed-off-by: Siddharth Nayyar <sidnayyar@google.com> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
1 parent 16d0e04 commit 55fcb92

5 files changed

Lines changed: 46 additions & 40 deletions

File tree

include/linux/export-internal.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
* section flag requires it. Use '%progbits' instead of '@progbits' since the
3838
* former apparently works on all arches according to the binutils source.
3939
*/
40-
#define __KSYMTAB(name, sym, sec, ns) \
40+
#define __KSYMTAB(name, sym, ns) \
4141
asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1" "\n" \
4242
"__kstrtab_" #name ":" "\n" \
4343
" .asciz \"" #name "\"" "\n" \
4444
"__kstrtabns_" #name ":" "\n" \
4545
" .asciz \"" ns "\"" "\n" \
4646
" .previous" "\n" \
47-
" .section \"___ksymtab" sec "+" #name "\", \"a\"" "\n" \
47+
" .section \"___ksymtab+" #name "\", \"a\"" "\n" \
4848
__KSYM_ALIGN "\n" \
4949
"__ksymtab_" #name ":" "\n" \
5050
__KSYM_REF(sym) "\n" \
@@ -59,15 +59,16 @@
5959
#define KSYM_FUNC(name) name
6060
#endif
6161

62-
#define KSYMTAB_FUNC(name, sec, ns) __KSYMTAB(name, KSYM_FUNC(name), sec, ns)
63-
#define KSYMTAB_DATA(name, sec, ns) __KSYMTAB(name, name, sec, ns)
62+
#define KSYMTAB_FUNC(name, ns) __KSYMTAB(name, KSYM_FUNC(name), ns)
63+
#define KSYMTAB_DATA(name, ns) __KSYMTAB(name, name, ns)
6464

65-
#define SYMBOL_CRC(sym, crc, sec) \
66-
asm(".section \"___kcrctab" sec "+" #sym "\",\"a\"" "\n" \
67-
".balign 4" "\n" \
68-
"__crc_" #sym ":" "\n" \
69-
".long " #crc "\n" \
70-
".previous" "\n")
65+
#define SYMBOL_CRC(sym, crc) \
66+
asm(" .section \"___kcrctab+" #sym "\",\"a\"" "\n" \
67+
" .balign 4" "\n" \
68+
"__crc_" #sym ":" "\n" \
69+
" .long " #crc "\n" \
70+
" .previous" "\n" \
71+
)
7172

7273
#define SYMBOL_FLAGS(sym, flags) \
7374
asm(" .section \"___kflagstab+" #sym "\",\"a\"" "\n" \

include/linux/module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ struct module {
419419
/* Exported symbols */
420420
const struct kernel_symbol *syms;
421421
const u32 *crcs;
422+
const u8 *flagstab;
422423
unsigned int num_syms;
423424

424425
#ifdef CONFIG_ARCH_USES_CFI_TRAPS

kernel/module/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
5757
extern const struct kernel_symbol __stop___ksymtab_gpl[];
5858
extern const u32 __start___kcrctab[];
5959
extern const u32 __start___kcrctab_gpl[];
60+
extern const u8 __start___kflagstab[];
6061

6162
#define KMOD_PATH_LEN 256
6263
extern char modprobe_path[];

kernel/module/main.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/extable.h>
1212
#include <linux/moduleloader.h>
1313
#include <linux/module_signature.h>
14+
#include <linux/module_symbol.h>
1415
#include <linux/trace_events.h>
1516
#include <linux/init.h>
1617
#include <linux/kallsyms.h>
@@ -87,7 +88,7 @@ struct mod_tree_root mod_tree __cacheline_aligned = {
8788
struct symsearch {
8889
const struct kernel_symbol *start, *stop;
8990
const u32 *crcs;
90-
enum mod_license license;
91+
const u8 *flagstab;
9192
};
9293

9394
/*
@@ -364,19 +365,21 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
364365
struct find_symbol_arg *fsa)
365366
{
366367
struct kernel_symbol *sym;
367-
368-
if (!fsa->gplok && syms->license == GPL_ONLY)
369-
return false;
368+
u8 sym_flags;
370369

371370
sym = bsearch(fsa->name, syms->start, syms->stop - syms->start,
372371
sizeof(struct kernel_symbol), cmp_name);
373372
if (!sym)
374373
return false;
375374

375+
sym_flags = *(syms->flagstab + (sym - syms->start));
376+
if (!fsa->gplok && (sym_flags & KSYM_FLAG_GPL_ONLY))
377+
return false;
378+
376379
fsa->owner = owner;
377380
fsa->crc = symversion(syms->crcs, sym - syms->start);
378381
fsa->sym = sym;
379-
fsa->license = syms->license;
382+
fsa->license = (sym_flags & KSYM_FLAG_GPL_ONLY) ? GPL_ONLY : NOT_GPL_ONLY;
380383

381384
return true;
382385
}
@@ -387,36 +390,31 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
387390
*/
388391
bool find_symbol(struct find_symbol_arg *fsa)
389392
{
390-
static const struct symsearch arr[] = {
391-
{ __start___ksymtab, __stop___ksymtab, __start___kcrctab,
392-
NOT_GPL_ONLY },
393-
{ __start___ksymtab_gpl, __stop___ksymtab_gpl,
394-
__start___kcrctab_gpl,
395-
GPL_ONLY },
393+
const struct symsearch syms = {
394+
.start = __start___ksymtab,
395+
.stop = __stop___ksymtab,
396+
.crcs = __start___kcrctab,
397+
.flagstab = __start___kflagstab,
396398
};
397399
struct module *mod;
398-
unsigned int i;
399400

400-
for (i = 0; i < ARRAY_SIZE(arr); i++)
401-
if (find_exported_symbol_in_section(&arr[i], NULL, fsa))
402-
return true;
401+
if (find_exported_symbol_in_section(&syms, NULL, fsa))
402+
return true;
403403

404404
list_for_each_entry_rcu(mod, &modules, list,
405405
lockdep_is_held(&module_mutex)) {
406-
struct symsearch arr[] = {
407-
{ mod->syms, mod->syms + mod->num_syms, mod->crcs,
408-
NOT_GPL_ONLY },
409-
{ mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
410-
mod->gpl_crcs,
411-
GPL_ONLY },
406+
const struct symsearch syms = {
407+
.start = mod->syms,
408+
.stop = mod->syms + mod->num_syms,
409+
.crcs = mod->crcs,
410+
.flagstab = mod->flagstab,
412411
};
413412

414413
if (mod->state == MODULE_STATE_UNFORMED)
415414
continue;
416415

417-
for (i = 0; i < ARRAY_SIZE(arr); i++)
418-
if (find_exported_symbol_in_section(&arr[i], mod, fsa))
419-
return true;
416+
if (find_exported_symbol_in_section(&syms, mod, fsa))
417+
return true;
420418
}
421419

422420
pr_debug("Failed to find symbol %s\n", fsa->name);
@@ -2681,6 +2679,7 @@ static int find_module_sections(struct module *mod, struct load_info *info)
26812679
sizeof(*mod->gpl_syms),
26822680
&mod->num_gpl_syms);
26832681
mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
2682+
mod->flagstab = section_addr(info, "__kflagstab");
26842683

26852684
#ifdef CONFIG_CONSTRUCTORS
26862685
mod->ctors = section_objs(info, ".ctors",
@@ -2884,8 +2883,12 @@ static int move_module(struct module *mod, struct load_info *info)
28842883
return ret;
28852884
}
28862885

2887-
static int check_export_symbol_versions(struct module *mod)
2886+
static int check_export_symbol_sections(struct module *mod)
28882887
{
2888+
if (mod->num_syms && !mod->flagstab) {
2889+
pr_err("%s: no flags for exported symbols\n", mod->name);
2890+
return -ENOEXEC;
2891+
}
28892892
#ifdef CONFIG_MODVERSIONS
28902893
if ((mod->num_syms && !mod->crcs) ||
28912894
(mod->num_gpl_syms && !mod->gpl_crcs)) {
@@ -3501,7 +3504,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
35013504
if (err)
35023505
goto free_unload;
35033506

3504-
err = check_export_symbol_versions(mod);
3507+
err = check_export_symbol_sections(mod);
35053508
if (err)
35063509
goto free_unload;
35073510

scripts/mod/modpost.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,9 +1876,9 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
18761876
if (trim_unused_exports && !sym->used)
18771877
continue;
18781878

1879-
buf_printf(buf, "KSYMTAB_%s(%s, \"%s\", \"%s\");\n",
1879+
buf_printf(buf, "KSYMTAB_%s(%s, \"%s\");\n",
18801880
sym->is_func ? "FUNC" : "DATA", sym->name,
1881-
sym->is_gpl_only ? "_gpl" : "", sym->namespace);
1881+
sym->namespace);
18821882

18831883
buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n",
18841884
sym->name, get_symbol_flags(sym));
@@ -1899,8 +1899,8 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
18991899
sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
19001900
sym->name);
19011901

1902-
buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n",
1903-
sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : "");
1902+
buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n",
1903+
sym->name, sym->crc);
19041904
}
19051905
}
19061906

0 commit comments

Comments
 (0)