diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c index 2e224435c024..cee0781112d4 100644 --- a/arch/arm64/kernel/module-plts.c +++ b/arch/arm64/kernel/module-plts.c @@ -7,6 +7,7 @@ #include #include #include +#include #include static struct plt_entry __get_adrp_add_pair(u64 dst, u64 pc, @@ -290,6 +291,7 @@ static int partition_branch_plt_relas(Elf64_Sym *syms, Elf64_Rela *rela, int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod) { + bool copy_rela_for_fips140 = false; unsigned long core_plts = 0; unsigned long init_plts = 0; Elf64_Sym *syms = NULL; @@ -321,6 +323,10 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, return -ENOEXEC; } + if (IS_ENABLED(CONFIG_CRYPTO_FIPS140) && + !strcmp(mod->name, "fips140")) + copy_rela_for_fips140 = true; + for (i = 0; i < ehdr->e_shnum; i++) { Elf64_Rela *rels = (void *)ehdr + sechdrs[i].sh_offset; int nents, numrels = sechdrs[i].sh_size / sizeof(Elf64_Rela); @@ -329,10 +335,38 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, if (sechdrs[i].sh_type != SHT_RELA) continue; +#ifdef CONFIG_CRYPTO_FIPS140 + if (copy_rela_for_fips140 && + !strcmp(secstrings + dstsec->sh_name, ".rodata")) { + void *p = kmemdup(rels, numrels * sizeof(Elf64_Rela), + GFP_KERNEL); + if (!p) { + pr_err("fips140: failed to allocate .rodata RELA buffer\n"); + return -ENOMEM; + } + mod->arch.rodata_relocations = p; + mod->arch.num_rodata_relocations = numrels; + } +#endif + /* ignore relocations that operate on non-exec sections */ if (!(dstsec->sh_flags & SHF_EXECINSTR)) continue; +#ifdef CONFIG_CRYPTO_FIPS140 + if (copy_rela_for_fips140 && + !strcmp(secstrings + dstsec->sh_name, ".text")) { + void *p = kmemdup(rels, numrels * sizeof(Elf64_Rela), + GFP_KERNEL); + if (!p) { + pr_err("fips140: failed to allocate .text RELA buffer\n"); + return -ENOMEM; + } + mod->arch.text_relocations = p; + mod->arch.num_text_relocations = numrels; + } +#endif + /* * sort branch relocations requiring a PLT by type, symbol index * and addend