Skip to content
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

cmake: Add hardening, reduce exports, werror and install #32

Merged
merged 9 commits into from
Oct 29, 2023

Conversation

hebasto
Copy link
Owner

@hebasto hebasto commented Oct 17, 2023

New CMake variables that affect the build system configuration:

  • HARDENING
  • REDUCE_EXPORTS
  • WERROR

@hebasto
Copy link
Owner Author

hebasto commented Oct 17, 2023

CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
fanquake added a commit to bitcoin-core/gui that referenced this pull request Oct 19, 2023
…_CXXFLAGS

8cfa22a build: move -fstack-reuse=none to CORE_CXXFLAGS (fanquake)

Pull request description:

  This is not a hardening specific flag, it should be used at all times, regardless of if hardening is enabled or not. Note that this was still the case here, but having this exist in the hardening flags is confusing, and may lead someone to move it inside one of the `use_hardening` blocks, where it would become unused, with `--disable-hardening`.

  Noticed while reviewing hebasto/bitcoin#32 (comment).

ACKs for top commit:
  theuni:
    ACK 8cfa22a. Agree it's confusing as-is and this better matches the intent.
  hebasto:
    ACK 8cfa22a
  luke-jr:
    utACK 8cfa22a
  TheCharlatan:
    ACK 8cfa22a

Tree-SHA512: 74c3219301398361d06b1ef2257fc9ec18055b1661f8733ee909adefee61e458d70991c32adf0e0450905a7ffbddc99799f5fdac894f4896cfade19f961818df
Copy link

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Posting review mid-way

CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
@hebasto hebasto force-pushed the 230715-cmake-K branch 2 times, most recently from f228f51 to 5219f18 Compare October 19, 2023 15:39
@hebasto hebasto changed the title cmake: Add hardening, reduce exports, werror, libbitcoinconsensus and install cmake: Add hardening, reduce exports, werror and install Oct 20, 2023
@hebasto
Copy link
Owner Author

hebasto commented Oct 20, 2023

I've dropped the "cmake: Build libbitcoinconsensus library" commit from this PR because I feel like it deserves its own PR, which will be submitted shortly.

And I apologise for a delay with the answer to this comment.

@hebasto
Copy link
Owner Author

hebasto commented Oct 20, 2023

And I apologise for a delay with the answer to this comment.

Answered.

@fanquake
Copy link

Where is -D_FORTIFY_SOURCE=3? I can't find any mention of it in the CMake files in this branch.

@hebasto
Copy link
Owner Author

hebasto commented Oct 20, 2023

Where is -D_FORTIFY_SOURCE=3? I can't find any mention of it in the CMake files in this branch.

Thanks! Added.

CMakeLists.txt Outdated
try_append_linker_flag(core "/HIGHENTROPYVA")
try_append_linker_flag(core "/NXCOMPAT")
else()
set(fortfy_flags "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if these could work the same way as what we discussed with hardening? Add debug/release interface libs?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked.

Frank-GER pushed a commit to syscoin/syscoin that referenced this pull request Oct 21, 2023
8cfa22a build: move -fstack-reuse=none to CORE_CXXFLAGS (fanquake)

Pull request description:

  This is not a hardening specific flag, it should be used at all times, regardless of if hardening is enabled or not. Note that this was still the case here, but having this exist in the hardening flags is confusing, and may lead someone to move it inside one of the `use_hardening` blocks, where it would become unused, with `--disable-hardening`.

  Noticed while reviewing hebasto#32 (comment).

ACKs for top commit:
  theuni:
    ACK 8cfa22a. Agree it's confusing as-is and this better matches the intent.
  hebasto:
    ACK 8cfa22a
  luke-jr:
    utACK 8cfa22a
  TheCharlatan:
    ACK 8cfa22a

Tree-SHA512: 74c3219301398361d06b1ef2257fc9ec18055b1661f8733ee909adefee61e458d70991c32adf0e0450905a7ffbddc99799f5fdac894f4896cfade19f961818df
@hebasto
Copy link
Owner Author

hebasto commented Oct 21, 2023

@theuni

I'm suggesting nested interfaces (if possible). something like:

add_library(hardening INTERFACE)
if(HARDENING)
  try_append_linker_flag(hardening "-Wl,--enable-reloc-section")
endif()
target_link_libraries(core PRIVATE hardening)

I wonder if these could work the same way as what we discussed with hardening? Add debug/release interface libs?

How does this alternative implementation look for you?

@theuni
Copy link

theuni commented Oct 24, 2023

@theuni

I'm suggesting nested interfaces (if possible). something like:

add_library(hardening INTERFACE)
if(HARDENING)
  try_append_linker_flag(hardening "-Wl,--enable-reloc-section")
endif()
target_link_libraries(core PRIVATE hardening)

I wonder if these could work the same way as what we discussed with hardening? Add debug/release interface libs?

How does this alternative implementation look for you?

Yes, please! Much better :)

@hebasto
Copy link
Owner Author

hebasto commented Oct 24, 2023

Fellow reviewers,

Please review #38 first. Thank you!

