ANDROID: modpost: generate protected exports

These are symbols that unsigned modules may not export.

* kernel/module/internal.h - declares protected exports
* modpost generates protected-exports.c - defines protected exports

Bug: 393366754
Change-Id: I3e6d630542875e35754126e64bc279313fc131b9
Signed-off-by: Sid Nayyar <sidnayyar@google.com>
This commit is contained in:
Sid Nayyar
2025-01-30 09:49:53 -08:00
parent 54bfd8db38
commit 48559833d1
3 changed files with 77 additions and 1 deletions

View File

@@ -420,3 +420,11 @@ static inline int same_magic(const char *amagic, const char *bmagic, bool has_cr
return strcmp(amagic, bmagic) == 0;
}
#endif /* CONFIG_MODVERSIONS */
#ifdef CONFIG_MODULE_SIG_PROTECT
extern const char *const protected_symbol_exports[];
extern size_t protected_symbol_exports_count;
#else
#define protected_symbol_exports NULL
#define protected_symbol_exports_count 0UL
#endif

View File

@@ -20,6 +20,7 @@
#include <limits.h>
#include <stdbool.h>
#include <errno.h>
#include <stdlib.h>
#include <hashtable.h>
#include <list.h>
@@ -60,6 +61,8 @@ static bool extra_warn;
bool target_is_big_endian;
bool host_is_big_endian;
static unsigned int nr_module_exported_symbols;
/*
* Cut off the warnings when there are too many. This typically occurs when
* vmlinux is missing. ('make modules' without building vmlinux.)
@@ -99,6 +102,11 @@ static inline bool strends(const char *str, const char *postfix)
return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
}
static int symbol_cmp(const void *a, const void *b)
{
return strcmp(*(const char **)a, *(const char **)b);
}
char *read_text_file(const char *filename)
{
struct stat st;
@@ -365,6 +373,9 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
s->namespace = xstrdup(namespace);
list_add_tail(&s->list, &mod->exported_symbols);
hash_add_symbol(s);
if (!mod->is_vmlinux && !mod->from_dump) {
++nr_module_exported_symbols;
}
return s;
}
@@ -2179,17 +2190,65 @@ static void check_host_endian(void)
}
}
static void handle_protected_modules_list(const char *fname)
{
char *buf, *p, *name;
buf = read_text_file(fname);
p = buf;
while ((name = strsep(&p, "\n"))) {
struct module *mod = find_module(name);
if (mod)
mod->is_protected = true;
}
free(buf);
}
static void write_protected_exports_c_file(void)
{
const char* symbols[nr_module_exported_symbols];
unsigned int symbols_size = 0;
unsigned int i;
struct module *mod;
struct symbol *sym;
struct buffer buf = {};
list_for_each_entry(mod, &modules, list) {
if (mod->is_vmlinux || mod->from_dump || !mod->is_protected)
continue;
list_for_each_entry(sym, &mod->exported_symbols, list) {
symbols[symbols_size++] = sym->name;
}
}
qsort(symbols, symbols_size, sizeof(const char*), symbol_cmp);
buf_printf(&buf, "#include \"../kernel/module/internal.h\"\n\n");
buf_printf(&buf, "size_t protected_symbol_exports_count = %d;\n\n", symbols_size);
buf_printf(&buf, "const char *const protected_symbol_exports[] = {\n");
for (i=0; i<symbols_size; ++i) {
buf_printf(&buf, "\t\"%s\",\n", symbols[i]);
}
buf_printf(&buf, "};\n");
write_if_changed(&buf, ".vmlinux.protected-exports.c");
free(buf.p);
}
int main(int argc, char **argv)
{
struct module *mod;
char *missing_namespace_deps = NULL;
char *unused_exports_white_list = NULL;
char *protected_modules_list = NULL;
char *dump_write = NULL, *files_source = NULL;
int opt;
LIST_HEAD(dump_lists);
struct dump_list *dl, *dl2;
while ((opt = getopt(argc, argv, "ei:MmnT:to:au:WwENd:v:xb")) != -1) {
while ((opt = getopt(argc, argv, "ei:MmnT:to:au:WwENd:v:xbp:")) != -1) {
switch (opt) {
case 'e':
external_module = true;
@@ -2247,6 +2306,9 @@ int main(int argc, char **argv)
case 'x':
extended_modversions = true;
break;
case 'p':
protected_modules_list = optarg;
break;
default:
exit(1);
}
@@ -2300,5 +2362,10 @@ int main(int argc, char **argv)
warn("suppressed %u unresolved symbol warnings because there were too many)\n",
nr_unresolved - MAX_UNRESOLVED_REPORTS);
if (protected_modules_list) {
handle_protected_modules_list(protected_modules_list);
write_protected_exports_c_file();
}
return error_occurred ? 1 : 0;
}

View File

@@ -89,6 +89,7 @@ struct module {
bool seen;
bool has_init;
bool has_cleanup;
bool is_protected; /* true if module exports are protected */
struct buffer dev_table_buf;
char srcversion[25];
// Missing namespace dependencies