Re: [PATCH v2] module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols

2021-01-15 Thread Fāng-ruì Sòng
On Thu, Jan 14, 2021 at 11:04 PM Marco Elver  wrote:
>
> On Thu, 14 Jan 2021 at 22:54, Fangrui Song  wrote:
> > clang-12 -fno-pic (since
> > https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008232da3f1d6)
> > can emit `call __stack_chk_fail@PLT` instead of `call __stack_chk_fail`
> > on x86.  The two forms should have identical behaviors on x86-64 but the
> > former causes GNU as<2.37 to produce an unreferenced undefined symbol
> > _GLOBAL_OFFSET_TABLE_.
> >
> > (On x86-32, there is an R_386_PC32 vs R_386_PLT32 difference but the
> > linker behavior is identical as far as Linux kernel is concerned.)
> >
> > Simply ignore _GLOBAL_OFFSET_TABLE_ for now, like what
> > scripts/mod/modpost.c:ignore_undef_symbol does. This also fixes the
> > problem for gcc/clang -fpie and -fpic, which may emit `call foo@PLT` for
> > external function calls on x86.
> >
> > Note: ld -z defs and dynamic loaders do not error for unreferenced
> > undefined symbols so the module loader is reading too much.  If we ever
> > need to ignore more symbols, the code should be refactored to ignore
> > unreferenced symbols.
> >
> > Reported-by: Marco Elver 
> > Link: https://github.com/ClangBuiltLinux/linux/issues/1250
> > Signed-off-by: Fangrui Song 
>
> Tested-by: Marco Elver 
>
> Thank you for the patch!
>
> > ---
> >  kernel/module.c | 20 ++--
> >  1 file changed, 18 insertions(+), 2 deletions(-)
> > ---
> > Changes in v2:
> > * Fix Marco's email address
> > * Add a function ignore_undef_symbol similar to 
> > scripts/mod/modpost.c:ignore_undef_symbol
> >
> > diff --git a/kernel/module.c b/kernel/module.c
> > index 4bf30e4b3eaa..278f5129bde2 100644
> > --- a/kernel/module.c
> > +++ b/kernel/module.c
> > @@ -2348,6 +2348,20 @@ static int verify_exported_symbols(struct module 
> > *mod)
> > return 0;
> >  }
> >
> > +static int ignore_undef_symbol(Elf_Half emachine, const char *name)
>
> Why not 'bool' return-type?

Will use bool and false in v3.

> > +{
> > +   /* On x86, PIC code and Clang non-PIC code may have call foo@PLT. 
> > GNU as
>
> Not sure if checkpatch.pl warns about this, but this multi-line
> comment does not follow the normal kernel-style (see elsewhere in
> file):

It doesn't warn about this. (The commit description warning cannot be
fixed, even if I place the closing paren on the next line.)

% ./scripts/checkpatch.pl
v2-0001-module-Ignore-_GLOBAL_OFFSET_TABLE_-when-warning-.patch
WARNING: Possible unwrapped commit description (prefer a maximum 75
chars per line)
#8:
https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008232da3f1d6)

total: 0 errors, 1 warnings, 32 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
  mechanically convert to the typical style using --fix or --fix-inplace.

v2-0001-module-Ignore-_GLOBAL_OFFSET_TABLE_-when-warning-.patch has
style problems, please review.

NOTE: If any of the errors are false positives, please report
  them to the maintainer, see CHECKPATCH in MAINTAINERS.

> /*
>  * ...
>  */
>
> > +* before 2.37 produces an unreferenced _GLOBAL_OFFSET_TABLE_ on 
> > x86-64.
> > +* i386 has a similar problem but may not deserve a fix.
> > +*
> > +* If we ever have to ignore many symbols, consider refactoring the 
> > code to
> > +* only warn if referenced by a relocation.
> > +*/
> > +   if (emachine == EM_386 || emachine == EM_X86_64)
> > +   return !strcmp(name, "_GLOBAL_OFFSET_TABLE_");
> > +   return 0;
> > +}
> > +
> >  /* Change all symbols so that st_value encodes the pointer directly. */
> >  static int simplify_symbols(struct module *mod, const struct load_info 
> > *info)
> >  {
> > @@ -2395,8 +2409,10 @@ static int simplify_symbols(struct module *mod, 
> > const struct load_info *info)
> > break;
> > }
> >
> > -   /* Ok if weak.  */
> > -   if (!ksym && ELF_ST_BIND(sym[i].st_info) == 
> > STB_WEAK)
> > +   /* Ok if weak or ignored.  */
> > +   if (!ksym &&
> > +   (ELF_ST_BIND(sym[i].st_info) == STB_WEAK ||
> > +ignore_undef_symbol(info->hdr->e_machine, 
> > name)))
> > break;
> >
> > ret = PTR_ERR(ksym) ?: -ENOENT;
> > --
> > 2.30.0.296.g2bfb1c46d8-goog
> >



