diff --git a/CMakeLists.txt b/CMakeLists.txt index 165727a13a124791f46f5f4172a6ef81572b40c3..1d0abf5f33a16016986b71248adf29b41cfeddd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,26 @@ include(cmake/profile.cmake) include(cmake/module.cmake) include(cmake/thread.cmake) +# Fuzzers are compiled without PIC support, +# LuaJIT in FreeBSD doesn't work with PIC (gh-7640), +# ligomp.a for AArch64 CentOS is compiled without PIC support. +if (ENABLE_FUZZER OR TARGET_OS_FREEBSD OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(ENABLE_HARDENING_DEFAULT FALSE) +else() + set(ENABLE_HARDENING_DEFAULT TRUE) +endif() +option(ENABLE_HARDENING "Enable compiler options that harden against memory corruption attacks" ${ENABLE_HARDENING_DEFAULT}) +set(HARDENING_FLAGS " ") +set(HARDENING_LDFLAGS " ") +if (ENABLE_HARDENING) + set(HARDENING_FLAGS "-Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIC") + if (NOT TARGET_OS_DARWIN) + set(HARDENING_LDFLAGS "-pie -z relro -z now") + endif() + add_compile_flags("C;CXX" ${HARDENING_FLAGS}) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${HARDENING_LDFLAGS}") +endif() + set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") check_symbol_exists(MAP_ANON sys/mman.h HAVE_MAP_ANON) @@ -438,14 +458,14 @@ option(BUNDLED_LIBCURL_USE_NGHTTP2 "Build curl with bundled nghttp2" if (ENABLE_BUNDLED_LIBCURL) if(BUNDLED_LIBCURL_USE_ARES) include(BuildAres) - ares_build() + ares_build(${HARDENING_FLAGS}) endif() if(BUNDLED_LIBCURL_USE_NGHTTP2) include(BuildNghttp2) - nghttp2_build() + nghttp2_build(${HARDENING_FLAGS}) endif() include(BuildLibCURL) - curl_build() + curl_build(${HARDENING_FLAGS}) add_dependencies(build_bundled_libs bundled-libcurl) else() set(CURL_FIND_REQUIRED ON) @@ -522,7 +542,7 @@ if(ENABLE_BACKTRACE) endif() include(BuildLibUnwind) - libunwind_build() + libunwind_build(${HARDENING_FLAGS}) add_dependencies(build_bundled_libs bundled-libunwind bundled-libunwind-platform) @@ -744,6 +764,7 @@ set(options PACKAGE VERSION BUILD C_COMPILER CXX_COMPILER C_FLAGS CXX_FLAGS ENABLE_SSE2 ENABLE_AVX ENABLE_GCOV ENABLE_GPROF ENABLE_VALGRIND ENABLE_ASAN ENABLE_UB_SANITIZER ENABLE_FUZZER ENABLE_BACKTRACE + ENABLE_HARDENING ENABLE_DOC ENABLE_DIST ENABLE_BUNDLED_LIBCURL diff --git a/changelogs/unreleased/gh-7536-add-cmake-enable_hardening-option.md b/changelogs/unreleased/gh-7536-add-cmake-enable_hardening-option.md new file mode 100644 index 0000000000000000000000000000000000000000..573474d64ad26513506a583ba7aed8a7b7778e5f --- /dev/null +++ b/changelogs/unreleased/gh-7536-add-cmake-enable_hardening-option.md @@ -0,0 +1,4 @@ +## feature/build + +* Added the `-DENABLE_HARDENING=ON/OFF` CMake option that enables hardening + against memory corruption attacks (gh-7536). diff --git a/cmake/BuildAres.cmake b/cmake/BuildAres.cmake index 46db51bc60651e36331fbefbb99dc4c9343779d6..5dc3584f4a81f8b5b6854e01e3c363d438afaa32 100644 --- a/cmake/BuildAres.cmake +++ b/cmake/BuildAres.cmake @@ -1,11 +1,11 @@ # A macro to build the bundled libcares -macro(ares_build) +macro(ares_build CFLAGS) set(ARES_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/c-ares) set(ARES_BINARY_DIR ${PROJECT_BINARY_DIR}/build/ares/work) set(ARES_INSTALL_DIR ${PROJECT_BINARY_DIR}/build/ares/dest) # See BuildLibCURL.cmake for details. - set(ARES_CFLAGS "") + set(ARES_CFLAGS ${CFLAGS}) if (TARGET_OS_DARWIN AND NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "") set(ARES_CFLAGS "${ARES_CFLAGS} ${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT}") endif() diff --git a/cmake/BuildLibCURL.cmake b/cmake/BuildLibCURL.cmake index c4a2e5acf5c46ae82893879dcb5c359b37277da0..99f1ead0fce4af4a8bd642fb2e8dfa4dbb8af6d0 100644 --- a/cmake/BuildLibCURL.cmake +++ b/cmake/BuildLibCURL.cmake @@ -1,9 +1,9 @@ # A macro to build the bundled libcurl -macro(curl_build) +macro(curl_build CFLAGS) set(LIBCURL_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/curl) set(LIBCURL_BINARY_DIR ${PROJECT_BINARY_DIR}/build/curl/work) set(LIBCURL_INSTALL_DIR ${PROJECT_BINARY_DIR}/build/curl/dest) - set(LIBCURL_CMAKE_FLAGS "") + set(LIBCURL_CFLAGS ${CFLAGS}) get_filename_component(FOUND_ZLIB_ROOT_DIR ${ZLIB_INCLUDE_DIR} DIRECTORY) list(APPEND LIBCURL_CMAKE_FLAGS "-DZLIB_ROOT=${FOUND_ZLIB_ROOT_DIR}") @@ -14,17 +14,19 @@ macro(curl_build) OUTPUT_VARIABLE OPENSSL_COMPILE_OPTIONS) # Add pthread library for openssl static library linking. if(NOT OPENSSL_COMPILE_OPTIONS MATCHES ".* -pthread .*") - list(APPEND LIBCURL_CMAKE_FLAGS "-DCMAKE_C_FLAGS=-pthread") + set(LIBCURL_CFLAGS "${LIBCURL_CFLAGS} -pthread") endif() # Add librt for clock_gettime function definition. if(${CMAKE_MAJOR_VERSION} VERSION_LESS "3") CHECK_LIBRARY_EXISTS (rt clock_gettime "" HAVE_LIBRT) if (HAVE_LIBRT) - list(APPEND LIBCURL_CMAKE_FLAGS "-DCMAKE_C_FLAGS=-lrt") + set(LIBCURL_CFLAGS "${LIBCURL_CFLAGS} -lrt") endif() endif() + list(APPEND LIBCURL_CMAKE_FLAGS "-DCMAKE_C_FLAGS=${LIBCURL_CFLAGS}") + # Switch on the static build. list(APPEND LIBCURL_CMAKE_FLAGS "-DCURL_STATICLIB=ON") @@ -243,6 +245,7 @@ macro(curl_build) unset(FOUND_ZLIB_ROOT_DIR) unset(FOUND_OPENSSL_ROOT_DIR) + unset(LIBCURL_CFLAGS) unset(LIBCURL_INSTALL_DIR) unset(LIBCURL_BINARY_DIR) unset(LIBCURL_SOURCE_DIR) diff --git a/cmake/BuildLibUnwind.cmake b/cmake/BuildLibUnwind.cmake index 741316b0ea38cd6a5b284f1e908bced68b2a349b..750e6df6d04508f9c7ab2b2915be3e19ce4f9bfa 100644 --- a/cmake/BuildLibUnwind.cmake +++ b/cmake/BuildLibUnwind.cmake @@ -18,12 +18,12 @@ Cache Variables The paths to the libunwind libraries. #]========================================================================] -macro(libunwind_build) +macro(libunwind_build CFLAGS) set(LIBUNWIND_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/libunwind) set(LIBUNWIND_BUILD_DIR ${PROJECT_BINARY_DIR}/build/libunwind) set(LIBUNWIND_BINARY_DIR ${LIBUNWIND_BUILD_DIR}/work) set(LIBUNWIND_INSTALL_DIR ${LIBUNWIND_BUILD_DIR}/dest) - set(LIBUNWIND_CFLAGS "-g -O2") + set(LIBUNWIND_CFLAGS "-g -O2 ${CFLAGS}") set(LIBUNWIND_CXXFLAGS "-g -O2") include(ExternalProject) diff --git a/cmake/BuildNghttp2.cmake b/cmake/BuildNghttp2.cmake index 864cd0bf1fd84b2d15ca2d626d2b8fa4c150b6b3..54c37137fa0c76323cabb9fde6bd8c89d14a5bbf 100644 --- a/cmake/BuildNghttp2.cmake +++ b/cmake/BuildNghttp2.cmake @@ -1,12 +1,12 @@ # # A macro to build the bundled nghttp2 library. -macro(nghttp2_build) +macro(nghttp2_build CFLAGS) set(NGHTTP2_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/nghttp2) set(NGHTTP2_BINARY_DIR ${PROJECT_BINARY_DIR}/build/nghttp2/work) set(NGHTTP2_INSTALL_DIR ${PROJECT_BINARY_DIR}/build/nghttp2/dest) # See BuildLibCURL.cmake for details. - set(NGHTTP2_CFLAGS "") + set(NGHTTP2_CFLAGS ${CFLAGS}) if (TARGET_OS_DARWIN AND NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "") set(NGHTTP2_CFLAGS "${NGHTTP2_CFLAGS} ${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT}") endif() diff --git a/debian/rules b/debian/rules index 5fbe7c9dac0a3fae531baf97d2fb8c482dda5a2a..45f4c43963359ca6a87431fbefb91672a8080436 100755 --- a/debian/rules +++ b/debian/rules @@ -37,7 +37,6 @@ DEB_DH_SYSTEMD_START_ARGS_tarantool-common := --no-restart-on-upgrade tarantool # Needed for proper backtraces in fiber.info() DEB_DH_STRIP_ARGS := -X/usr/bin/tarantool -export DEB_BUILD_MAINT_OPTIONS = hardening=-stackprotector DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk diff --git a/rpm/tarantool.spec b/rpm/tarantool.spec index 10aaf9945bca6cff84a40952c9b92529e6eee040..9d76155e0542d8a9ad9ce81818f313619551b40d 100644 --- a/rpm/tarantool.spec +++ b/rpm/tarantool.spec @@ -91,9 +91,6 @@ BuildRequires: libunwind-devel %global debug_package %{nil} %global __os_install_post /usr/lib/rpm/brp-compress %{nil} %global __strip /bin/true -# -fPIE break backtraces -# https://github.com/tarantool/tarantool/issues/1262 -%undefine _hardened_build %endif # Set dependences for tests. diff --git a/static-build/CMakeLists.txt b/static-build/CMakeLists.txt index a067704df1e96e29ac536109705d9f1444ebb7f7..4b8654a96ba1e8d0c065352c431a94d4cc80104f 100644 --- a/static-build/CMakeLists.txt +++ b/static-build/CMakeLists.txt @@ -7,6 +7,7 @@ cmake_minimum_required(VERSION 3.1) # linux machine). project(tarantool-static C CXX) +include(FindPackageMessage) include(ExternalProject) set(LIBICU_VERSION release-71-1/icu4c-71_1) set(LIBICU_HASH e06ffc96f59762bd3c929b217445aaec) @@ -22,6 +23,8 @@ set(READLINE_VERSION 8.0) set(READLINE_HASH 7e6c1f16aee3244a69aba6e438295ca3) set(BACKUP_STORAGE https://distrib.hb.bizmrg.com) +include(../cmake/os.cmake) + # Pass -isysroot=<SDK_PATH> option on Mac OS to a preprocessor and a C # compiler to find header files installed with an SDK. # @@ -43,6 +46,24 @@ if (APPLE) set(DEPENDENCY_CPPFLAGS "${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT}") endif() +# LuaJIT in FreeBSD doesn't work with PIC (gh-7640), +# ligomp.a for AArch64 CentOS is compiled without PIC support. +if (TARGET_OS_FREEBSD OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(ENABLE_HARDENING_DEFAULT FALSE) +else() + set(ENABLE_HARDENING_DEFAULT TRUE) +endif() +option(ENABLE_HARDENING "Enable compiler options that harden against memory corruption attacks" ${ENABLE_HARDENING_DEFAULT}) +if (ENABLE_HARDENING) + set(HARDENING_FLAGS "-Wformat -Wformat-security -Werror=format-security -fstack-protector-strong -fPIC") + if (NOT TARGET_OS_DARWIN) + set(HARDENING_LDFLAGS "-pie -z relro -z now") + endif() + set(DEPENDENCY_CFLAGS "${DEPENDENCY_CFLAGS} ${HARDENING_FLAGS}") + set(DEPENDENCY_CXXFLAGS "${DEPENDENCY_CXXFLAGS} ${HARDENING_FLAGS}") + set(DEPENDENCY_LDFLAGS "${DEPENDENCY_LDFLAGS} ${HARDENING_LDFLAGS}") +endif() + # Install all libraries required by tarantool at current build dir # @@ -124,6 +145,7 @@ ExternalProject_Add(ncurses CXX=${CMAKE_CXX_COMPILER} CFLAGS=${DEPENDENCY_CFLAGS} CPPFLAGS=${DEPENDENCY_CPPFLAGS} + CXXFLAGS=${DEPENDENCY_CXXFLAGS} LDFLAGS=${DEPENDENCY_LDFLAGS} --prefix=<INSTALL_DIR> @@ -237,6 +259,7 @@ ExternalProject_Add(tarantool -DBUILD_STATIC=TRUE -DENABLE_DIST=TRUE -DENABLE_BACKTRACE=TRUE + -DENABLE_HARDENING=${ENABLE_HARDENING} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} ${CMAKE_TARANTOOL_ARGS}