From: Nicolas Schier <nicolas@fjasle.eu>
To: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Masahiro Yamada <masahiroy@kernel.org>,
linux-kbuild@vger.kernel.org,
Nathan Chancellor <nathan@kernel.org>,
Michael Ellerman <mpe@ellerman.id.au>,
Morten Linderud <morten@linderud.pw>,
Haelwenn Monnier <contact@lanodan.eu>,
Jann Horn <jannh@google.com>, Kees Cook <kees@kernel.org>,
James Bottomley <James.Bottomley@hansenpartnership.com>,
Theodore Ts'o <tytso@mit.edu>,
linux-hardening@vger.kernel.org
Subject: Re: [RFC PATCH 00/11] output a valid shell script when running 'make -n'
Date: Sat, 2 Nov 2024 22:07:09 +0100 [thread overview]
Message-ID: <ZyaUfcPt3OHztjc_@fjasle.eu> (raw)
In-Reply-To: <20240819160309.2218114-1-vegard.nossum@oracle.com>
[-- Attachment #1: Type: text/plain, Size: 5686 bytes --]
On Mon, Aug 19, 2024 at 06:02:57PM +0200 Vegard Nossum wrote:
> This patch series lets 'make -n' output a shell script that can be
> used to build the kernel without any further use of make. For example:
>
> make defconfig
>
> # ensure some build prerequisites are built
> make prepare
>
> # generate build script
> make -n | tee build.sh
>
> # excecute build script
> bash -eux build.sh
>
> The purpose of this is to take a step towards defeating the insertion of
> backdoors at build time (see [1]). Some of the benefits of separating the
> build script from the build system are:
>
> - we can invoke make in a restricted environment (e.g. mostly read-only
> kernel tree),
>
> - we have an audit log of the exact commands that run during the build
> process; although it's true that the build script wouldn't be useful
> for either production or development builds (as it doesn't support
> incremental rebuilds or parallel builds), it would allow you to
> rebuild an existing kernel and compare the resulting binary for
> discrepancies to the original build,
>
> - the audit log can be stored (e.g. in git) and changes to it over time
> can themselves be audited (e.g. by looking at diffs),
>
> - there's a lot fewer places to hide malicious code in a straight-line
> shell script that makes minimal use of variables and helper functions.
> You also cannot inject fragments of Makefile code through environment
> variables (again, see [1]).
>
> Alternative ways to achieve some of the same things would be:
>
> - the existing compile_commands.json infrastructure; unfortunately this
> does not include most of the steps performed during a build (such as
> linking vmlinux) and does not really allow you to reproduce/verify the
> full build,
>
> - simply running something like strace -f -e trace=execve make; however,
> this also does not result in something that can be easily played back;
> at the very least it would need to be heavily filtered and processed
> to account for data passed in environment variables and things like
> temporary files used by the compiler.
>
> This implementation works as follows:
>
> - 'make -n' (AKA --dry-run) by default prints out the commands that make
> runs; this output is modified to be usable as a shell script,
>
> - we output 'make() { :; }' at the start of the script in order to make
> all 'make' invocations in the resulting build script no-ops (GNU Make
> will actually execute -- and print -- all recipe lines that include
> $(MAKE), even when invoked with -n).
>
> - we simplify the makefile rules in some cases to make the shell script
> more readable; for example, we don't need the logic that extracts
> dependencies from .c files (since that is only used by 'make' itself
> when determining what to rebuild) or the logic that generates .cmd
> files,
>
> This patch is WIP and may not produce a working shell script in all
> circumstances. For example, while plain 'make -n' works for me, other
> make targets (e.g. 'make -n htmldocs') are not at all guaranteed to
> produce meaningful output; certain kernel configs may also not work,
> especially those that rely on external tools like e.g. Rust.
Thanks for this patch set and all the thoughts laid out here in detail,
especially for the write-up in [1], too!
I think it is a good idea to work towards hardening the build system against
known and difficult to spot attacks. As the patch set integration needs a
complete 'make -n' script (at least for a "simple", defined config) to be
successful, I expect that it might become quite some work and patience, but I
think it is a meaningful goal.
In order to prevent "degradation" of Make rules after a possible integration,
we need some (automated) testers, otherwise we will loose all the efforts again.
Please give me yet some days for a first rough round through the patches.
Kind regards
Nicolas
>
> [1]: https://www.openwall.com/lists/oss-security/2024/04/17/3
> [2]: https://www.gnu.org/software/make/manual/make.html#Testing-Flags
>
>
> Vegard
>
> ---
>
> Vegard Nossum (11):
> kbuild: ignore .config rule for make --always-make
> kbuild: document some prerequisites
> kbuild: pass KERNELVERSION and LOCALVERSION explicitly to
> setlocalversion
> kbuild: don't execute .ko recipe in --dry-run mode
> kbuild: execute modules.order recipe in --dry-run mode
> kbuild: set $dry_run when running in --dry-run mode
> kbuild: define 'make' as a no-op in --dry-run mode
> kbuild: make link-vmlinux.sh respect $dry_run
> kbuild: simplify commands in --dry-run mode
> kbuild: don't test for file presence in --dry-run mode
> kbuild: suppress echoing of commands in --dry-run mode
>
> Makefile | 28 +++++++++++++++++---
> arch/x86/boot/compressed/Makefile | 6 +++++
> scripts/Kbuild.include | 27 +++++++++++++++++++
> scripts/Makefile.build | 2 +-
> scripts/Makefile.modfinal | 9 +++++--
> scripts/Makefile.modpost | 8 ++++--
> scripts/Makefile.vmlinux | 22 ++++++++++++++--
> scripts/Makefile.vmlinux_o | 3 +++
> scripts/link-vmlinux.sh | 44 ++++++++++++++++++++-----------
> 9 files changed, 123 insertions(+), 26 deletions(-)
>
> --
> 2.34.1
>
--
epost|xmpp: nicolas@fjasle.eu irc://oftc.net/nsc
↳ gpg: 18ed 52db e34f 860e e9fb c82b 7d97 0932 55a0 ce7f
-- frykten for herren er opphav til kunnskap --
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
prev parent reply other threads:[~2024-11-02 21:08 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-19 16:02 [RFC PATCH 00/11] output a valid shell script when running 'make -n' Vegard Nossum
2024-08-19 16:02 ` [RFC PATCH 01/11] kbuild: ignore .config rule for make --always-make Vegard Nossum
2024-11-02 21:07 ` Nicolas Schier
2024-11-02 21:39 ` Miguel Ojeda
2024-11-03 11:15 ` Nicolas Schier
2024-08-19 16:02 ` [RFC PATCH 02/11] kbuild: document some prerequisites Vegard Nossum
2024-11-02 21:07 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 03/11] kbuild: pass KERNELVERSION and LOCALVERSION explicitly to setlocalversion Vegard Nossum
2024-11-02 21:07 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 04/11] kbuild: don't execute .ko recipe in --dry-run mode Vegard Nossum
2024-11-02 21:08 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 05/11] kbuild: execute modules.order " Vegard Nossum
2024-11-02 21:10 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 06/11] kbuild: set $dry_run when running " Vegard Nossum
2024-11-02 21:11 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 07/11] kbuild: define 'make' as a no-op " Vegard Nossum
2024-11-14 10:47 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 08/11] kbuild: make link-vmlinux.sh respect $dry_run Vegard Nossum
2024-11-14 10:47 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 09/11] kbuild: simplify commands in --dry-run mode Vegard Nossum
2024-11-14 10:48 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 10/11] kbuild: don't test for file presence " Vegard Nossum
2024-11-14 10:48 ` Nicolas Schier
2024-08-19 16:03 ` [RFC PATCH 11/11] kbuild: suppress echoing of commands " Vegard Nossum
2024-11-14 10:49 ` Nicolas Schier
2024-09-25 9:27 ` [RFC PATCH 00/11] output a valid shell script when running 'make -n' Vegard Nossum
2024-11-02 21:07 ` Nicolas Schier [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZyaUfcPt3OHztjc_@fjasle.eu \
--to=nicolas@fjasle.eu \
--cc=James.Bottomley@hansenpartnership.com \
--cc=contact@lanodan.eu \
--cc=jannh@google.com \
--cc=kees@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=masahiroy@kernel.org \
--cc=morten@linderud.pw \
--cc=mpe@ellerman.id.au \
--cc=nathan@kernel.org \
--cc=tytso@mit.edu \
--cc=vegard.nossum@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox