anolis: module: redirect kmalloc related symbols

ANBZ: #9065

During module loading, when processing relocation symbols, memory
allocation symbols such as __kmalloc are specially handled to make them
point to symbols dedicated for out-of-tree (OOT) modules, thus obtaining
memory from dedicated slabs.

Signed-off-by: Yi Tao <escape@linux.alibaba.com>
Reviewed-by: Xu Yu <xuyu@linux.alibaba.com>
Reviewed-by: Guixin Liu <kanie@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/3208
This commit is contained in:
Yi Tao 2024-03-22 16:36:31 +08:00 committed by 小龙
parent baa47e1aa7
commit 1f31422bb6
2 changed files with 89 additions and 3 deletions

View File

@ -535,7 +535,7 @@ struct module {
struct error_injection_entry *ei_funcs;
unsigned int num_ei_funcs;
#endif
unsigned int oot_isolation_index;
CK_KABI_RESERVE(1)
CK_KABI_RESERVE(2)
CK_KABI_RESERVE(3)

View File

@ -591,6 +591,54 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
return false;
}
#define OOT_POOL_NUM 16
struct redirect_sym {
char *src_name;
char *dst_name[OOT_POOL_NUM];
};
#define DEFINE_REDIRECT_SYM(__src_name, __dst_name) \
{ \
.src_name = __src_name, \
.dst_name = { \
__dst_name "_0", \
__dst_name "_1", \
__dst_name "_2", \
__dst_name "_3", \
__dst_name "_4", \
__dst_name "_5", \
__dst_name "_6", \
__dst_name "_7", \
__dst_name "_8", \
__dst_name "_9", \
__dst_name "_10", \
__dst_name "_11", \
__dst_name "_12", \
__dst_name "_13", \
__dst_name "_14", \
__dst_name "_15", \
} \
}
static struct redirect_sym redirect_syms[] = {
DEFINE_REDIRECT_SYM("kmalloc_caches", "oot_kmalloc_caches"),
DEFINE_REDIRECT_SYM("__kmalloc", "oot___kmalloc"),
DEFINE_REDIRECT_SYM("__kmalloc_node", "oot___kmalloc_node"),
{},
};
static const char *find_true_name(const char *name, struct module *mod)
{
struct redirect_sym *rsym;
for (rsym = redirect_syms; rsym->src_name; rsym++)
if (!strcmp(name, rsym->src_name))
return rsym->dst_name[mod->oot_isolation_index];
return name;
}
/* Find an exported symbol and return it, along with, (optional) crc and
* (optional) module which owns it. Needs preempt disabled or module_mutex. */
static const struct kernel_symbol *find_symbol(const char *name,
@ -1330,7 +1378,7 @@ static int check_version(const struct load_info *info,
for (i = 0; i < num_versions; i++) {
u32 crcval;
if (strcmp(versions[i].name, symname) != 0)
if (strcmp(versions[i].name, find_true_name(symname, mod)) != 0)
continue;
if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
@ -1476,7 +1524,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
*/
sched_annotate_sleep();
mutex_lock(&module_mutex);
sym = find_symbol(name, &owner, &crc, &license,
sym = find_symbol(find_true_name(name, mod), &owner, &crc, &license,
!(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
if (!sym)
goto unlock;
@ -2229,6 +2277,39 @@ void __weak module_arch_freeing_init(struct module *mod)
{
}
struct module *oot_table[OOT_POOL_NUM];
static void get_oot_mempool(struct module *mod)
{
int i;
//TODO: check this mod need oot mempool
mutex_lock(&module_mutex);
for (i = 0; i < OOT_POOL_NUM; i++) {
if (!oot_table[i]) {
oot_table[i] = mod;
mod->oot_isolation_index = i;
pr_info("Module %s use oot-kmalloc-%d.\n", mod->name, i);
break;
}
}
mutex_unlock(&module_mutex);
if (mod->oot_isolation_index == -1)
pr_info("Module %s can't use oot-kmalloc because pool exhausted.\n", mod->name);
}
static void put_oot_mempool(struct module *mod)
{
//TODO: check this mod need oot mempool
mutex_lock(&module_mutex);
if (oot_table[mod->oot_isolation_index] == mod)
oot_table[mod->oot_isolation_index] = NULL;
else
WARN_ON("oot mempool dismatch with owner!!!\n");
mutex_unlock(&module_mutex);
}
/* Free a module, remove from lists, etc. */
static void free_module(struct module *mod)
{
@ -2242,6 +2323,8 @@ static void free_module(struct module *mod)
mod->state = MODULE_STATE_UNFORMED;
mutex_unlock(&module_mutex);
put_oot_mempool(mod);
/* Remove dynamic debug info */
ddebug_remove_module(mod->name);
@ -4048,6 +4131,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
/* Set up MODINFO_ATTR fields */
setup_modinfo(mod, info);
get_oot_mempool(mod);
/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(mod, info);
if (err < 0)
@ -4138,6 +4223,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
free_arch_cleanup:
module_arch_cleanup(mod);
free_modinfo:
put_oot_mempool(mod);
free_modinfo(mod);
free_unload:
module_unload_free(mod);