diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1177ff5dcf..48d5775f74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,7 @@ jobs: - name: system_deps_minimal cmake_opts: -DBUILD_WARNINGS_AS_ERRORS=On -DUSE_BUNDLED_DEPS=False -DMINIMAL_BUILD=True - name: sanitizers - cmake_opts: -DCMAKE_C_FLAGS="-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=undefined" -DCMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=undefined" -DUSE_BUNDLED_DEPS=False - ldflags: -lpthread + cmake_opts: -DUSE_ASAN=On -DUSE_UBSAN=On -DUSE_BUNDLED_DEPS=False container: image: debian:buster steps: @@ -59,7 +58,7 @@ jobs: UBSAN_OPTIONS: print_stacktrace=1 run: | mkdir -p build - cd build && LDFLAGS="${{ matrix.ldflags }}" cmake ${{ matrix.cmake_opts }} ../ + cd build && cmake ${{ matrix.cmake_opts }} ../ KERNELDIR=/lib/modules/$(ls /lib/modules)/build make -j4 make run-unit-tests diff --git a/.github/workflows/e2e_ci.yml b/.github/workflows/e2e_ci.yml index 57b65bb992..860827a0f1 100644 --- a/.github/workflows/e2e_ci.yml +++ b/.github/workflows/e2e_ci.yml @@ -15,7 +15,7 @@ concurrency: jobs: test-e2e: - name: test-e2e-${{ matrix.arch }} 😇 (system_deps) + name: test-e2e-${{ matrix.arch }} 😇 (bundled_deps) runs-on: ${{ (matrix.arch == 'arm64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-22.04' }} strategy: matrix: @@ -81,7 +81,9 @@ jobs: cd build && \ cmake \ -DBUILD_BPF=ON \ - -DUSE_BUNDLED_DEPS=OFF \ + -DUSE_BUNDLED_DEPS=ON \ + -DUSE_ASAN=ON \ + -DUSE_UBSAN=ON \ -DENABLE_LIBSINSP_E2E_TESTS=ON \ -DBUILD_LIBSCAP_MODERN_BPF=ON \ -DBUILD_LIBSCAP_GVISOR=OFF \ @@ -92,14 +94,18 @@ jobs: - name: Run e2e tests with ${{ matrix.driver.name }} 🏎️ if: matrix.arch == 'amd64' + env: + UBSAN_OPTIONS: print_stacktrace=1 run: | cd build/test/libsinsp_e2e/ - sudo ./libsinsp_e2e_tests ${{ matrix.driver.option }} + sudo -E ./libsinsp_e2e_tests ${{ matrix.driver.option }} # the actuated arm64 workers doesn't have the CONFIG_QFMT_V2 flag # which is needed for the quotactl_ok test (cmd=QQUOTA_ON + id=QFMT_VFS_V0). - name: Run e2e tests with ${{ matrix.driver.name }} 🏎️ if: matrix.arch == 'arm64' + env: + UBSAN_OPTIONS: print_stacktrace=1 run: | cd build/test/libsinsp_e2e/ - sudo ./libsinsp_e2e_tests ${{ matrix.driver.option }} --gtest_filter=-sys_call_test.quotactl_ok + sudo -E ./libsinsp_e2e_tests ${{ matrix.driver.option }} --gtest_filter=-sys_call_test.quotactl_ok diff --git a/CMakeLists.txt b/CMakeLists.txt index c43cd720dd..48f10af32a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,9 @@ option(ENABLE_LIBSCAP_TESTS "Enable libscap unit tests" OFF) option(ENABLE_LIBSINSP_E2E_TESTS "Enable libsinsp e2e tests" OFF) option(BUILD_SHARED_LIBS "Build libscap and libsinsp as shared libraries" OFF) option(ENABLE_VM_TESTS "Enable driver sanity tests" OFF) +option(USE_ASAN "Build with AddressSanitizer" OFF) +option(USE_UBSAN "Build with UndefinedBehaviorSanitizer" OFF) +option(UBSAN_HALT_ON_ERROR "Halt on error when building with UBSan" ON) if(${CMAKE_VERSION} VERSION_LESS "3.1.0" AND BUILD_SHARED_LIBS) # scap_engine_savefile uses target_sources diff --git a/cmake/modules/CompilerFlags.cmake b/cmake/modules/CompilerFlags.cmake index 5caa8f5589..a67bbf36f7 100644 --- a/cmake/modules/CompilerFlags.cmake +++ b/cmake/modules/CompilerFlags.cmake @@ -24,6 +24,9 @@ endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) +set(FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS "") +set(FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS "") + if(NOT MSVC) set(FALCOSECURITY_LIBS_COMMON_FLAGS "-Wall -ggdb") @@ -52,6 +55,19 @@ if(NOT MSVC) set(FALCOSECURITY_LIBS_COMMON_FLAGS "${FALCOSECURITY_LIBS_COMMON_FLAGS} -Werror -Wextra ${CMAKE_SUPPRESSED_WARNINGS}") endif() + if(USE_ASAN) + set(FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS "${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS};-fsanitize=address") + set(FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS "${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS};-fsanitize=address;-lpthread") + endif() + + if(USE_UBSAN) + set(FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS "${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS};-fsanitize=undefined") + set(FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS "${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS};-fsanitize=undefined") + if(UBSAN_HALT_ON_ERROR) + set(FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS "${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS};-fno-sanitize-recover=undefined") + endif() + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FALCOSECURITY_LIBS_COMMON_FLAGS}") # we need also `-std=c++17` here beacuse `set(CMAKE_CXX_STANDARD 17)` is not enough to enforce c++17 # with some Cmake versions: https://github.com/falcosecurity/libs/pull/950 diff --git a/test/drivers/CMakeLists.txt b/test/drivers/CMakeLists.txt index e1f45ad73c..4b88fc1bc5 100644 --- a/test/drivers/CMakeLists.txt +++ b/test/drivers/CMakeLists.txt @@ -60,6 +60,8 @@ if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64" AND ENABLE_IA32_TESTS) ) endif() +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) add_executable(drivers_test ${DRIVERS_TEST_SOURCES}) target_include_directories(drivers_test ${DRIVERS_TEST_INCLUDE}) target_link_libraries(drivers_test ${DRIVERS_TEST_LINK_LIBRARIES}) diff --git a/test/e2e/CMakeLists.txt b/test/e2e/CMakeLists.txt index 37cc7c56fc..86934515eb 100644 --- a/test/e2e/CMakeLists.txt +++ b/test/e2e/CMakeLists.txt @@ -17,6 +17,9 @@ else() set(E2E_REPORT ${CMAKE_CURRENT_BINARY_DIR}) endif() +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) + add_custom_target(e2e-install-deps COMMAND pip3 install -r ${CMAKE_CURRENT_SOURCE_DIR}/tests/requirements.txt COMMAND pip3 install ${CMAKE_CURRENT_SOURCE_DIR}/tests/commons/ diff --git a/test/libscap/CMakeLists.txt b/test/libscap/CMakeLists.txt index 3fad7ea4ad..0119ccbda2 100644 --- a/test/libscap/CMakeLists.txt +++ b/test/libscap/CMakeLists.txt @@ -107,6 +107,8 @@ message(STATUS "${LIBSCAP_UNIT_TESTS_PREFIX} LIBSCAP_TESTS_INCLUDE: ${LIBSCAP_TE message(STATUS "${LIBSCAP_UNIT_TESTS_PREFIX} LIBSCAP_TESTS_LIBRARIES: ${LIBSCAP_TESTS_LIBRARIES}") message(STATUS "${LIBSCAP_UNIT_TESTS_PREFIX} LIBSCAP_TESTS_DEPENDENCIES: ${LIBSCAP_TESTS_DEPENDENCIES}") +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) add_executable(libscap_test ${LIBSCAP_TESTS_SOURCES}) target_include_directories(libscap_test ${LIBSCAP_TESTS_INCLUDE}) target_link_libraries(libscap_test ${LIBSCAP_TESTS_LIBRARIES}) diff --git a/test/libsinsp_e2e/CMakeLists.txt b/test/libsinsp_e2e/CMakeLists.txt index c535fbf5f0..077545c350 100755 --- a/test/libsinsp_e2e/CMakeLists.txt +++ b/test/libsinsp_e2e/CMakeLists.txt @@ -21,6 +21,9 @@ if(NOT DEFINED DRIVER_NAME) set(DRIVER_NAME "scap") endif() +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) + # Create a libsinsp_test_var.h file with some variables used by our tests # for example the kmod path or the bpf path. configure_file ( diff --git a/test/libsinsp_e2e/resources/CMakeLists.txt b/test/libsinsp_e2e/resources/CMakeLists.txt index 2dc6faf9cb..10cbb57a14 100644 --- a/test/libsinsp_e2e/resources/CMakeLists.txt +++ b/test/libsinsp_e2e/resources/CMakeLists.txt @@ -1,5 +1,8 @@ include(ExternalProject) +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) + install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX}/test diff --git a/userspace/libpman/CMakeLists.txt b/userspace/libpman/CMakeLists.txt index e1aebc0ad1..da92e9f275 100644 --- a/userspace/libpman/CMakeLists.txt +++ b/userspace/libpman/CMakeLists.txt @@ -15,6 +15,9 @@ # limitations under the License. # +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) + add_library(pman src/stats.c src/maps.c diff --git a/userspace/libscap/CMakeLists.txt b/userspace/libscap/CMakeLists.txt index 8d6a6b8930..604a6cfa6d 100644 --- a/userspace/libscap/CMakeLists.txt +++ b/userspace/libscap/CMakeLists.txt @@ -24,6 +24,8 @@ include(ExternalProject) include(zlib) add_definitions(-DPLATFORM_NAME="${CMAKE_SYSTEM_NAME}") +add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) +add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) if(CMAKE_SYSTEM_NAME MATCHES "Linux") if(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -127,7 +129,6 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") option(BUILD_LIBSCAP_EXAMPLES "Build libscap examples" ON) include(FindMakedev) - add_subdirectory(linux) target_link_libraries(scap PUBLIC scap_platform) diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 56c85dec73..6d017059ff 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -460,7 +460,7 @@ static int32_t load_maps(struct bpf_engine *handle, struct bpf_map_data *maps, i } static int32_t parse_relocations(struct bpf_engine *handle, Elf_Data *data, Elf_Data *symbols, - GElf_Shdr *shdr, struct bpf_insn *insn, + GElf_Shdr *shdr, struct bpf_insn *insns, struct bpf_map_data *maps, int nr_maps) { int nrels; @@ -480,14 +480,18 @@ static int32_t parse_relocations(struct bpf_engine *handle, Elf_Data *data, Elf_ insn_idx = rel.r_offset / sizeof(struct bpf_insn); + struct bpf_insn insn; + gelf_getsym(symbols, GELF_R_SYM(rel.r_info), &sym); - if(insn[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) + memcpy(&insn, &insns[insn_idx], sizeof(insn)); + + if(insn.code != (BPF_LD | BPF_IMM | BPF_DW)) { - return scap_errprintf(handle->m_lasterr, 0, "invalid relocation for insn[%d].code 0x%x", insn_idx, insn[insn_idx].code); + return scap_errprintf(handle->m_lasterr, 0, "invalid relocation for insn[%d].code 0x%x", insn_idx, insn.code); } - insn[insn_idx].src_reg = BPF_PSEUDO_MAP_FD; + insn.src_reg = BPF_PSEUDO_MAP_FD; for(map_idx = 0; map_idx < nr_maps; map_idx++) { @@ -500,7 +504,8 @@ static int32_t parse_relocations(struct bpf_engine *handle, Elf_Data *data, Elf_ if(match) { - insn[insn_idx].imm = maps[map_idx].fd; + insn.imm = maps[map_idx].fd; + memcpy(&insns[insn_idx], &insn, sizeof(insn)); } else { diff --git a/userspace/libsinsp/CMakeLists.txt b/userspace/libsinsp/CMakeLists.txt index e8f9dc74ed..561f10751e 100644 --- a/userspace/libsinsp/CMakeLists.txt +++ b/userspace/libsinsp/CMakeLists.txt @@ -23,6 +23,9 @@ if(NOT MSVC) if(MUSL_OPTIMIZED_BUILD) add_definitions(-DMUSL_OPTIMIZED) endif() + + add_compile_options(${FALCOSECURITY_LIBS_USERSPACE_COMPILE_FLAGS}) + add_link_options(${FALCOSECURITY_LIBS_USERSPACE_LINK_FLAGS}) endif() if(NOT DEFINED CHISEL_TOOL_LIBRARY_NAME)