@hebasto
Copy link
Owner Author

hebasto commented Oct 26, 2023

Rebased.

How does this alternative implementation look for you?

Yes, please! Much better :)

Implemented.

@theuni
Copy link

theuni commented Oct 26, 2023

Rebased.

How does this alternative implementation look for you?

Yes, please! Much better :)

Implemented.

Note to other reviewers: The "core" lib has become the catch-all lib. Anything that doesn't apply globally can be broken out, as (for ex) hardening is here.

Copy link

@theuni theuni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Left a few questions.

I didn't review the first two commits deeply, so for now I'm mostly just assuming those functions work as intended.

try_append_cxx_flags("-fstack-clash-protection" TARGET hardening)
endif()

if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why this checks for both? Do we need to do this everywhere we want aarch64?

Copy link
Owner Author

@hebasto hebasto Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why this checks for both? Do we need to do this everywhere we want aarch64?

It is "arm64" on macOS, and "aarch64" on Linux.

We can use CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)" though.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Nah, thanks, it's good as-is.

unset(installable_targets)

if(INSTALL_MAN)
install(DIRECTORY ../doc/man/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really familiar with how our manfiles are handled, but it seems strange to me that we'd install the placeholders rather than files generated at install-time by gen-manpages.py

Presumably the answer comes from the commit message in daf1ebf: "We can't remove them completely because make dist relies on the files being present."

So now that we won't have that restriction anymore, do we need these placeholders?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really familiar with how our manfiles are handled, but it seems strange to me that we'd install the placeholders rather than files generated at install-time by gen-manpages.py

This branch mimics the Autotoos-based build system in master right now: https://github.com/hebasto/bitcoin/blob/master/doc/man/Makefile.am

Presumably the answer comes from the commit message in daf1ebf: "We can't remove them completely because make dist relies on the files being present."

So now that we won't have that restriction anymore, do we need these placeholders?

That would be possible after migration to CMake, right?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess this is just copying our current behavior. It's just that our current behavior is only needed (afact) because of autotools.

Maybe just add: "TODO: these stubs are no longer needed. man pages should be generated at install time."

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess this is just copying our current behavior. It's just that our current behavior is only needed (afact) because of autotools.

Maybe just add: "TODO: these stubs are no longer needed. man pages should be generated at install time."

Thanks! Done.

@@ -278,6 +279,12 @@ if(HARDENING)
target_link_libraries(core INTERFACE hardening)
endif()

if(REDUCE_EXPORTS)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this should probably become on by default in the future (once libbitcoinkernel is ok with it).

Historically it was only off by default because of an ancient broken boost impl that didn't properly export its exceptions.

@vasild
Copy link

vasild commented Oct 27, 2023

Light ACK e4204f4, I don't fully understand all the stuff.

Some comparisons on FreeBSD:

[diff] install autotools vs cmake
--- /tmp/autotools.install      2023-10-27 12:31:40.242919000 +0200
+++ /tmp/cmake.install  2023-10-27 12:32:07.594775000 +0200
@@ -2,22 +2,11 @@
 bin
 bin/bench_bitcoin
 bin/bitcoin-cli
-bin/bitcoin-qt
 bin/bitcoin-tx
 bin/bitcoin-util
 bin/bitcoin-wallet
 bin/bitcoind
 bin/test_bitcoin
-include
-include/bitcoinconsensus.h
-lib
-lib/libbitcoinconsensus.a
-lib/libbitcoinconsensus.la
-lib/libbitcoinconsensus.so
-lib/libbitcoinconsensus.so.0
-lib/libbitcoinconsensus.so.0.0.0
-lib/pkgconfig
-lib/pkgconfig/libbitcoinconsensus.pc
 share
 share/man
 share/man/man1
[diff] compile flags for net.cpp autotools vs cmake
--- /tmp/autotools.compile.flags	2023-10-27 13:25:45.576600000 +0200
+++ /tmp/cmake.compile.flags	2023-10-27 13:29:07.406586000 +0200
@@ -4,53 +4,29 @@
 -DDEBUG
 -DDEBUG_LOCKCONTENTION
 -DDEBUG_LOCKORDER
--DHAVE_BUILD_INFO
+-DENABLE_ZMQ=1  # not sure why ENABLE_ZMQ, USE_NATPMP and USE_UPNP are not in autotools
 -DHAVE_CONFIG_H
--DPROVIDE_FUZZ_MAIN_FUNCTION
 -DRPC_DOC_CHECK
+-DUSE_NATPMP=1
+-DUSE_UPNP=1
 -fcf-protection=full
--fPIE
+-fPIC
 -fstack-clash-protection
 -fstack-protector-all
 -ftrapv
 -g3
--I.
--I.
--I../src/config
--I./leveldb/include
--I./minisketch/include
--I./secp256k1/include
--I./univalue/include
--I/usr/local/include
--I/usr/local/include
+-I/path/to/bitcoin_source/src
+-I/path/to/bitcoin_source/src/leveldb/include
+-I/path/to/bitcoin_source/src/minisketch/include
+-I/path/to/bitcoin_source/src/univalue/include
+-I/path/to/build/src
 -isystem /usr/local/include
--isystem /usr/local/include
 -MD
--MF .deps/libbitcoin_node_a-net.Tpo
--MP
--MT libbitcoin_node_a-net.o
+-MF src/CMakeFiles/bitcoin_node.dir/net.cpp.o.d
+-MT src/CMakeFiles/bitcoin_node.dir/net.cpp.o
 -O0
 -pthread
 -std=c++17
--Wall  # why these -W options are missing from cmake?
--Wconditional-uninitialized
--Wdate-time
--Wdocumentation
 -Werror
--Wextra
--Wformat
--Wformat-security
--Wgnu
--Wimplicit-fallthrough
--Wloop-analysis
--Wno-self-assign
--Wno-unused-parameter
--Woverloaded-virtual
--Wredundant-decls
--Wshadow-field
 -Wstack-protector
--Wsuggest-override
--Wthread-safety
--Wunreachable-code-loop-increment
--Wunused-member-function
--Wvla
[diff] link flags for bitcoind autotools vs cmake
--- /tmp/autotools.link.flags	2023-10-27 13:40:53.495687000 +0200
+++ /tmp/cmake.link.flags	2023-10-27 13:46:14.900102000 +0200
@@ -1,46 +1,16 @@
--fcf-protection=full  # even though HARDENING is turned on this is not used?
 -fPIE
--fstack-clash-protection
--fstack-protector-all
 -ftrapv
 -g3
--L/usr/local/lib
--levent  # these libs are given as e.g. /usr/local/lib/libevent.so, see at the bottom
--levent
--levent_pthreads
--lminiupnpc
--lminiupnpc
--lminiupnpc
--lnatpmp
--lpthread
--lsqlite3
--lzmq
 -O0
 -pie
 -pthread
--std=c++17
--Wall  # all these -W are compilation options and autotools wrongly uses them when linking?
--Wconditional-uninitialized
--Wdate-time
--Wdocumentation
--Werror
--Wextra
--Wformat
--Wformat-security
--Wgnu
--Wimplicit-fallthrough
+-Wl,-rpath,/usr/local/lib:  # the : at the end looks like a typo?
 -Wl,-z,now
 -Wl,-z,relro
 -Wl,-z,separate-code
--Wloop-analysis
--Wno-self-assign
--Wno-unused-parameter
--Woverloaded-virtual
--Wredundant-decls
--Wshadow-field
--Wstack-protector
--Wsuggest-override
--Wthread-safety
--Wunreachable-code-loop-increment
--Wunused-member-function
--Wvla
+/usr/local/lib/libevent_pthreads.so
+/usr/local/lib/libevent.so
+/usr/local/lib/libminiupnpc.so
+/usr/local/lib/libnatpmp.so
+/usr/local/lib/libsqlite3.so
+/usr/local/lib/libzmq.so

@hebasto
Copy link
Owner Author

hebasto commented Oct 27, 2023

@vasild

Thank you for testing!

not sure why ENABLE_ZMQ, USE_NATPMP and USE_UPNP are not in autotools

In Autotools, those definitions are defined in the config/bitcoin-config.h header, for example:

AC_DEFINE([ENABLE_ZMQ], [1], [Define this symbol to enable ZMQ functions]),

However, CMake uses the "target -- properties" approach and binds definitions to specific targets, for example:

target_compile_definitions(bitcoin_zmq
INTERFACE
ENABLE_ZMQ=1
)

This approach guarantees that a particular property (i.e., a precompiler definition) will be applied iif it is required.

@hebasto
Copy link
Owner Author

hebasto commented Oct 27, 2023

@vasild

--fcf-protection=full # even though HARDENING is turned on this is not used?

What version of FreeBSD do you use?

UPD. As discussed on IRC, CMake is smart enough to avoid providing compiler options to a linker.

@hebasto
Copy link
Owner Author

hebasto commented Oct 27, 2023

+-Wl,-rpath,/usr/local/lib: # the : at the end looks like a typo?

See https://gitlab.kitware.com/cmake/cmake/-/issues/18852.

@theuni
Copy link

theuni commented Oct 27, 2023

Thanks @vasild for the comparison :)

I'd really like to spend more time reviewing the details here, but I think it's more important to get through everything at a high level once.

Personally at least, I'm happy now with the approach for adding groups of compiler/linker flags. ACK to keep things moving.

@vasild
Copy link

vasild commented Oct 27, 2023

Maybe I was not clear - my ACK implies that the diffs are ok and I do not see them as a show stopper. Some of the diffs are due to autotools doing nonsensical stuff and other due to stuff not implemented yet in cmake, as expected.

@theuni
Copy link

theuni commented Oct 27, 2023

Maybe I was not clear - my ACK implies that the diffs are ok and I do not see them as a show stopper. Some of the diffs are due to autotools doing nonsensical stuff and other due to stuff not implemented yet in cmake, as expected.

That was clear to me, thanks :)

@hebasto hebasto merged commit 6e20a0f into cmake-staging Oct 29, 2023
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants