2021-10-24 06:48:09

by Rob Landley

[permalink] [raw]
Subject: Commit 0d989ac2c90b broke my x86-64 build.

The attached config built fine before the above commit, doesn't build after. The
commit in question did nothing except remove support for building x86-64 without
libelf.

It took me a while to notice because the commit ONLY broke x86-64. I can still
build arm (32 and 64 bit), i686, m68k, mips/mipsel, powerpc, s390x, and sh4
without libelf in my cross compiler. Heck, I can still build i686. The change
seems to have added a unique build dependency to just x86-64.

Rob

P.S. Why do you need a special library to parse elf anyway? It's a fairly simple
file format, linux has include/linux.elf.h, the toolchain already has an objtool
prefixed for the appropriate cross compiler...


Attachments:
linux-fullconfig (54.72 kB)

2021-10-24 18:33:46

by Masahiro Yamada

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Sun, Oct 24, 2021 at 3:36 PM Rob Landley <[email protected]> wrote:
>
> The attached config built fine before the above commit, doesn't build after. The
> commit in question did nothing except remove support for building x86-64 without
> libelf.

You enable CONFIG_STACK_VALIDATION in your .config file.
At least, you observed
"warning: Cannot use CONFIG_STACK_VALIDATION=y, please install
libelf-dev, libelf-devel or elfutils-libelf-devel"
in the previous builds.


>
> It took me a while to notice because the commit ONLY broke x86-64. I can still
> build arm (32 and 64 bit), i686, m68k, mips/mipsel, powerpc, s390x, and sh4
> without libelf in my cross compiler. Heck, I can still build i686. The change
> seems to have added a unique build dependency to just x86-64.

The other architectures are not affected because you cannot enable
CONFIG_STACK_VALIDATION.

Please note only x86_64 selects HAVE_STACK_VALIDATION.


> Rob
>
> P.S. Why do you need a special library to parse elf anyway? It's a fairly simple
> file format, linux has include/linux.elf.h, the toolchain already has an objtool
> prefixed for the appropriate cross compiler...

You are asking a question about the objtool implementation.
CCed Josh Poimboeuf.


--
Best Regards
Masahiro Yamada

2021-10-24 20:19:45

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Mon, Oct 25, 2021 at 03:13:40AM +0900, Masahiro Yamada wrote:
> On Sun, Oct 24, 2021 at 3:36 PM Rob Landley <[email protected]> wrote:
> >
> > The attached config built fine before the above commit, doesn't build after. The
> > commit in question did nothing except remove support for building x86-64 without
> > libelf.
>
> You enable CONFIG_STACK_VALIDATION in your .config file.
> At least, you observed
> "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install
> libelf-dev, libelf-devel or elfutils-libelf-devel"
> in the previous builds.

Unfortunately I think CONFIG_STACK_VALIDATION is no longer optional on
x86-64 these days, because of static calls and retpolines. But it
should be possible to extricate them if that's a problem.

> > It took me a while to notice because the commit ONLY broke x86-64. I can still
> > build arm (32 and 64 bit), i686, m68k, mips/mipsel, powerpc, s390x, and sh4
> > without libelf in my cross compiler. Heck, I can still build i686. The change
> > seems to have added a unique build dependency to just x86-64.
>
> The other architectures are not affected because you cannot enable
> CONFIG_STACK_VALIDATION.
>
> Please note only x86_64 selects HAVE_STACK_VALIDATION.
>
>
> > Rob
> >
> > P.S. Why do you need a special library to parse elf anyway? It's a fairly simple
> > file format, linux has include/linux.elf.h, the toolchain already has an objtool
> > prefixed for the appropriate cross compiler...

We didn't see the need to reinvent the wheel, and some of the ELF corner
cases are tricky.

Objtool heavily relies on libelf for both reading and writing. The
kernel needs objtool to be robust. Libelf has been solid.

--
Josh

2021-10-25 03:00:44

by Rob Landley

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On 10/24/21 2:27 PM, Josh Poimboeuf wrote:
> On Mon, Oct 25, 2021 at 03:13:40AM +0900, Masahiro Yamada wrote:
>> On Sun, Oct 24, 2021 at 3:36 PM Rob Landley <[email protected]> wrote:
>> >
>> > The attached config built fine before the above commit, doesn't build after. The
>> > commit in question did nothing except remove support for building x86-64 without
>> > libelf.
>>
>> You enable CONFIG_STACK_VALIDATION in your .config file.

When I first noticed this dependency in 2018 it was because the ORC unwinder
selected it, which is why I selected UNWINDER_FRAME_POINTER to avoid that
dependency.

>> At least, you observed
>> "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install
>> libelf-dev, libelf-devel or elfutils-libelf-devel"
>> in the previous builds.

