ANDROID: enforce symbol import protection
The module loader will check each unsigned module's imported symbols against the generated list of permitted imports. If any lookup fails, the module will be rejected and fail to load. Bug: 393366754 Change-Id: Ifd4d242135eaba1f215f982c5d6e8a76b1fc8522 Signed-off-by: Sid Nayyar <sidnayyar@google.com>
This commit is contained in:
@@ -90,7 +90,7 @@ struct symsearch {
|
||||
enum mod_license license;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MODULE_SIG_PROTECT
|
||||
#if defined(CONFIG_MODULE_SIG_PROTECT) || defined(CONFIG_TRIM_UNUSED_KSYMS)
|
||||
static int cmp_string(const void *a, const void *b)
|
||||
{
|
||||
return strcmp((const char *)a, *(const char **)b);
|
||||
@@ -1148,12 +1148,25 @@ static bool inherit_taint(struct module *mod, struct module *owner, const char *
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRIM_UNUSED_KSYMS
|
||||
static bool is_permitted_symbol_import(const char *name)
|
||||
{
|
||||
return bsearch(name, permitted_symbol_imports,
|
||||
permitted_symbol_imports_count,
|
||||
sizeof(const char *), cmp_string) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Resolve a symbol for this module. I.e. if we find one, record usage. */
|
||||
static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||
const struct load_info *info,
|
||||
const char *name,
|
||||
char ownername[])
|
||||
{
|
||||
#ifdef CONFIG_TRIM_UNUSED_KSYMS
|
||||
bool is_vendor_module;
|
||||
bool is_vendor_exported_symbol;
|
||||
#endif
|
||||
struct find_symbol_arg fsa = {
|
||||
.name = name,
|
||||
.gplok = !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)),
|
||||
@@ -1190,6 +1203,26 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||
goto getname;
|
||||
}
|
||||
|
||||
/*
|
||||
* ANDROID GKI
|
||||
*
|
||||
* Vendor (i.e., unsigned) modules are only permitted to use:
|
||||
*
|
||||
* 1. symbols exported by other vendor (unsigned) modules
|
||||
* 2. symbols which are permitted explicitly
|
||||
*/
|
||||
#ifdef CONFIG_TRIM_UNUSED_KSYMS
|
||||
is_vendor_module = !mod->sig_ok;
|
||||
is_vendor_exported_symbol = fsa.owner && !fsa.owner->sig_ok;
|
||||
|
||||
if (is_vendor_module &&
|
||||
!is_vendor_exported_symbol &&
|
||||
!is_permitted_symbol_import(name)) {
|
||||
fsa.sym = ERR_PTR(-EACCES);
|
||||
goto getname;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = ref_module(mod, fsa.owner);
|
||||
if (err) {
|
||||
fsa.sym = ERR_PTR(err);
|
||||
@@ -1487,9 +1520,15 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
|
||||
ignore_undef_symbol(info->hdr->e_machine, name)))
|
||||
break;
|
||||
|
||||
ret = PTR_ERR(ksym) ?: -ENOENT;
|
||||
pr_warn("%s: Unknown symbol %s (err %d)\n",
|
||||
mod->name, name, ret);
|
||||
if (PTR_ERR(ksym) == -EACCES) {
|
||||
ret = -EACCES;
|
||||
pr_warn("%s: Protected symbol: %s (err %d)\n",
|
||||
mod->name, name, ret);
|
||||
} else {
|
||||
ret = PTR_ERR(ksym) ?: -ENOENT;
|
||||
pr_warn("%s: Unknown symbol %s (err %d)\n",
|
||||
mod->name, name, ret);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user