-
Notifications
You must be signed in to change notification settings - Fork 38.7k
build: Mark x86_64-linux-gnu release binaries as CET-enabled
#30685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
Concept NACK on the approach here (CI is showing why it wont work with depends, I assume it will also break other builds (where we haven't built the libs)). I'd rather build up from from something like #30438 (and have a branch with similar changes).
I don't think we should be making a change this invasive and deferring the addition of checks until later. |
|
🚧 At least one of the CI tasks failed. HintsMake sure to run all tests locally, according to the documentation. The failure may happen due to a number of reasons, for example:
Leave a comment here, if you need help tracking down a confusing failure. |
Is that branch publicly available? |
615b94c to
89f8e8e
Compare
|
depends/hosts/linux.mk
Outdated
| x86_64_linux_NM=nm | ||
| x86_64_linux_STRIP=strip | ||
|
|
||
| ifeq ($(NO_HARDEN),) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is the right place for these flags. If we want them in the Guix build, then we should add them to the Guix build, not hardcode them into depends.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate on how you think we should in general decide where configuration should live (default in configure/cmake vs depends vs guix)?
My thinking would be that depends builds are intended to be as close to production binaries as we can get them, but without having a deterministic build environment (so without controlling compiler or dependency versions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without controlling ... dependency versions
I might be misunderstanding you, but one of the main reasons depends exists is to control dependency versions? i.e as-opposed to using whatever ships with the system packages.
so without controlling compiler
This change is a good example of trying to add that control; i.e hardcoding compiler flags with no check for if they are actually supported/or work as expected.
Can you elaborate on how you think we should in general decide where configuration should live (default in configure/cmake vs depends vs guix)?
Sure! I'll follow up with something lengthier tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be misunderstanding you, but one of the main reasons depends exists is to control dependency versions? i.e as-opposed to using whatever ships with the system packages.
Err, yes, of course. I had compiler-infused dependencies like glibc in mind, but that's the exception rather than the rule.
This change is a good example of trying to add that control; i.e hardcoding compiler flags with no check for if they are actually supported/or work as expected.
Ah that makes sense. Your concern here is that this may not work (or not work as expected) on the full range of environments where we expect depends-builds to work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your concern here is that this may not work (or not work as expected) on the full range of environments where we expect depends-builds to work?
Yea. It's also somewhat displayed by the inconsistency of the change here; C/XXFLAGS is being put into depends, but the LDFLAGS are put into Guix. The LDFLAGS can't be hard-coded into depends, because that'll break depends builds where the libc/other base libs haven't been compiled with support for CET (for example, the current release of Alpine Linux on x86_64), or, any other builds where we use other libs compiled without such support, fuzzing, sanitizers etc.
Doing so would also add a requirement on the version of the linker, and possibly which ones
you can use. For any given flag, ld,lld, mold etc may/or may not implement it, and
will do so at various times (same holds for GCC vs Clang and compilation flags).
The C/CXXFLAGS addition might currently be ok (at least, nothing we test in CI is broken), and we know these flags are atleast "supported" by our minimum GCC and Clang, but now we're just playing whackamole with where things end up, and have got the inconsistency of spreading the flags for a certain feature across the two different systems, because after enough shuffling it now compiles and (hopefully) doesn't break anything.
Other concerns:
-
Generally, this approach of hardcoding specific flags for specific targets (while simeltaneous just assuming they'll work) doesn't scale well: i.e for other
x86_64targets where these compilation flags may be relevant; are we just copy-pasting the same blocks of flags around inside depends? That's messy. -
You've now got 3 different places to consider when thinking about hardening logic/flags and
their interactions (configure, depends, Guix), and, for anyone wanting to add new flags, it's even less
clear where they should live, or why.
Can you elaborate on how you think we should in general decide where configuration should live
(default in configure/CMake vs depends vs Guix)?
Ideally, depends should remain generic/assumption free, and then users (including us), can use their distro of choice (which, for example, may already have it's own hardened toolchain), or bring their own compiler /
flags, and things will pretty much always just "work". We can then try flags generically/best effort in configure/CMake, and anyone can always continue to override what we are doing.
In that sense, you can think of Guix as essentially Cores own distro, where we have full
control to choose the compiler, glibc, binutils etc, configure them exactly as (and as hardened as)
we want, and then use that to compile depends and Core, with whichever additional flags we prefer for release
builds (that have additional post-build checks and ideally some coverage in CI).
| esac | ||
|
|
||
| case "$HOST" in | ||
| x86_64-linux-gnu) HARDENED_LDFLAGS="-Wl,-z,cet-report=error" ;; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think splitting flags into LDFLAGS and HARDENED_LDFLAGS inside Guix makes sense, as, everything in Guix is meant to be a "hardened" build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done to prevent disruption of internal flag checks test-security-check.py.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What disruption?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
x86_64-linux-gnu-ld: /tmp/ccwqGS4u.o: error: missing IBT and SHSTK properties
collect2: error: ld returned 1 exit status
E
======================================================================
ERROR: test_ELF (__main__.TestSecurityChecks)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/distsrc-base/distsrc-5fda052191b0-x86_64-linux-gnu/./contrib/devtools/test-security-check.py", line 67, in test_ELF
self.assertEqual(call_security_check(cxx, source, executable, pass_flags + ['-fcf-protection=none']), (1, executable + ': failed CONTROL_FLOW'))
File "/distsrc-base/distsrc-5fda052191b0-x86_64-linux-gnu/./contrib/devtools/test-security-check.py", line 42, in call_security_check
subprocess.run([*cxx,source,'-o',executable] + env_flags() + options, check=True)
File "/gnu/store/fn4rrnx7vx1bl6mccrhm95y6br8yg9s6-python-minimal-3.10.7/lib/python3.10/subprocess.py", line 524, in run
raise CalledProcessError(retcode, process.args,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GIven that the whole point of these scripts is to sanity check the (release) tests, using the release flags, and in the Guix env; I don't think an undocumented workaround, of just hiding certain release flags, from the test scripts, is the right thing to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. What can you suggest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. What can you suggest?
My suggestion is to remove the changes that have been added to facilitate bypassing tests (i.e separating the LDFLAGS into LDFLAGS and HARDENED_LDFLAGS, so that some flags are skipped when tests are performed). If the build environment has changed such that the current set of tests don't pass with the new changes, then the tests should be reworked, not skipped.
|
Guix building 89f8e8e on time HOSTS="x86_64-linux-gnu" ./contrib/guix/guix-build
<snip>
CXXLD test/test_bitcoin
x86_64-linux-gnu-ld: /bitcoin/depends/x86_64-linux-gnu/lib/libevent.a(buffer.c.o): error: missing IBT and SHSTK properties
x86_64-linux-gnu-ld: /bitcoin/depends/x86_64-linux-gnu/lib/libevent.a(bufferevent.c.o): error: missing IBT and SHSTK properties
<snip>
x86_64-linux-gnu-ld: /bitcoin/depends/x86_64-linux-gnu/lib/libzmq.a(mechanism_base.cpp.o): error: missing IBT and SHSTK properties
collect2: error: ld returned 1 exit status |
89f8e8e to
c5bed74
Compare
|
The PR description has been updated with a runtime check example. |
The issue should be fixed now. |
|
🐙 This pull request conflicts with the target branch and needs rebase. |
|
What is the status of this? |
|
Apparently, I haven't had time to address feedback and rebase this PR recently. Perhaps it could be labelled "Up for grabs"? |
I'll cherry-pick / followup with this. |
4d3da08 guix: Enable CET for `glibc` package (Hennadii Stepanov) Pull request description: Pulled from #30685. This doesn't need to wait for anything. ACKs for top commit: laanwj: ACK 4d3da08 TheCharlatan: ACK 4d3da08 Tree-SHA512: 1f4645971381fd342adec52c826fc0023722519a3e28043c9fe8b64bbc1abad822fcc25a64f3f959e3f3a10f5c119029f4cae13c22bac6badcbec9ae8b501dfc
CET is Intel’s Control-flow Enforcement Technology.
The current GCC implementation of the
-fcf-protectionoption is based on CET forx86_64-linux-gnu.However, on the master branch @ d79ea80, the release binaries are not marked as CET-enabled:
This occurs because not all object files, including those from the depends and the
secp256k1subtree, have the required properties.This PR resolves the issue by explicitly enabling
-fcf-protection=fullfor all object files, which will be beneficial for all targets, not justx86_64-linux-gnu.With this PR:
Please note
Properties: x86 feature: IBT, SHSTK.A runtime check on Ubuntu 24.04 (GLIBC 2.39):
As a follow-up, a check for the
IBTandSHSTKcan be added to thecontrib/devtools/security-check.pyscript.Fixes #30677.