I turned off CONFIG_STACK_VALIDATION=y because I didn't want the dependency. It
appears to have crept back in since.

> Unfortunately I think CONFIG_STACK_VALIDATION is no longer optional on
> x86-64 these days, because of static calls and retpolines.

Does it need stack validation, or just a frame unwinder?

> But it
> should be possible to extricate them if that's a problem.

Yes please. How would I go about that? (Is there something to grep for?)

This is to build a small kernel that runs dedicated code. It hasn't got selinux
or containers, and part of the goal is to have a minimal self-contained build
system which can be binary audited against Ken Thompson's "trusting trust" attack:

http://lists.landley.net/pipermail/toybox-landley.net/2020-July/011898.html

...and then bootstrap up to arbitrarily complexity using nothing but the audited
binaries built from known source with no external dependencies.

Last go-round I got the minimal system down to 7 packages (busybox, uclibc,
linux, make, bash, gcc, binutils), under natively rebuilt itself under itself,
and under which I built Linux From Scratch (and large chunks of BLFS).

I'm now working to get it down to 4 (toybox, musl, tinycc, linux) and this time
targeting an AOSP build under the result.

>> > It took me a while to notice because the commit ONLY broke x86-64. I can still
>> > build arm (32 and 64 bit), i686, m68k, mips/mipsel, powerpc, s390x, and sh4
>> > without libelf in my cross compiler. Heck, I can still build i686. The change
>> > seems to have added a unique build dependency to just x86-64.

FYI:

git clone https://github.com/landley/toybox
git clone https://github.com/richfelker/musl-cross-make
git clone https://github.com/torvalds/linux
cd musl-cross-make
../toybox/scripts/mcm-buildall.sh
cd ../toybox
ln -s ../musl-cross-make/ccc ccc
LINUX="$PWD"/../linux CROSS=allnonstop scripts/mkroot.sh

Assuming I haven't typoed anything and live repo tips don't have bug du jour,
that should build 21 cross toolchains (and 20 native: todo make armv7r work),
then attempt to build tiny bootable qemu systems for each target (I think 14
currently boot to a shell prompt, ala (cd root/sh4 && ./qemu-*.sh)

The mkroot.sh script that builds the systems is currently 254 lines of bash,
hopefully readable...

>> The other architectures are not affected because you cannot enable
>> CONFIG_STACK_VALIDATION.
>>
>> Please note only x86_64 selects HAVE_STACK_VALIDATION.

Indeed. I'd like to tweak the config so I can disable stack validation and thus
this dependency. It worked fine for me before the above commit, and a kernel
with the following quick hack just built and booted for me:

--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
- select HAVE_STACK_VALIDATION if X86_64
+ select HAVE_STACK_VALIDATION if X86_64 && !UNWINDER_FRAME_POINTER

The question is the right way to go about it. (New config symbol?)

Rob

2021-10-25 09:10:50

by Peter Zijlstra

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Sun, Oct 24, 2021 at 09:51:45PM -0500, Rob Landley wrote:
> > Unfortunately I think CONFIG_STACK_VALIDATION is no longer optional on
> > x86-64 these days, because of static calls and retpolines.
>
> Does it need stack validation, or just a frame unwinder?

static_calls rely on objtool to find all "call __SCT*" instructions and
write their location in a .static_call_sites section.

The having of static calls is not optional on x86_64, and I have zero
interest in trying to work out what not having static_call() does, or to
maintain that option.

We have too damn many daft configurations as is.

2021-10-25 15:03:21

by Peter Zijlstra

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Mon, Oct 25, 2021 at 07:46:56AM -0700, Josh Poimboeuf wrote:
> On Mon, Oct 25, 2021 at 11:04:33AM +0200, Peter Zijlstra wrote:
> > On Sun, Oct 24, 2021 at 09:51:45PM -0500, Rob Landley wrote:
> > > > Unfortunately I think CONFIG_STACK_VALIDATION is no longer optional on
> > > > x86-64 these days, because of static calls and retpolines.
> > >
> > > Does it need stack validation, or just a frame unwinder?
> >
> > static_calls rely on objtool to find all "call __SCT*" instructions and
> > write their location in a .static_call_sites section.
> >
> > The having of static calls is not optional on x86_64, and I have zero
> > interest in trying to work out what not having static_call() does, or to
> > maintain that option.
>
> What I meant was, make STATIC_CALL_INLINE optional. Then it would use
> out-of-line static calls which should just work, no?

Yeah, I suppose so... I think we're then missing a STACK_VALIDATION
dependency for KCOV. We rely on objtool to nop out those
__sanitizer_cov_* calls.

I had really hoped to just make objtool an unconditional part of x86_64.

2021-10-25 20:23:19

by Peter Zijlstra

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Mon, Oct 25, 2021 at 11:59:45AM -0700, Josh Poimboeuf wrote:
> Plus it's a good idea to make the dependencies more explicit. We've
> already been looking at modularizing, like creating a new CONFIG_OBJTOOL
> option and splitting stack validation out from some of the other
> features. This could be a nice extension of that.
>
> Which reminds me, I'm still thinking we need to make the interface more
> easily combinable, like:
>
> objtool run \
> [--validate] \
> [--noinstr] \
> [--retpoline] \
> [--orc] \
> [--mcount] \
> [--static-call] \
> [--kcov] \
> [--frame-pointer] \
> [--vmlinux] \
> [--uaccess] \
> [--module] \
> [--no-unreachable] \
> [--backup] \
> [--stats] \
> [--backtrace]
>
> objtool dump \
> [--orc] \
> [--mcount] \
> [--static-call] \
> [--alternatives] \
> [--whatever]
>
> I can hopefully get to it one of these weeks...

Yes, that would be nice.

Also, unrelated, were you going to do that .fixup cleanup for x86_64 or
should I try and squeeze it in?

2021-10-25 21:23:05

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Mon, Oct 25, 2021 at 11:04:33AM +0200, Peter Zijlstra wrote:
> On Sun, Oct 24, 2021 at 09:51:45PM -0500, Rob Landley wrote:
> > > Unfortunately I think CONFIG_STACK_VALIDATION is no longer optional on
> > > x86-64 these days, because of static calls and retpolines.
> >
> > Does it need stack validation, or just a frame unwinder?
>
> static_calls rely on objtool to find all "call __SCT*" instructions and
> write their location in a .static_call_sites section.
>
> The having of static calls is not optional on x86_64, and I have zero
> interest in trying to work out what not having static_call() does, or to
> maintain that option.

What I meant was, make STATIC_CALL_INLINE optional. Then it would use
out-of-line static calls which should just work, no?

--
Josh

2021-10-25 21:40:41

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Mon, Oct 25, 2021 at 04:56:37PM +0200, Peter Zijlstra wrote:
> On Mon, Oct 25, 2021 at 07:46:56AM -0700, Josh Poimboeuf wrote:
> > On Mon, Oct 25, 2021 at 11:04:33AM +0200, Peter Zijlstra wrote:
> > > On Sun, Oct 24, 2021 at 09:51:45PM -0500, Rob Landley wrote:
> > > > > Unfortunately I think CONFIG_STACK_VALIDATION is no longer optional on
> > > > > x86-64 these days, because of static calls and retpolines.
> > > >
> > > > Does it need stack validation, or just a frame unwinder?
> > >
> > > static_calls rely on objtool to find all "call __SCT*" instructions and
> > > write their location in a .static_call_sites section.
> > >
> > > The having of static calls is not optional on x86_64, and I have zero
> > > interest in trying to work out what not having static_call() does, or to
> > > maintain that option.
> >
> > What I meant was, make STATIC_CALL_INLINE optional. Then it would use
> > out-of-line static calls which should just work, no?
>
> Yeah, I suppose so... I think we're then missing a STACK_VALIDATION
> dependency for KCOV. We rely on objtool to nop out those
> __sanitizer_cov_* calls.
>
> I had really hoped to just make objtool an unconditional part of x86_64.

I was hoping the opposite ;-) Not everybody wants the extra build
overhead, object size, complexity, warnings, etc. And it should be
pretty easy to make it optional anyway.

Plus it's a good idea to make the dependencies more explicit. We've
already been looking at modularizing, like creating a new CONFIG_OBJTOOL
option and splitting stack validation out from some of the other
features. This could be a nice extension of that.

Which reminds me, I'm still thinking we need to make the interface more
easily combinable, like:

objtool run \
[--validate] \
[--noinstr] \
[--retpoline] \
[--orc] \
[--mcount] \
[--static-call] \
[--kcov] \
[--frame-pointer] \
[--vmlinux] \
[--uaccess] \
[--module] \
[--no-unreachable] \
[--backup] \
[--stats] \
[--backtrace]

objtool dump \
[--orc] \
[--mcount] \
[--static-call] \
[--alternatives] \
[--whatever]

I can hopefully get to it one of these weeks...

--
Josh

2021-10-26 06:56:22

by Josh Poimboeuf

[permalink] [raw]
Subject: Re: Commit 0d989ac2c90b broke my x86-64 build.

On Mon, Oct 25, 2021 at 10:01:01PM +0200, Peter Zijlstra wrote:
> Also, unrelated, were you going to do that .fixup cleanup for x86_64 or
> should I try and squeeze it in?

If you have time in the next week or so, go ahead. I'm planning to
(mostly) disappear for a week starting on Wednesday.

--
Josh