提交 abb6e48f 编写于 作者: D Dong Kai 提交者: Zheng Zengkai

arm/module: Use plt section indices for relocations

hulk inclusion
category: feature
bugzilla: 51921
CVE: NA

---------------------------

We are planning to add livepatch without ftrace support for arm
in the next commit. However after commit 425595a7 ("livepatch:
reuse module loader code to write relocations") merged, the klp
relocations is done by apply_relocate function.

The mod->arch.{core,init}.plt pointers were problematic for livepatch
because they pointed within temporary section headers (provided by the
module loader via info->sechdrs) that would be freed after module load.

Here we take same modification based on commit c8ebf64e
("arm64/module: use plt section indices for relocations") to solve.
Signed-off-by: NDong Kai <dongkai11@huawei.com>
Signed-off-by: NYe Weihua <yeweihua4@huawei.com>
Reviewed-by: NYang Jihong <yangjihong1@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 2b9ee60d
...@@ -20,7 +20,7 @@ enum { ...@@ -20,7 +20,7 @@ enum {
#endif #endif
struct mod_plt_sec { struct mod_plt_sec {
struct elf32_shdr *plt; int plt_shndx;
int plt_count; int plt_count;
}; };
...@@ -35,7 +35,8 @@ struct mod_arch_specific { ...@@ -35,7 +35,8 @@ struct mod_arch_specific {
}; };
struct module; struct module;
u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val); u32 get_module_plt(struct module *mod, Elf32_Shdr *sechdrs,
unsigned long loc, Elf32_Addr val);
#ifdef CONFIG_THUMB2_KERNEL #ifdef CONFIG_THUMB2_KERNEL
#define HAVE_ARCH_KALLSYMS_SYMBOL_VALUE #define HAVE_ARCH_KALLSYMS_SYMBOL_VALUE
......
...@@ -34,12 +34,14 @@ static bool in_init(const struct module *mod, unsigned long loc) ...@@ -34,12 +34,14 @@ static bool in_init(const struct module *mod, unsigned long loc)
return loc - (u32)mod->init_layout.base < mod->init_layout.size; return loc - (u32)mod->init_layout.base < mod->init_layout.size;
} }
u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val) u32 get_module_plt(struct module *mod, Elf32_Shdr *sechdrs,
unsigned long loc, Elf32_Addr val)
{ {
struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core : struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
&mod->arch.init; &mod->arch.init;
struct plt_entries *plt = (struct plt_entries *)pltsec->plt->sh_addr; struct plt_entries *plt =
(struct plt_entries *)sechdrs[pltsec->plt_shndx].sh_addr;
int idx = 0; int idx = 0;
/* /*
...@@ -60,7 +62,8 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val) ...@@ -60,7 +62,8 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
} }
pltsec->plt_count++; pltsec->plt_count++;
BUG_ON(pltsec->plt_count * PLT_ENT_SIZE > pltsec->plt->sh_size); BUG_ON(pltsec->plt_count * PLT_ENT_SIZE >
sechdrs[pltsec->plt_shndx].sh_size);
if (!idx) if (!idx)
/* Populate a new set of entries */ /* Populate a new set of entries */
...@@ -193,21 +196,23 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, ...@@ -193,21 +196,23 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
unsigned long init_plts = 0; unsigned long init_plts = 0;
Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum; Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
Elf32_Sym *syms = NULL; Elf32_Sym *syms = NULL;
Elf32_Shdr *core_pltsec, *init_pltsec;
int i = 0;
/* /*
* To store the PLTs, we expand the .text section for core module code * To store the PLTs, we expand the .text section for core module code
* and for initialization code. * and for initialization code.
*/ */
for (s = sechdrs; s < sechdrs_end; ++s) { for (s = sechdrs; s < sechdrs_end; ++s, ++i) {
if (strcmp(".plt", secstrings + s->sh_name) == 0) if (strcmp(".plt", secstrings + s->sh_name) == 0)
mod->arch.core.plt = s; mod->arch.core.plt_shndx = i;
else if (strcmp(".init.plt", secstrings + s->sh_name) == 0) else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
mod->arch.init.plt = s; mod->arch.init.plt_shndx = i;
else if (s->sh_type == SHT_SYMTAB) else if (s->sh_type == SHT_SYMTAB)
syms = (Elf32_Sym *)s->sh_addr; syms = (Elf32_Sym *)s->sh_addr;
} }
if (!mod->arch.core.plt || !mod->arch.init.plt) { if (!mod->arch.core.plt_shndx || !mod->arch.init.plt_shndx) {
pr_err("%s: module PLT section(s) missing\n", mod->name); pr_err("%s: module PLT section(s) missing\n", mod->name);
return -ENOEXEC; return -ENOEXEC;
} }
...@@ -239,21 +244,23 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, ...@@ -239,21 +244,23 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
numrels, s->sh_info); numrels, s->sh_info);
} }
mod->arch.core.plt->sh_type = SHT_NOBITS; core_pltsec = sechdrs + mod->arch.core.plt_shndx;
mod->arch.core.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC; core_pltsec->sh_type = SHT_NOBITS;
mod->arch.core.plt->sh_addralign = L1_CACHE_BYTES; core_pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
mod->arch.core.plt->sh_size = round_up(core_plts * PLT_ENT_SIZE, core_pltsec->sh_addralign = L1_CACHE_BYTES;
sizeof(struct plt_entries)); core_pltsec->sh_size = round_up(core_plts * PLT_ENT_SIZE,
sizeof(struct plt_entries));
mod->arch.core.plt_count = 0; mod->arch.core.plt_count = 0;
mod->arch.init.plt->sh_type = SHT_NOBITS; init_pltsec = sechdrs + mod->arch.init.plt_shndx;
mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC; init_pltsec->sh_type = SHT_NOBITS;
mod->arch.init.plt->sh_addralign = L1_CACHE_BYTES; init_pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
mod->arch.init.plt->sh_size = round_up(init_plts * PLT_ENT_SIZE, init_pltsec->sh_addralign = L1_CACHE_BYTES;
sizeof(struct plt_entries)); init_pltsec->sh_size = round_up(init_plts * PLT_ENT_SIZE,
sizeof(struct plt_entries));
mod->arch.init.plt_count = 0; mod->arch.init.plt_count = 0;
pr_debug("%s: plt=%x, init.plt=%x\n", __func__, pr_debug("%s: plt=%x, init.plt=%x\n", __func__,
mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size); core_pltsec->sh_size, init_pltsec->sh_size);
return 0; return 0;
} }
...@@ -142,7 +142,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, ...@@ -142,7 +142,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) && if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) &&
(offset <= (s32)0xfe000000 || (offset <= (s32)0xfe000000 ||
offset >= (s32)0x02000000)) offset >= (s32)0x02000000))
offset = get_module_plt(module, loc, offset = get_module_plt(module, sechdrs, loc,
offset + loc + 8) offset + loc + 8)
- loc - 8; - loc - 8;
...@@ -265,7 +265,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, ...@@ -265,7 +265,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) && if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) &&
(offset <= (s32)0xff000000 || (offset <= (s32)0xff000000 ||
offset >= (s32)0x01000000)) offset >= (s32)0x01000000))
offset = get_module_plt(module, loc, offset = get_module_plt(module, sechdrs, loc,
offset + loc + 4) offset + loc + 4)
- loc - 4; - loc - 4;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册