Skip to content

Commit

Permalink
Enable hardening flags on Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
RossBrunton committed Sep 24, 2024
1 parent 45ad7c5 commit a360c21
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 7 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ jobs:
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DUR_BUILD_TESTS=ON
-DUR_FORMAT_CPP_STYLE=ON
-DUR_WEXTRA=OFF # https://github.com/oneapi-src/unified-runtime/issues/2109
-DUR_HARDEN=ON
-DUR_DPCXX=${{github.workspace}}/dpcpp_compiler/bin/clang++
${{matrix.libbacktrace}}
${{matrix.pool_tracking}}
Expand All @@ -110,6 +112,8 @@ jobs:
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DUR_BUILD_TESTS=ON
-DUR_FORMAT_CPP_STYLE=ON
-DUR_WEXTRA=OFF # https://github.com/oneapi-src/unified-runtime/issues/2109
-DUR_HARDEN=OFF # Older GCC - doesn't support all required hardening flags
${{matrix.libbacktrace}}
${{matrix.pool_tracking}}
${{matrix.latency_tracking}}
Expand All @@ -121,6 +125,9 @@ jobs:
- name: Verify that each source file contains a license
run: cmake --build ${{github.workspace}}/build --target verify-licenses

- name: Verify hardening flags have been set
run: cmake --build ${{github.workspace}}/build --target verify-licenses

- name: Build
run: cmake --build ${{github.workspace}}/build -j $(nproc)

Expand Down
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ option(UR_BUILD_XPTI_LIBS "Build the XPTI libraries when tracing is enabled" ON)
option(UR_STATIC_LOADER "Build loader as a static library" OFF)
option(UR_FORCE_LIBSTDCXX "Force use of libstdc++ in a build using libc++ on Linux" OFF)
option(UR_ENABLE_LATENCY_HISTOGRAM "Enable latncy histogram" OFF)
option(UR_WEXTRA "Enable -Wextra on all build targets" OFF)
option(UR_HARDEN "Enable additional hardening flags" ON)
set(UR_DPCXX "" CACHE FILEPATH "Path of the DPC++ compiler executable")
set(UR_DPCXX_BUILD_FLAGS "" CACHE STRING "Build flags to pass to DPC++ when compiling device programs")
set(UR_SYCL_LIBRARY_DIR "" CACHE PATH
Expand Down Expand Up @@ -160,6 +162,8 @@ if(UR_ENABLE_TRACING)
set_target_properties(xptifw PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
)
add_ur_target_compile_options(xptifw)
add_ur_target_link_options(xptifw)

if (UR_STATIC_LOADER)
install(TARGETS xpti xptifw
Expand Down Expand Up @@ -269,6 +273,14 @@ add_custom_target(verify-licenses
COMMENT "Verify all files contain a license."
)

# Add hardening check
list(FILTER license_src EXCLUDE REGEX "registry.yml")
add_custom_target(verify-hardening
COMMAND "${PROJECT_SOURCE_DIR}/scripts/check-hardening.sh"
${CMAKE_BINARY_DIR}
COMMENT "Check hardening settings on built binaries and libraries"
)

# Add code formatter target
add_custom_target(cppformat)
# ... and all source files to the formatter
Expand Down
47 changes: 43 additions & 4 deletions cmake/helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ endfunction()

include(CheckCXXCompilerFlag)

if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
set(OLD_GCC_VERSION ON)
endif()

macro(add_sanitizer_flag flag)
set(SAVED_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} -fsanitize=${flag}")
Expand All @@ -59,18 +63,33 @@ endmacro()

function(add_ur_target_compile_options name)
if(NOT MSVC)
target_compile_definitions(${name} PRIVATE -D_FORTIFY_SOURCE=2)
target_compile_options(${name} PRIVATE
-fPIC
-Wall
-Wpedantic
-Wempty-body
-Wunused-parameter
$<$<CXX_COMPILER_ID:GNU>:-fdiagnostics-color=always>
$<$<CXX_COMPILER_ID:Clang,AppleClang>:-fcolor-diagnostics>
)
if (UR_HARDEN)
target_compile_options(${name} PRIVATE
-fstack-protector
-fstack-clash-protection
-fcf-protection=full
-fstack-protector-strong
-fvisibility=hidden # Required for -fsanitize=cfi
# -fsanitize=cfi requires -flto, which breaks a lot of things
# See: https://github.com/oneapi-src/unified-runtime/issues/2120
# -flto
# $<$<CXX_COMPILER_ID:Clang,AppleClang>:-fsanitize=cfi>
)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_definitions(${name} PRIVATE -D_FORTIFY_SOURCE=2)
target_compile_options(${name} PRIVATE -fvisibility=hidden)
target_compile_options(${name} PRIVATE
-Werror
-fvisibility=hidden
)
endif()
if(UR_DEVELOPER_MODE)
target_compile_options(${name} PRIVATE
Expand All @@ -79,6 +98,20 @@ function(add_ur_target_compile_options name)
-fstack-protector-strong
)
endif()
if(UR_WEXTRA)
target_compile_options(${name} PRIVATE
-Wextra
# Note: LLVM libraries don't compile successfully with -Wunused-parameter
-Wunused-parameter
-Wformat
-Wformat-security
)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_options(${name} PRIVATE
-Werror=format-security
)
endif()
endif()
elseif(MSVC)
target_compile_options(${name} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/MP> # clang-cl.exe does not support /MP
Expand All @@ -102,7 +135,13 @@ endfunction()
function(add_ur_target_link_options name)
if(NOT MSVC)
if (NOT APPLE)
target_link_options(${name} PRIVATE "LINKER:-z,relro,-z,now")
target_link_options(${name} PRIVATE "LINKER:-z,relro,-z,now,-z,noexecstack")
if (CMAKE_BUILD_TYPE STREQUAL "Release")
target_link_options(${name} PRIVATE
-Werror
$<$<CXX_COMPILER_ID:GNU>:-pie>
)
endif()
endif()
elseif(MSVC)
target_link_options(${name} PRIVATE
Expand Down
42 changes: 42 additions & 0 deletions scripts/check-hardening.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/sh
if [ -z $1 ]; then
echo "Usage: $0 builddir" >&2;
exit;
fi

which hardening-check >> /dev/null;
if [ $? != "0" ]; then
echo "hardening-check not found - on Ubuntu it is from the 'devscripts' package." >&2;
exit;
fi

RET=0;

for file in $1/bin/*; do
case "$file" in
*/urtrace)
# This is a python script
true;;
*)
hardening-check -q --nocfprotection --nofortify $file;;
esac
RET=$(($RET + $?))
done;

for file in $1/lib/*.so; do
case "$file" in
*/libOpenCL*)
# This is not built as part of UR
true;;
*/libzeCallMap.so | */libur_mock_headers.so)
# Only used in testing, and are too simple for many of the hardening flags to have an effect.
true;;
*)
hardening-check -q --nocfprotection --nofortify $file;;
esac
RET=$(($RET + $?))
done;

