diff --git a/xen/arch/arm/livepatch.c b/xen/arch/arm/livepatch.c index 679abf1d63..f467d9db4a 100644 --- a/xen/arch/arm/livepatch.c +++ b/xen/arch/arm/livepatch.c @@ -84,6 +84,39 @@ void arch_livepatch_unmask(void) local_abort_enable(); } +bool arch_livepatch_symbol_ok(const struct livepatch_elf *elf, + const struct livepatch_elf_sym *sym) +{ + /* + * - Mapping symbols - denote the "start of a sequence of bytes of the + * appropriate type" to mark certain features - such as start of region + * containing data ($d); ARM ($a), or A64 ($x) instructions. + * We ignore Thumb instructions ($t) as we shouldn't have them. + * + * The format is either short: '$x' or long: '$x.'. We do not + * need this and more importantly - each payload will contain this + * resulting in symbol collisions. + */ + if ( sym->name[0] == '$' && sym->name[1] != '\0' ) + { + char p = sym->name[1]; + size_t len = strlen(sym->name); + + if ( (len >= 3 && (sym->name[2] == '.' )) || (len == 2) ) + { + if ( p == 'd' || +#ifdef CONFIG_ARM_32 + p == 'a' +#else + p == 'x' +#endif + ) + return false; + } + } + return true; +} + int arch_livepatch_perform_rel(struct livepatch_elf *elf, const struct livepatch_elf_sec *base, const struct livepatch_elf_sec *rela) diff --git a/xen/arch/x86/livepatch.c b/xen/arch/x86/livepatch.c index b0d81d7ceb..7a369a004b 100644 --- a/xen/arch/x86/livepatch.c +++ b/xen/arch/x86/livepatch.c @@ -124,6 +124,13 @@ int arch_livepatch_verify_elf(const struct livepatch_elf *elf) return 0; } +bool arch_livepatch_symbol_ok(const struct livepatch_elf *elf, + const struct livepatch_elf_sym *sym) +{ + /* No special checks on x86. */ + return true; +} + int arch_livepatch_perform_rel(struct livepatch_elf *elf, const struct livepatch_elf_sec *base, const struct livepatch_elf_sec *rela) diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index 2d08c9af60..fc8ef9999a 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -747,7 +747,7 @@ static bool_t is_payload_symbol(const struct livepatch_elf *elf, !strncmp(sym->name, ".L", 2) ) return 0; - return 1; + return arch_livepatch_symbol_ok(elf, sym); } static int build_symbol_table(struct payload *payload, diff --git a/xen/include/xen/livepatch.h b/xen/include/xen/livepatch.h index b7b84e705f..e8c67d6b01 100644 --- a/xen/include/xen/livepatch.h +++ b/xen/include/xen/livepatch.h @@ -48,6 +48,8 @@ bool_t is_patch(const void *addr); /* Arch hooks. */ int arch_livepatch_verify_elf(const struct livepatch_elf *elf); +bool arch_livepatch_symbol_ok(const struct livepatch_elf *elf, + const struct livepatch_elf_sym *sym); int arch_livepatch_perform_rel(struct livepatch_elf *elf, const struct livepatch_elf_sec *base, const struct livepatch_elf_sec *rela);