2020-08-17 23:13:27

by Nick Desaulniers

[permalink] [raw]
Subject: [PATCH 4/4] x86: don't build CONFIG_X86_32 as -ffreestanding

-ffreestanding typically inhibits "libcall optimizations" where calls to
certain library functions can be replaced by the compiler in certain
cases to calls to other library functions that may be more efficient.
This can be problematic for embedded targets that don't provide full
libc implementations.

-ffreestanding inhibits all such optimizations, which is the safe
choice, but generally we want the optimizations that are performed. The
Linux kernel does implement a fair amount of libc routines. Instead of
-ffreestanding (which makes more sense in smaller images like kexec's
purgatory image), prefer -fno-builtin-* flags to disable the compiler
from emitting calls to functions which may not be defined.

If you see a linkage failure due to a missing symbol that's typically
defined in a libc, and not explicitly called from the source code, then
the compiler may have done such a transform. You can either implement
such a function (ie. in lib/string.c) or disable the transform outright
via -fno-builtin-* flag (where * is the name of the library routine, ie.
-fno-builtin-bcmp).

i386_defconfig build+boot tested with GCC and Clang. Removes a pretty
old TODO from the codebase.

Fixes: 6edfba1b33c7 ("x86_64: Don't define string functions to builtin")
Suggested-by: Arvind Sankar <[email protected]>
Signed-off-by: Nick Desaulniers <[email protected]>
---
arch/x86/Makefile | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 4346ffb2e39f..2383a96cf4fd 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -80,9 +80,6 @@ ifeq ($(CONFIG_X86_32),y)
# CPU-specific tuning. Anything which can be shared with UML should go here.
include arch/x86/Makefile_32.cpu
KBUILD_CFLAGS += $(cflags-y)
-
- # temporary until string.h is fixed
- KBUILD_CFLAGS += -ffreestanding
else
BITS := 64
UTS_MACHINE := x86_64
--
2.28.0.220.ged08abb693-goog


2020-08-18 19:27:29

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH 4/4] x86: don't build CONFIG_X86_32 as -ffreestanding

On Mon, Aug 17, 2020 at 03:02:12PM -0700, Nick Desaulniers wrote:
> -ffreestanding typically inhibits "libcall optimizations" where calls to
> certain library functions can be replaced by the compiler in certain
> cases to calls to other library functions that may be more efficient.
> This can be problematic for embedded targets that don't provide full
> libc implementations.
>
> -ffreestanding inhibits all such optimizations, which is the safe
> choice, but generally we want the optimizations that are performed. The
> Linux kernel does implement a fair amount of libc routines. Instead of
> -ffreestanding (which makes more sense in smaller images like kexec's
> purgatory image), prefer -fno-builtin-* flags to disable the compiler
> from emitting calls to functions which may not be defined.
>
> If you see a linkage failure due to a missing symbol that's typically
> defined in a libc, and not explicitly called from the source code, then
> the compiler may have done such a transform. You can either implement
> such a function (ie. in lib/string.c) or disable the transform outright
> via -fno-builtin-* flag (where * is the name of the library routine, ie.
> -fno-builtin-bcmp).
>
> i386_defconfig build+boot tested with GCC and Clang. Removes a pretty
> old TODO from the codebase.
>
> Fixes: 6edfba1b33c7 ("x86_64: Don't define string functions to builtin")
> Suggested-by: Arvind Sankar <[email protected]>
> Signed-off-by: Nick Desaulniers <[email protected]>

Reviewed-by: Kees Cook <[email protected]>

--
Kees Cook

2021-01-07 00:30:21

by Fangrui Song

[permalink] [raw]
Subject: Re: [PATCH 4/4] x86: don't build CONFIG_X86_32 as -ffreestanding

