modpost: validate symbol names also in find_elf_symbol
PATCH 1/1 modpost: validate symbol names also in find_elf_symbol
If an ARM mapping symbol shares an address with a valid symbol, find_elf_symbol can currently return the mapping symbol instead, as the symbol is not validated. This can result in confusing warnings:
WARNING: vmlinux.o(.text+0x18f4028): Section mismatch in reference from the function set_reset_devices() to the variable .init.text:$x.0
This change adds a call to is_valid_name to find_elf_symbol, similarly to how it's already used in find_elf_symbol2.
--- scripts/mod/modpost.c | 50 ++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-)
scripts/mod/modpost.c +26 -24
@@ -1204,6 +1204,30 @@ static int secref_whitelist(const struct sectioncheck *mismatch,return 1 ; } +static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("axtd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} + +/* +* If there's no name there, ignore it; likewise, ignore it if it's +* one of the magic symbols emitted used by current ARM tools. +* +* Otherwise if find_symbols_between() returns those symbols, they'll +* fail the whitelist tests and cause lots of false alarms ... fixable +* only by merging __exit and __init sections into __text, bloating +* the kernel (which is especially evil on embedded platforms). +*/ +static inline int is_valid_name (struct elf_info *elf,Elf_Sym *sym) +{ +const char *name = elf->strtab + sym->st_name; + +if (!name || !strlen (name)) +return 0 ; +return !is_arm_mapping_symbol (name); +} +/** * Find symbol based on relocation record info. * In some cases the symbol supplied is a valid symbol so
@@ -1229,6 +1253,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,continue ;if (ELF_ST_TYPE (sym->st_info) ==STT_SECTION )continue ; +if (!is_valid_name (elf, sym)) +continue ;if (sym->st_value == addr)return sym;/* Find a symbol nearby - addr are maybe negative */
@@ -1247,30 +1273,6 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,return NULL ; } -static inline int is_arm_mapping_symbol (const char *str) -{ -return str[0 ] =='$' &&strchr ("axtd" , str[1 ]) - && (str[2 ] =='\0' || str[2 ] =='.' ); -} - -/* -* If there's no name there, ignore it; likewise, ignore it if it's -* one of the magic symbols emitted used by current ARM tools. -* -* Otherwise if find_symbols_between() returns those symbols, they'll -* fail the whitelist tests and cause lots of false alarms ... fixable -* only by merging __exit and __init sections into __text, bloating -* the kernel (which is especially evil on embedded platforms). -*/ -static inline int is_valid_name (struct elf_info *elf,Elf_Sym *sym) -{ -const char *name = elf->strtab + sym->st_name; - -if (!name || !strlen (name)) -return 0 ; -return !is_arm_mapping_symbol (name); -} -/* * Find symbols before or equal addr and after addr - in the section sec. * If we find two symbols with equal offset prefer one with a valid name.
Signature · 1 line
2.19.1.568.g152ad8e336-goog
Quoted 5 lines · Sami Tolvanen
If an ARM mapping symbol shares an address with a valid symbol,
find_elf_symbolcan currently return the mapping symbol instead, as the symbol is not validated. This can result in confusing warnings:
Quoted 8 lines
WARNING:
vmlinux.o(.text+0x18f4028): Section mismatch in reference from the functionset_reset_devices()to the variable .init.text:$x.0This change adds a call to
is_valid_nametofind_elf_symbol, similarly to how it's already used infind_elf_symbol2.Signed-off-by Sami Tolvanen <[email protected]>---
Applied to linux-kbuild.
Thanks!
Quoted 81 lines
scripts/mod/modpost.c | 50 ++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-)scripts/mod/modpost.c +26
-25@@ -1204,6 +1204,30 @@ static int secref_whitelist(const struct sectioncheck *mismatch,return 1 ; } +static inline int is_arm_mapping_symbol (const char *str) +{ +return str[0 ] =='$' &&strchr ("axtd" , str[1 ]) + && (str[2 ] =='\0' || str[2 ] =='.' ); +} + +/* +* If there's no name there, ignore it; likewise, ignore it if it's +* one of the magic symbols emitted used by current ARM tools. +* +* Otherwise if find_symbols_between() returns those symbols, they'll +* fail the whitelist tests and cause lots of false alarms ... fixable +* only by merging __exit and __init sections into __text, bloating +* the kernel (which is especially evil on embedded platforms). +*/ +static inline int is_valid_name (struct elf_info *elf,Elf_Sym *sym) +{ +const char *name = elf->strtab + sym->st_name; + +if (!name || !strlen (name)) +return 0 ; +return !is_arm_mapping_symbol (name); +} +/** * Find symbol based on relocation record info. * In some cases the symbol supplied is a valid symbol so @@ -1229,6 +1253,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,continue ;if (ELF_ST_TYPE (sym->st_info) ==STT_SECTION )continue ; +if (!is_valid_name (elf, sym)) +continue ;if (sym->st_value == addr)return sym;/* Find a symbol nearby - addr are maybe negative */ @@ -1247,30 +1273,6 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,return NULL ; } -static inline int is_arm_mapping_symbol (const char *str) -{ -return str[0 ] =='$' &&strchr ("axtd" , str[1 ]) - && (str[2 ] =='\0' || str[2 ] =='.' ); -} - -/* -* If there's no name there, ignore it; likewise, ignore it if it's -* one of the magic symbols emitted used by current ARM tools. -* -* Otherwise if find_symbols_between() returns those symbols, they'll -* fail the whitelist tests and cause lots of false alarms ... fixable -* only by merging __exit and __init sections into __text, bloating -* the kernel (which is especially evil on embedded platforms). -*/ -static inline int is_valid_name (struct elf_info *elf,Elf_Sym *sym) -{ -const char *name = elf->strtab + sym->st_name; - -if (!name || !strlen (name)) -return 0 ; -return !is_arm_mapping_symbol (name); -} -/* * Find symbols before or equal addr and after addr - in the section sec. * If we find two symbols with equal offset prefer one with a valid name. -- 2.19.1.568.g152ad8e336-goog
Signature · 2 lines
Best Regards Masahiro Yamada