-- 
宋方睿


Re: [PATCH v2] module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols

2021-01-15 Thread Jessica Yu

+++ Marco Elver [15/01/21 08:03 +0100]:

On Thu, 14 Jan 2021 at 22:54, Fangrui Song  wrote:

clang-12 -fno-pic (since
https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008232da3f1d6)
can emit `call __stack_chk_fail@PLT` instead of `call __stack_chk_fail`
on x86.  The two forms should have identical behaviors on x86-64 but the
former causes GNU as<2.37 to produce an unreferenced undefined symbol
_GLOBAL_OFFSET_TABLE_.

(On x86-32, there is an R_386_PC32 vs R_386_PLT32 difference but the
linker behavior is identical as far as Linux kernel is concerned.)

Simply ignore _GLOBAL_OFFSET_TABLE_ for now, like what
scripts/mod/modpost.c:ignore_undef_symbol does. This also fixes the
problem for gcc/clang -fpie and -fpic, which may emit `call foo@PLT` for
external function calls on x86.

Note: ld -z defs and dynamic loaders do not error for unreferenced
undefined symbols so the module loader is reading too much.  If we ever
need to ignore more symbols, the code should be refactored to ignore
unreferenced symbols.

Reported-by: Marco Elver 
Link: https://github.com/ClangBuiltLinux/linux/issues/1250
Signed-off-by: Fangrui Song 


Tested-by: Marco Elver 

Thank you for the patch!


---
 kernel/module.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)
---
Changes in v2:
* Fix Marco's email address
* Add a function ignore_undef_symbol similar to 
scripts/mod/modpost.c:ignore_undef_symbol

diff --git a/kernel/module.c b/kernel/module.c
index 4bf30e4b3eaa..278f5129bde2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2348,6 +2348,20 @@ static int verify_exported_symbols(struct module *mod)
return 0;
 }

+static int ignore_undef_symbol(Elf_Half emachine, const char *name)


Why not 'bool' return-type?


