Commit 33fed73a authored by Dong Kai's avatar Dong Kai Committed by Zheng Zengkai
Browse files

livepatch/core: Add support for arm for klp relocation



hulk inclusion
category: feature
bugzilla: 51923
CVE: NA

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

In the older version of livepatch implementation without ftrace on
arm, it use klp_relocs and do special relocation for klp syms. The
kpatch-build front-tools use kpatch version to generate klp_relocs.

After commit 7c8e2bdd ("livepatch: Apply vmlinux-specific KLP
relocations early") and commit 425595a7 ("livepatch: reuse module
loader code to write relocations"), the mainline klp relocation flow
is always using ".klp.rela." section and kpatch-build front-tools use
klp version to generate klp module.

The default klp_apply_section_relocs is only for 64bit and modules
with rela support. Because CONFIG_MODULES_USE_ELF_REL is set in arm,
so we modify klp relocation to support 32bit and modules using rel.
Also the kpatch-build front-tools should adapter to support this.

Signed-off-by: default avatarDong Kai <dongkai11@huawei.com>

Signed-off-by: default avatarYe Weihua <yeweihua4@huawei.com>
Reviewed-by: default avatarYang Jihong <yangjihong1@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent abb6e48f
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -258,14 +258,18 @@ static int klp_find_object_symbol(const char *objname, const char *name,
	return -EINVAL;
}

static int klp_resolve_symbols(Elf64_Shdr *sechdrs, const char *strtab,
static int klp_resolve_symbols(Elf_Shdr *sechdrs, const char *strtab,
			       unsigned int symndx, Elf_Shdr *relasec,
			       const char *sec_objname)
{
	int i, cnt, ret;
	char sym_objname[MODULE_NAME_LEN];
	char sym_name[KSYM_NAME_LEN];
#ifdef CONFIG_MODULES_USE_ELF_RELA
	Elf_Rela *relas;
#else
	Elf_Rel *relas;
#endif
	Elf_Sym *sym;
	unsigned long sympos, addr;
	bool sym_vmlinux;
@@ -283,10 +287,14 @@ static int klp_resolve_symbols(Elf64_Shdr *sechdrs, const char *strtab,
	 */
	BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128);

#ifdef CONFIG_MODULES_USE_ELF_RELA
	relas = (Elf_Rela *) relasec->sh_addr;
#else
	relas = (Elf_Rel *) relasec->sh_addr;
#endif
	/* For each rela in this klp relocation section */
	for (i = 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) {
		sym = (Elf64_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info);
	for (i = 0; i < relasec->sh_size / sizeof(*relas); i++) {
		sym = (Elf_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info);
		if (sym->st_shndx != SHN_LIVEPATCH) {
			pr_err("symbol %s is not marked as a livepatch symbol\n",
			       strtab + sym->st_name);
@@ -381,7 +389,11 @@ int klp_apply_section_relocs(struct module *pmod, Elf_Shdr *sechdrs,
	if (ret)
		return ret;

#ifdef CONFIG_MODULES_USE_ELF_RELA
	return apply_relocate_add(sechdrs, strtab, symndx, secndx, pmod);
#else
	return apply_relocate(sechdrs, strtab, symndx, secndx, pmod);
#endif
}

/*