ANDROID: kallsyms: ignore ThinLTO+CFI hash suffix in kallsyms_lookup_name()

Similar to commit f683c8dc7f ("ANDROID: kallsyms: strip hashes from
static functions with ThinLTO and CFI"), since LLVM adds a hash to
static function names when CONFIG_THINLTO and CFI are enabled, callers
of kallsyms_lookup_name() which aren't aware of the additional suffix
will fail to find the symbol. One example is kprobes (both compiled
and the dynamic events) which rely on this to resolve the function
name to attach a kprobe/kretprobe to.

Address this by also calling the cleanup_symbol_name() helper from
kallsyms_lookup_name() when failing to match a symbol by name.
This will strip off the hash suffix, if any, and attempt the
strcmp() again.

Bug: 167595670
Change-Id: I4c79c818c29b4b82a94a5a7e86ae9783a41e853d
Signed-off-by: Jack Pham <jackp@codeaurora.org>
This commit is contained in:
Jack Pham 2020-09-09 14:52:54 -07:00 committed by Todd Kjos
parent 1bb4dcbb7a
commit eaf38dc2bb

View File

@ -159,6 +159,26 @@ static unsigned long kallsyms_sym_address(int idx)
return kallsyms_relative_base - 1 - kallsyms_offsets[idx];
}
#if defined(CONFIG_CFI_CLANG) && defined(CONFIG_THINLTO)
/*
* LLVM appends a hash to static function names when ThinLTO and CFI are
* both enabled, which causes confusion and potentially breaks user space
* tools, so we will strip the postfix from expanded symbol names.
*/
static inline char *cleanup_symbol_name(char *s)
{
char *res = NULL;
res = strrchr(s, '$');
if (res)
*res = '\0';
return res;
}
#else
static inline char *cleanup_symbol_name(char *s) { return NULL; }
#endif
/* Lookup the address for this symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name)
{
@ -171,6 +191,9 @@ unsigned long kallsyms_lookup_name(const char *name)
if (strcmp(namebuf, name) == 0)
return kallsyms_sym_address(i);
if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0)
return kallsyms_sym_address(i);
}
return module_kallsyms_lookup_name(name);
}
@ -269,24 +292,6 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
!!__bpf_address_lookup(addr, symbolsize, offset, namebuf);
}
#if defined(CONFIG_CFI_CLANG) && defined(CONFIG_THINLTO)
/*
* LLVM appends a hash to static function names when ThinLTO and CFI are
* both enabled, which causes confusion and potentially breaks user space
* tools, so we will strip the postfix from expanded symbol names.
*/
static inline void cleanup_symbol_name(char *s)
{
char *res;
res = strrchr(s, '$');
if (res)
*res = '\0';
}
#else
static inline void cleanup_symbol_name(char *s) {}
#endif
/*
* Lookup an address
* - modname is set to NULL if it's in the kernel.