On 2020-08-17, Nick Desaulniers wrote:
>-ffreestanding typically inhibits "libcall optimizations" where calls to
>certain library functions can be replaced by the compiler in certain
>cases to calls to other library functions that may be more efficient.
>This can be problematic for embedded targets that don't provide full
>libc implementations.
>
>-ffreestanding inhibits all such optimizations, which is the safe
>choice, but generally we want the optimizations that are performed. The
>Linux kernel does implement a fair amount of libc routines. Instead of
>-ffreestanding (which makes more sense in smaller images like kexec's
>purgatory image), prefer -fno-builtin-* flags to disable the compiler
>from emitting calls to functions which may not be defined.
>
>If you see a linkage failure due to a missing symbol that's typically
>defined in a libc, and not explicitly called from the source code, then
>the compiler may have done such a transform. You can either implement
>such a function (ie. in lib/string.c) or disable the transform outright
>via -fno-builtin-* flag (where * is the name of the library routine, ie.
>-fno-builtin-bcmp).
>
>i386_defconfig build+boot tested with GCC and Clang. Removes a pretty
>old TODO from the codebase.
>
>Fixes: 6edfba1b33c7 ("x86_64: Don't define string functions to builtin")
>Suggested-by: Arvind Sankar <[email protected]>
>Signed-off-by: Nick Desaulniers <[email protected]>
>Reviewed-by: Kees Cook <[email protected]>
>---
> arch/x86/Makefile | 3 ---
> 1 file changed, 3 deletions(-)
>
>diff --git a/arch/x86/Makefile b/arch/x86/Makefile
>index 4346ffb2e39f..2383a96cf4fd 100644
>--- a/arch/x86/Makefile
>+++ b/arch/x86/Makefile
>@@ -80,9 +80,6 @@ ifeq ($(CONFIG_X86_32),y)
> # CPU-specific tuning. Anything which can be shared with UML should go here.
> include arch/x86/Makefile_32.cpu
> KBUILD_CFLAGS += $(cflags-y)
>-
>- # temporary until string.h is fixed
>- KBUILD_CFLAGS += -ffreestanding
> else
> BITS := 64
> UTS_MACHINE := x86_64
>--
>2.28.0.220.ged08abb693-goog

Reviewed-by: Fangrui Song <[email protected]>

But dropping -ffreestanding causes compiler produced declarations which
require
https://lore.kernel.org/lkml/[email protected]/
"x86: Treat R_386_PLT32 as R_386_PC32" as a prerequisite
to build with trunk Clang https://github.com/ClangBuiltLinux/linux/issues/1210

Since there have been more than 4 months, it seems that something else
regressed the non -ffreestanding build. Maybe another -fno-builtin-* is
needed somewhere.

Subject: [tip: x86/build] x86/build: Don't build CONFIG_X86_32 as -ffreestanding

The following commit has been merged into the x86/build branch of tip:

Commit-ID: 9b2687f29bc1a050ffd63b425129aa9db987e4f3
Gitweb: https://git.kernel.org/tip/9b2687f29bc1a050ffd63b425129aa9db987e4f3
Author: Nick Desaulniers <[email protected]>
AuthorDate: Thu, 03 Feb 2022 12:40:25 -08:00
Committer: Borislav Petkov <[email protected]>
CommitterDate: Thu, 07 Apr 2022 11:55:42 +02:00

x86/build: Don't build CONFIG_X86_32 as -ffreestanding

-ffreestanding typically inhibits "libcall optimizations" where calls to
certain library functions can be replaced by the compiler in certain
cases to calls to other library functions that may be more efficient.
This can be problematic for embedded targets that don't provide full
libc implementations.

-ffreestanding inhibits all such optimizations, which is the safe
choice, but generally we want the optimizations that are performed. The
Linux kernel does implement a fair amount of libc routines. Instead of
-ffreestanding (which makes more sense in smaller images like kexec's
purgatory image), prefer -fno-builtin-* flags to disable the compiler
from emitting calls to functions which may not be defined.

If you see a linkage failure due to a missing symbol that's typically
defined in a libc, and not explicitly called from the source code, then
the compiler may have done such a transform. You can either implement
such a function (i.e. in lib/string.c) or disable the transform outright
via -fno-builtin-* flag (where * is the name of the library routine,
i.e. -fno-builtin-bcmp).

i386_defconfig build+boot tested with GCC and Clang. Removes a pretty
old TODO from the code base.

[kees: These libcall optimizations are specifically needed to allow Clang
to correctly optimize the string functions under CONFIG_FORTIFY_SOURCE.]

Fixes: 6edfba1b33c7 ("[PATCH] x86_64: Don't define string functions to builtin")
Suggested-by: Arvind Sankar <[email protected]>
Signed-off-by: Nick Desaulniers <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Fangrui Song <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Link: https://lore.kernel.org/r/[email protected]
---
arch/x86/Makefile | 3 ---
1 file changed, 3 deletions(-)

diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 1abd7cc..670fe40 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -100,9 +100,6 @@ ifeq ($(CONFIG_X86_32),y)
include $(srctree)/arch/x86/Makefile_32.cpu
KBUILD_CFLAGS += $(cflags-y)

- # temporary until string.h is fixed
- KBUILD_CFLAGS += -ffreestanding
-
ifeq ($(CONFIG_STACKPROTECTOR),y)
ifeq ($(CONFIG_SMP),y)
KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard