ANDROID: modpost: generate permitted imports

These are symbols permitted to be imported by unsigned modules.

* kernel/module/internal.h - declares permitted imports
* modpost generates permitted-imports.c - defines permitted imports

Bug: 393366754
Change-Id: I8f884a11b32565e82ace25b61f32c4f23c190670
Signed-off-by: Sid Nayyar <sidnayyar@google.com>
This commit is contained in:
Sid Nayyar
2025-05-01 10:42:46 +00:00
parent cf33526ab7
commit 19ee9bccea
2 changed files with 55 additions and 5 deletions

View File

@@ -428,3 +428,11 @@ extern size_t protected_symbol_exports_count;
#define protected_symbol_exports NULL
#define protected_symbol_exports_count 0UL
#endif
#ifdef CONFIG_TRIM_UNUSED_KSYMS
extern const char *const permitted_symbol_imports[];
extern size_t permitted_symbol_imports_count;
#else
#define permitted_symbol_imports NULL
#define permitted_symbol_imports_count 0UL
#endif

View File

@@ -62,6 +62,7 @@ bool target_is_big_endian;
bool host_is_big_endian;
static unsigned int nr_module_exported_symbols;
static unsigned int nr_white_list_symbols;
/*
* Cut off the warnings when there are too many. This typically occurs when
@@ -1737,18 +1738,29 @@ static void check_exports(struct module *mod)
}
}
static void handle_white_list_exports(const char *white_list)
struct permitted_symbol {
struct list_head list;
const char *name;
};
static void handle_white_list_exports(const char *white_list,
struct list_head *permitted_symbols)
{
char *buf, *p, *name;
struct permitted_symbol *ps;
buf = read_text_file(white_list);
p = buf;
while ((name = strsep(&p, "\n"))) {
struct symbol *sym = find_symbol(name);
if (sym)
if (sym) {
sym->used = true;
ps = xmalloc(sizeof(*ps));
ps->name = sym->name;
list_add_tail(&ps->list, permitted_symbols);
++nr_white_list_symbols;
}
}
free(buf);
@@ -2237,6 +2249,31 @@ static void write_protected_exports_c_file(void)
free(buf.p);
}
static void write_permitted_imports_c_file(struct list_head *permitted_symbols)
{
struct permitted_symbol *ps, *ps2;
const char *symbols[nr_white_list_symbols];
unsigned int i = 0;
struct buffer buf = {};
list_for_each_entry_safe(ps, ps2, permitted_symbols, list) {
symbols[i++] = ps->name;
list_del(&ps->list);
free(ps);
}
qsort(symbols, nr_white_list_symbols, sizeof(const char *), symbol_cmp);
buf_printf(&buf, "#include \"../kernel/module/internal.h\"\n\n");
buf_printf(&buf, "size_t permitted_symbol_imports_count = %d;\n\n", nr_white_list_symbols);
buf_printf(&buf, "const char *const permitted_symbol_imports[] = {\n");
for (i=0; i<nr_white_list_symbols; ++i) {
buf_printf(&buf, "\t\"%s\",\n", symbols[i]);
}
buf_printf(&buf, "};\n");
write_if_changed(&buf, ".vmlinux.permitted-imports.c");
free(buf.p);
}
int main(int argc, char **argv)
{
struct module *mod;
@@ -2336,8 +2373,13 @@ int main(int argc, char **argv)
check_exports(mod);
}
if (unused_exports_white_list)
handle_white_list_exports(unused_exports_white_list);
if (trim_unused_exports) {
LIST_HEAD(permitted_imports);
if (unused_exports_white_list)
handle_white_list_exports(unused_exports_white_list,
&permitted_imports);
write_permitted_imports_c_file(&permitted_imports);
}
list_for_each_entry(mod, &modules, list) {
if (mod->from_dump)