+{
+   /* On x86, PIC code and Clang non-PIC code may have call foo@PLT. GNU as


Not sure if checkpatch.pl warns about this, but this multi-line
comment does not follow the normal kernel-style (see elsewhere in
file):

/*
* ...
*/


+1 to Marco's comments. Otherwise, patch looks good to me.

Thanks Fangrui!

Jessica



Re: [PATCH v2] module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols

2021-01-15 Thread Jessica Yu

+++ Nick Desaulniers [14/01/21 14:01 -0800]:

On Thu, Jan 14, 2021 at 1:54 PM 'Fangrui Song' via Clang Built Linux
 wrote:


clang-12 -fno-pic (since
https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008232da3f1d6)
can emit `call __stack_chk_fail@PLT` instead of `call __stack_chk_fail`
on x86.  The two forms should have identical behaviors on x86-64 but the
former causes GNU as<2.37 to produce an unreferenced undefined symbol
_GLOBAL_OFFSET_TABLE_.

(On x86-32, there is an R_386_PC32 vs R_386_PLT32 difference but the
linker behavior is identical as far as Linux kernel is concerned.)

Simply ignore _GLOBAL_OFFSET_TABLE_ for now, like what
scripts/mod/modpost.c:ignore_undef_symbol does. This also fixes the
problem for gcc/clang -fpie and -fpic, which may emit `call foo@PLT` for
external function calls on x86.

Note: ld -z defs and dynamic loaders do not error for unreferenced
undefined symbols so the module loader is reading too much.  If we ever
need to ignore more symbols, the code should be refactored to ignore
unreferenced symbols.

Reported-by: Marco Elver 
Link: https://github.com/ClangBuiltLinux/linux/issues/1250
Signed-off-by: Fangrui Song 


Thanks for the patch.

Reviewed-by: Nick Desaulniers 

Jessica, would you mind adding when applying:

Cc: 

as I suspect we might want this fixed in stable tree's branches, too.
It might of interest to add:

Link: https://sourceware.org/bugzilla/show_bug.cgi?id=27178

too.


Sure, will do!

Thanks,

Jessica



Re: [PATCH v2] module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols

2021-01-14 Thread Marco Elver
On Thu, 14 Jan 2021 at 22:54, Fangrui Song  wrote:
> clang-12 -fno-pic (since
> https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008232da3f1d6)
> can emit `call __stack_chk_fail@PLT` instead of `call __stack_chk_fail`
> on x86.  The two forms should have identical behaviors on x86-64 but the
> former causes GNU as<2.37 to produce an unreferenced undefined symbol
> _GLOBAL_OFFSET_TABLE_.
>
> (On x86-32, there is an R_386_PC32 vs R_386_PLT32 difference but the
> linker behavior is identical as far as Linux kernel is concerned.)
>
> Simply ignore _GLOBAL_OFFSET_TABLE_ for now, like what
> scripts/mod/modpost.c:ignore_undef_symbol does. This also fixes the
> problem for gcc/clang -fpie and -fpic, which may emit `call foo@PLT` for
> external function calls on x86.
>
> Note: ld -z defs and dynamic loaders do not error for unreferenced
> undefined symbols so the module loader is reading too much.  If we ever
> need to ignore more symbols, the code should be refactored to ignore
> unreferenced symbols.
>
> Reported-by: Marco Elver 
> Link: https://github.com/ClangBuiltLinux/linux/issues/1250
> Signed-off-by: Fangrui Song 

Tested-by: Marco Elver 

Thank you for the patch!

> ---
>  kernel/module.c | 20 ++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> ---
> Changes in v2:
> * Fix Marco's email address
> * Add a function ignore_undef_symbol similar to 
> scripts/mod/modpost.c:ignore_undef_symbol
>
> diff --git a/kernel/module.c b/kernel/module.c
> index 4bf30e4b3eaa..278f5129bde2 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2348,6 +2348,20 @@ static int verify_exported_symbols(struct module *mod)
> return 0;
>  }
>
> +static int ignore_undef_symbol(Elf_Half emachine, const char *name)

Why not 'bool' return-type?

> +{
> +   /* On x86, PIC code and Clang non-PIC code may have call foo@PLT. GNU 
> as

Not sure if checkpatch.pl warns about this, but this multi-line
comment does not follow the normal kernel-style (see elsewhere in
file):

/*
 * ...
 */

> +* before 2.37 produces an unreferenced _GLOBAL_OFFSET_TABLE_ on 
> x86-64.
> +* i386 has a similar problem but may not deserve a fix.
> +*
> +* If we ever have to ignore many symbols, consider refactoring the 
> code to
> +* only warn if referenced by a relocation.
> +*/
> +   if (emachine == EM_386 || emachine == EM_X86_64)
> +   return !strcmp(name, "_GLOBAL_OFFSET_TABLE_");
> +   return 0;
> +}
> +
>  /* Change all symbols so that st_value encodes the pointer directly. */
>  static int simplify_symbols(struct module *mod, const struct load_info *info)
>  {
> @@ -2395,8 +2409,10 @@ static int simplify_symbols(struct module *mod, const 
> struct load_info *info)
> break;
> }
>
> -   /* Ok if weak.  */
> -   if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
> +   /* Ok if weak or ignored.  */
> +   if (!ksym &&
> +   (ELF_ST_BIND(sym[i].st_info) == STB_WEAK ||
> +ignore_undef_symbol(info->hdr->e_machine, name)))
> break;
>
> ret = PTR_ERR(ksym) ?: -ENOENT;
> --
> 2.30.0.296.g2bfb1c46d8-goog
>