if [ $RET != "0" ]; then
exit 1;
fi
11 changes: 11 additions & 0 deletions source/adapters/level_zero/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ if(UR_BUILD_ADAPTER_L0)
)
endif()

# Ensure UR flags are propogated to level zero
# TODO: https://github.com/oneapi-src/unified-runtime/issues/2105
#foreach(TARGET IN ITEMS ze_loader ze_validation_layer ze_tracing_layer ze_null)
# add_ur_target_compile_options(${TARGET})
# add_ur_target_link_options(${TARGET})
# target_compile_options(${TARGET} PRIVATE
# $<$<IN_LIST:$<CXX_COMPILER_ID>,GNU;Clang;Intel;IntelLLVM>:-Wno-error -Wno-unused-parameter>
# $<$<CXX_COMPILER_ID:MSVC>:/WX- /UUNICODE>
# )
#endforeach()

if(NOT WIN32)
target_sources(ur_adapter_level_zero
PRIVATE
Expand Down
2 changes: 1 addition & 1 deletion source/mock/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

add_library (ur_mock_headers SHARED
add_ur_library (ur_mock_headers SHARED
"${CMAKE_CURRENT_SOURCE_DIR}/ur_mock_helpers.cpp")

target_include_directories(ur_mock_headers
Expand Down
2 changes: 1 addition & 1 deletion test/adapters/level_zero/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ if(UR_BUILD_ADAPTER_L0)
if(NOT WIN32 AND NOT UR_STATIC_ADAPTER_L0)
# Make L0 use CallMap from a seprate shared lib so that we can access the map
# from the tests. This only seems to work on linux
add_library(zeCallMap SHARED zeCallMap.cpp)
add_ur_library(zeCallMap SHARED zeCallMap.cpp)
target_compile_definitions(ur_adapter_level_zero PRIVATE UR_L0_CALL_COUNT_IN_TESTS)
# TODO: stop exporting internals like this for tests...
target_link_libraries(ur_adapter_level_zero PRIVATE zeCallMap)
Expand Down
3 changes: 2 additions & 1 deletion test/adapters/level_zero/zeCallMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
// Map used by L0 adapter to count the number of calls to each L0 function
// Lifetime is managed by the adapter, this variable is defined here
// only so that we can read it from the tests.
std::map<std::string, int> *ZeCallCount = nullptr;
__attribute__((visibility("default"))) std::map<std::string, int> *ZeCallCount =
nullptr;

0 comments on commit a360c21

Please sign in to comment.