diff --git a/ci/scripts/cpp_build.sh b/ci/scripts/cpp_build.sh index 32ccf654bf82..54095fc2124f 100755 --- a/ci/scripts/cpp_build.sh +++ b/ci/scripts/cpp_build.sh @@ -227,6 +227,7 @@ else -DARROW_GANDIVA_PC_CXX_FLAGS="${ARROW_GANDIVA_PC_CXX_FLAGS:-}" \ -DARROW_GANDIVA="${ARROW_GANDIVA:-OFF}" \ -DARROW_GCS="${ARROW_GCS:-OFF}" \ + -DARROW_HARDENING="${ARROW_HARDENING:-OFF}" \ -DARROW_HDFS="${ARROW_HDFS:-ON}" \ -DARROW_INSTALL_NAME_RPATH="${ARROW_INSTALL_NAME_RPATH:-ON}" \ -DARROW_JEMALLOC="${ARROW_JEMALLOC:-OFF}" \ diff --git a/ci/scripts/python_wheel_xlinux_build.sh b/ci/scripts/python_wheel_xlinux_build.sh index b0e53a053217..4213b122404a 100755 --- a/ci/scripts/python_wheel_xlinux_build.sh +++ b/ci/scripts/python_wheel_xlinux_build.sh @@ -119,6 +119,7 @@ cmake \ -DARROW_FLIGHT="${ARROW_FLIGHT}" \ -DARROW_GANDIVA="${ARROW_GANDIVA}" \ -DARROW_GCS="${ARROW_GCS}" \ + -DARROW_HARDENING=ON \ -DARROW_HDFS="${ARROW_HDFS}" \ -DARROW_JEMALLOC="${ARROW_JEMALLOC}" \ -DARROW_JSON=ON \ @@ -181,6 +182,7 @@ pushd /arrow/python python -m build --sdist --wheel . --no-isolation \ -C build.verbose=true \ -C cmake.build-type="${CMAKE_BUILD_TYPE:-Debug}" \ + -C cmake.args="-DARROW_HARDENING=ON" \ -C cmake.args="-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=${CMAKE_INTERPROCEDURAL_OPTIMIZATION}" echo "=== Strip symbols from wheel ===" diff --git a/cpp/cmake_modules/DefineOptions.cmake b/cpp/cmake_modules/DefineOptions.cmake index bfe4485aa912..7de8937fd9cb 100644 --- a/cpp/cmake_modules/DefineOptions.cmake +++ b/cpp/cmake_modules/DefineOptions.cmake @@ -147,6 +147,11 @@ if(ARROW_DEFINE_OPTIONS) define_option_string(ARROW_GIT_DESCRIPTION "The Arrow git commit description (if any)" "") + # For more details see: + # https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html + define_option(ARROW_HARDENING + "Build with OpenSSF-recommended compiler and linker hardening flags" OFF) + define_option(ARROW_POSITION_INDEPENDENT_CODE "Whether to create position-independent target" ON) diff --git a/cpp/cmake_modules/SetupCxxFlags.cmake b/cpp/cmake_modules/SetupCxxFlags.cmake index 21341167fe99..9ed224fa3ea0 100644 --- a/cpp/cmake_modules/SetupCxxFlags.cmake +++ b/cpp/cmake_modules/SetupCxxFlags.cmake @@ -185,6 +185,10 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Build with -fPIC so that can static link our libraries into other people's # shared libraries set(CMAKE_POSITION_INDEPENDENT_CODE ${ARROW_POSITION_INDEPENDENT_CODE}) +if(CMAKE_POSITION_INDEPENDENT_CODE) + include(CheckPIESupported) + check_pie_supported() +endif() set(UNKNOWN_COMPILER_MESSAGE "Unknown compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") @@ -702,6 +706,71 @@ endif() message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") +# ---------------------------------------------------------------------- +# Hardening flags +# +# See the OpenSSF Compiler Options Hardening Guide for C and C++: +# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html +# +# Off by default to avoid fighting CFLAGS/CXXFLAGS/LDFLAGS from other packaging +# systems, i.e: conda. + +if(ARROW_HARDENING AND NOT MSVC) + include(CheckLinkerFlag) + + set(ARROW_HARDENING_FLAGS + -fstack-protector-strong + -fstack-clash-protection + -fstrict-flex-arrays=3 + -fzero-init-padding-bits=all + -Wtrampolines + -Wbidi-chars=any) + if(ARROW_CPU_FLAG STREQUAL "x86") + list(APPEND ARROW_HARDENING_FLAGS -fcf-protection=full) + elseif(ARROW_CPU_FLAG STREQUAL "aarch64") + list(APPEND ARROW_HARDENING_FLAGS -mbranch-protection=standard) + endif() + + # TODO: Ensure there's no performance regression. + # list(APPEND ARROW_HARDENING_FLAGS + # -fno-delete-null-pointer-checks + # -fno-strict-overflow + # -fno-strict-aliasing + # -ftrivial-auto-var-init=zero) + + # CXX_COMMON_FLAGS is applied to both CMAKE_CXX_FLAGS and CMAKE_C_FLAGS, so + # only flags that are valid for C as well may be added here. + foreach(ARROW_HARDENING_FLAG ${ARROW_HARDENING_FLAGS}) + string(MAKE_C_IDENTIFIER "CXX_SUPPORTS_${ARROW_HARDENING_FLAG}" + ARROW_HARDENING_FLAG_SUPPORTED) + check_cxx_compiler_flag(${ARROW_HARDENING_FLAG} ${ARROW_HARDENING_FLAG_SUPPORTED}) + if(${ARROW_HARDENING_FLAG_SUPPORTED}) + string(APPEND CXX_COMMON_FLAGS " ${ARROW_HARDENING_FLAG}") + endif() + endforeach() + + # _FORTIFY_SOURCE is predefined by some toolchains, undefine first. + #set(ARROW_FORTIFY_SOURCE_FLAGS "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3") + #foreach(ARROW_HARDENING_CONFIG RELEASE RELWITHDEBINFO MINSIZEREL) + # string(APPEND CMAKE_C_FLAGS_${ARROW_HARDENING_CONFIG} + # " ${ARROW_FORTIFY_SOURCE_FLAGS}") + # string(APPEND CMAKE_CXX_FLAGS_${ARROW_HARDENING_CONFIG} + # " ${ARROW_FORTIFY_SOURCE_FLAGS}") + #endforeach() + + foreach(ARROW_HARDENING_LINKER_FLAG "-Wl,-z,relro" "-Wl,-z,now" "-Wl,-z,noexecstack") + string(MAKE_C_IDENTIFIER "CXX_SUPPORTS_${ARROW_HARDENING_LINKER_FLAG}" + ARROW_HARDENING_LINKER_FLAG_VAR) + check_linker_flag(CXX ${ARROW_HARDENING_LINKER_FLAG} + ${ARROW_HARDENING_LINKER_FLAG_VAR}) + if(${ARROW_HARDENING_LINKER_FLAG_VAR}) + string(APPEND CMAKE_EXE_LINKER_FLAGS " ${ARROW_HARDENING_LINKER_FLAG}") + string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${ARROW_HARDENING_LINKER_FLAG}") + string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${ARROW_HARDENING_LINKER_FLAG}") + endif() + endforeach() +endif() + # ---------------------------------------------------------------------- # MSVC-specific linker options diff --git a/dev/conbench_envs/benchmarks.env b/dev/conbench_envs/benchmarks.env index 32e8aa6e4e7b..8eae714348f0 100644 --- a/dev/conbench_envs/benchmarks.env +++ b/dev/conbench_envs/benchmarks.env @@ -24,6 +24,7 @@ ARROW_DATASET=ON ARROW_DEFAULT_MEMORY_POOL=mimalloc ARROW_FLIGHT=OFF ARROW_GANDIVA=OFF +ARROW_HARDENING=ON ARROW_HDFS=ON ARROW_HOME=$CONDA_PREFIX ARROW_INSTALL_NAME_RPATH=ON