diff -drupN a/kernel/module.c b/kernel/module.c --- a/kernel/module.c 2018-08-06 17:23:04.000000000 +0300 +++ b/kernel/module.c 2022-06-12 05:28:14.000000000 +0300 @@ -2099,6 +2099,8 @@ void __weak module_arch_freeing_init(str { } +static void cfi_cleanup(struct module *mod); + /* Free a module, remove from lists, etc. */ static void free_module(struct module *mod) { @@ -2140,6 +2142,10 @@ static void free_module(struct module *m /* This may be empty, but that's OK */ disable_ro_nx(&mod->init_layout); + + /* Clean up CFI for the module. */ + cfi_cleanup(mod); + module_arch_freeing_init(mod); module_memfree(mod->init_layout.base); kfree(mod->args); @@ -3321,6 +3327,8 @@ int __weak module_finalize(const Elf_Ehd return 0; } +static void cfi_init(struct module *mod); + static int post_relocation(struct module *mod, const struct load_info *info) { /* Sort exception table now relocations are done. */ @@ -3333,6 +3341,9 @@ static int post_relocation(struct module /* Setup kallsyms-specific fields. */ add_kallsyms(mod, info); + /* Setup CFI for the module. */ + cfi_init(mod); + /* Arch-specific module finalizing. */ return module_finalize(info->hdr, info->sechdrs, mod); } @@ -4067,6 +4078,22 @@ int module_kallsyms_on_each_symbol(int ( } #endif /* CONFIG_KALLSYMS */ +static void cfi_init(struct module *mod) +{ +#ifdef CONFIG_CFI_CLANG + mod->cfi_check = + (cfi_check_fn)mod_find_symname(mod, CFI_CHECK_FN_NAME); + cfi_module_add(mod, module_addr_min, module_addr_max); +#endif +} + +static void cfi_cleanup(struct module *mod) +{ +#ifdef CONFIG_CFI_CLANG + cfi_module_remove(mod, module_addr_min, module_addr_max); +#endif +} + static char *module_flags(struct module *mod, char *buf) { int bx = 0;