Re: [PATCH v2] module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols

2021-01-14 Thread Nick Desaulniers
On Thu, Jan 14, 2021 at 1:54 PM 'Fangrui Song' via Clang Built Linux
 wrote:
>
> clang-12 -fno-pic (since
> https://github.com/llvm/llvm-project/commit/a084c0388e2a59b9556f2de008232da3f1d6)
> can emit `call __stack_chk_fail@PLT` instead of `call __stack_chk_fail`
> on x86.  The two forms should have identical behaviors on x86-64 but the
> former causes GNU as<2.37 to produce an unreferenced undefined symbol
> _GLOBAL_OFFSET_TABLE_.
>
> (On x86-32, there is an R_386_PC32 vs R_386_PLT32 difference but the
> linker behavior is identical as far as Linux kernel is concerned.)
>
> Simply ignore _GLOBAL_OFFSET_TABLE_ for now, like what
> scripts/mod/modpost.c:ignore_undef_symbol does. This also fixes the
> problem for gcc/clang -fpie and -fpic, which may emit `call foo@PLT` for
> external function calls on x86.
>
> Note: ld -z defs and dynamic loaders do not error for unreferenced
> undefined symbols so the module loader is reading too much.  If we ever
> need to ignore more symbols, the code should be refactored to ignore
> unreferenced symbols.
>
> Reported-by: Marco Elver 
> Link: https://github.com/ClangBuiltLinux/linux/issues/1250
> Signed-off-by: Fangrui Song 

Thanks for the patch.

Reviewed-by: Nick Desaulniers 

Jessica, would you mind adding when applying:

Cc: 

as I suspect we might want this fixed in stable tree's branches, too.
It might of interest to add:

Link: https://sourceware.org/bugzilla/show_bug.cgi?id=27178

too.

> ---
>  kernel/module.c | 20 ++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> ---
> Changes in v2:
> * Fix Marco's email address
> * Add a function ignore_undef_symbol similar to 
> scripts/mod/modpost.c:ignore_undef_symbol
>
> diff --git a/kernel/module.c b/kernel/module.c
> index 4bf30e4b3eaa..278f5129bde2 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2348,6 +2348,20 @@ static int verify_exported_symbols(struct module *mod)
> return 0;
>  }
>
> +static int ignore_undef_symbol(Elf_Half emachine, const char *name)
> +{
> +   /* On x86, PIC code and Clang non-PIC code may have call foo@PLT. GNU 
> as
> +* before 2.37 produces an unreferenced _GLOBAL_OFFSET_TABLE_ on 
> x86-64.
> +* i386 has a similar problem but may not deserve a fix.
> +*
> +* If we ever have to ignore many symbols, consider refactoring the 
> code to
> +* only warn if referenced by a relocation.
> +*/
> +   if (emachine == EM_386 || emachine == EM_X86_64)
> +   return !strcmp(name, "_GLOBAL_OFFSET_TABLE_");
> +   return 0;
> +}
> +
>  /* Change all symbols so that st_value encodes the pointer directly. */
>  static int simplify_symbols(struct module *mod, const struct load_info *info)
>  {
> @@ -2395,8 +2409,10 @@ static int simplify_symbols(struct module *mod, const 
> struct load_info *info)
> break;
> }
>
> -   /* Ok if weak.  */
> -   if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
> +   /* Ok if weak or ignored.  */
> +   if (!ksym &&
> +   (ELF_ST_BIND(sym[i].st_info) == STB_WEAK ||
> +ignore_undef_symbol(info->hdr->e_machine, name)))
> break;
>
> ret = PTR_ERR(ksym) ?: -ENOENT;
> --
-- 
Thanks,
~Nick Desaulniers