| From foo@baz Sat Sep 29 04:24:28 PDT 2018 |
| From: Jessica Yu <jeyu@kernel.org> |
| Date: Tue, 5 Jun 2018 10:22:52 +0200 |
| Subject: module: exclude SHN_UNDEF symbols from kallsyms api |
| |
| From: Jessica Yu <jeyu@kernel.org> |
| |
| [ Upstream commit 9f2d1e68cf4d641def734adaccfc3823d3575e6c ] |
| |
| Livepatch modules are special in that we preserve their entire symbol |
| tables in order to be able to apply relocations after module load. The |
| unwanted side effect of this is that undefined (SHN_UNDEF) symbols of |
| livepatch modules are accessible via the kallsyms api and this can |
| confuse symbol resolution in livepatch (klp_find_object_symbol()) and |
| cause subtle bugs in livepatch. |
| |
| Have the module kallsyms api skip over SHN_UNDEF symbols. These symbols |
| are usually not available for normal modules anyway as we cut down their |
| symbol tables to just the core (non-undefined) symbols, so this should |
| really just affect livepatch modules. Note that this patch doesn't |
| affect the display of undefined symbols in /proc/kallsyms. |
| |
| Reported-by: Josh Poimboeuf <jpoimboe@redhat.com> |
| Tested-by: Josh Poimboeuf <jpoimboe@redhat.com> |
| Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> |
| Signed-off-by: Jessica Yu <jeyu@kernel.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/module.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| --- a/kernel/module.c |
| +++ b/kernel/module.c |
| @@ -4067,7 +4067,7 @@ static unsigned long mod_find_symname(st |
| |
| for (i = 0; i < kallsyms->num_symtab; i++) |
| if (strcmp(name, symname(kallsyms, i)) == 0 && |
| - kallsyms->symtab[i].st_info != 'U') |
| + kallsyms->symtab[i].st_shndx != SHN_UNDEF) |
| return kallsyms->symtab[i].st_value; |
| return 0; |
| } |
| @@ -4113,6 +4113,10 @@ int module_kallsyms_on_each_symbol(int ( |
| if (mod->state == MODULE_STATE_UNFORMED) |
| continue; |
| for (i = 0; i < kallsyms->num_symtab; i++) { |
| + |
| + if (kallsyms->symtab[i].st_shndx == SHN_UNDEF) |
| + continue; |
| + |
| ret = fn(data, symname(kallsyms, i), |
| mod, kallsyms->symtab[i].st_value); |
| if (ret != 0) |