anolis: module: introduce the sig_enforce_subsys param
ANBZ: #9703 Introduce the sig_enforce_subsys module parameter to allow users to control the enforcement of signature verification for a specific subsystem module. Now we support gpu, block and net subsys. Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> Reviewed-by: Xunlei Pang <xlpang@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/3662
This commit is contained in:
parent
85d5e42cc3
commit
2f4c516abd
|
@ -3061,6 +3061,13 @@
|
|||
Note that if CONFIG_MODULE_SIG_FORCE is set, that
|
||||
is always true, so this option does nothing.
|
||||
|
||||
module.sig_enforce_subsys
|
||||
[KNL] When CONFIG_MODULE_SIG is set, this means that
|
||||
modules the user set without (valid) signatures will
|
||||
fail to load. Note that CONFIG_MODULE_SIG_FORCE is set,
|
||||
that is always true, so this option does nothing.
|
||||
Now we support gpu, block and net.
|
||||
|
||||
module_blacklist= [KNL] Do not load a comma-separated list of
|
||||
modules. Useful for debugging problem modules.
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ struct load_info {
|
|||
struct {
|
||||
unsigned int sym, str, mod, vers, info, pcpu;
|
||||
} index;
|
||||
|
||||
unsigned long subsys;
|
||||
};
|
||||
|
||||
extern int mod_verify_sig(const void *mod, struct load_info *info);
|
||||
|
|
|
@ -68,6 +68,72 @@
|
|||
#define ARCH_SHF_SMALL 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MODULE_SIG
|
||||
static char *sig_enforce_subsys = "";
|
||||
|
||||
module_param(sig_enforce_subsys, charp, 0644);
|
||||
MODULE_PARM_DESC(sig_enforce_subsys, "Enforce subsys modules signature check");
|
||||
|
||||
enum modules_subsys {
|
||||
MODULE_SUBSYS_GPU,
|
||||
MODULE_SUBSYS_BLOCK,
|
||||
MODULE_SUBSYS_NET,
|
||||
};
|
||||
|
||||
static void set_module_subsys(struct load_info *info, const char *name)
|
||||
{
|
||||
char *key_intf_blk = "device_add_disk";
|
||||
char *key_intf_scsi = "scsi_host_alloc";
|
||||
char *key_intf_net = "register_netdev";
|
||||
char *key_intf_gpu = "drm_";
|
||||
|
||||
if (info->subsys)
|
||||
return;
|
||||
|
||||
if (!strncmp(name, key_intf_gpu, strlen(key_intf_gpu)))
|
||||
set_bit(MODULE_SUBSYS_GPU, &info->subsys);
|
||||
|
||||
if (!strncmp(name, key_intf_blk, strlen(key_intf_blk)) ||
|
||||
!strncmp(name, key_intf_scsi, strlen(key_intf_scsi)))
|
||||
set_bit(MODULE_SUBSYS_BLOCK, &info->subsys);
|
||||
|
||||
/* register_netdev or register_netdevice */
|
||||
if (!strncmp(name, key_intf_net, strlen(key_intf_net)))
|
||||
set_bit(MODULE_SUBSYS_NET, &info->subsys);
|
||||
}
|
||||
|
||||
static int force_subsys_sig_check(struct load_info *info)
|
||||
{
|
||||
if (info->sig_ok)
|
||||
return 0;
|
||||
|
||||
if (test_bit(MODULE_SUBSYS_GPU, &info->subsys) &&
|
||||
parse_option_str(sig_enforce_subsys, "gpu"))
|
||||
goto err;
|
||||
|
||||
if (test_bit(MODULE_SUBSYS_BLOCK, &info->subsys) &&
|
||||
parse_option_str(sig_enforce_subsys, "block"))
|
||||
goto err;
|
||||
|
||||
if (test_bit(MODULE_SUBSYS_NET, &info->subsys) &&
|
||||
parse_option_str(sig_enforce_subsys, "net"))
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
pr_notice("%s: Loading is rejected, because of wrong signature or key missing!\n",
|
||||
info->name);
|
||||
return -EKEYREJECTED;
|
||||
}
|
||||
#else
|
||||
static void set_module_subsys(struct load_info *info, const char *name) {}
|
||||
|
||||
static int force_subsys_sig_check(struct load_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Modules' sections will be aligned on page boundaries
|
||||
* to ensure complete separation of code and data, but
|
||||
|
@ -2491,7 +2557,7 @@ static bool ignore_undef_symbol(Elf_Half emachine, const char *name)
|
|||
}
|
||||
|
||||
/* Change all symbols so that st_value encodes the pointer directly. */
|
||||
static int simplify_symbols(struct module *mod, const struct load_info *info)
|
||||
static int simplify_symbols(struct module *mod, struct load_info *info)
|
||||
{
|
||||
Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
|
||||
Elf_Sym *sym = (void *)symsec->sh_addr;
|
||||
|
@ -2531,6 +2597,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
|
|||
ksym = resolve_symbol_wait(mod, info, name);
|
||||
/* Ok if resolved. */
|
||||
if (ksym && !IS_ERR(ksym)) {
|
||||
set_module_subsys(info, name);
|
||||
sym[i].st_value = kernel_symbol_value(ksym);
|
||||
break;
|
||||
}
|
||||
|
@ -4186,6 +4253,10 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
|||
if (err < 0)
|
||||
goto free_modinfo;
|
||||
|
||||
err = force_subsys_sig_check(info);
|
||||
if (err < 0)
|
||||
goto free_modinfo;
|
||||
|
||||
err = apply_relocations(mod, info);
|
||||
if (err < 0)
|
||||
goto free_modinfo;
|
||||
|
|
Loading…
Reference in New Issue