summaryrefslogtreecommitdiff
path: root/Kernel/CMakeLists.txt
diff options
context:
space:
mode:
authorPatrick Meyer <git@the-space.agency>2021-06-06 16:15:07 -0700
committerGunnar Beutner <gunnar@beutner.name>2021-07-26 17:40:28 +0200
commit83f88df7574c41bd3c7255d7f46930eef6744b6b (patch)
tree4ec44f915b8c0c38f07493d344b39d8e71eac948 /Kernel/CMakeLists.txt
parent67b3255fe84324e384a52e19fb5233ccb3665c1d (diff)
downloadserenity-83f88df7574c41bd3c7255d7f46930eef6744b6b.zip
Kernel: Add option to build with coverage instrumentation and KCOV
GCC and Clang allow us to inject a call to a function named __sanitizer_cov_trace_pc on every edge. This function has to be defined by us. By noting down the caller in that function we can trace the code we have encountered during execution. Such information is used by coverage guided fuzzers like AFL and LibFuzzer to determine if a new input resulted in a new code path. This makes fuzzing much more effective. Additionally this adds a basic KCOV implementation. KCOV is an API that allows user space to request the kernel to start collecting coverage information for a given user space thread. Furthermore KCOV then exposes the collected program counters to user space via a BlockDevice which can be mmaped from user space. This work is required to add effective support for fuzzing SerenityOS to the Syzkaller syscall fuzzer. :^) :^)
Diffstat (limited to 'Kernel/CMakeLists.txt')
-rw-r--r--Kernel/CMakeLists.txt33
1 files changed, 33 insertions, 0 deletions
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt
index 87f0083fb7..c10e3a0088 100644
--- a/Kernel/CMakeLists.txt
+++ b/Kernel/CMakeLists.txt
@@ -46,6 +46,8 @@ set(KERNEL_SOURCES
Devices/CharacterDevice.cpp
Devices/Device.cpp
Devices/FullDevice.cpp
+ Devices/KCOVDevice.cpp
+ Devices/KCOVInstance.cpp
Devices/MemoryDevice.cpp
Devices/NullDevice.cpp
Devices/PCISerialDevice.cpp
@@ -76,6 +78,7 @@ set(KERNEL_SOURCES
Graphics/VirtIOGPU/GPU.cpp
Graphics/VirtIOGPU/GraphicsAdapter.cpp
Graphics/VGACompatibleAdapter.cpp
+ SanCov.cpp
Storage/Partition/DiskPartition.cpp
Storage/Partition/DiskPartitionMetadata.cpp
Storage/Partition/EBRPartitionTable.cpp
@@ -364,6 +367,36 @@ endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pie -Wl,--no-dynamic-linker")
+# Kernel Coverage (KCOV) is an API to collect and expose program counters of
+# kernel code that has been run to user space. It's rather slow and likely not
+# secure to run in production builds. Useful for coverage guided fuzzing.
+if (ENABLE_KERNEL_COVERAGE_COLLECTION)
+ add_definitions(-DENABLE_KERNEL_COVERAGE_COLLECTION)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-coverage=trace-pc")
+ set(KCOV_EXCLUDED_SOURCES
+ # Make sure we don't instrument any code called from __sanitizer_cov_trace_pc
+ # otherwise we'll end up with recursive calls to that function.
+ ../AK/Format.cpp
+ ../AK/StringBuilder.cpp
+ ../Kernel/Arch/x86/${KERNEL_ARCH}/Processor.cpp
+ ../Kernel/Devices/KCOVDevice.cpp
+ ../Kernel/Devices/KCOVInstance.cpp
+ ../Kernel/FileSystem/File.cpp
+ ../Kernel/FileSystem/FileDescription.cpp
+ ../Kernel/Heap/SlabAllocator.cpp
+ ../Kernel/init.cpp
+ ../Kernel/SanCov.cpp
+ # GCC assumes that the caller saves registers for functions according
+ # to the System V ABI and happily inserts coverage calls into the
+ # function prologue for all functions. This assumption is not true for
+ # interrupt handlers because their calling convention is not compatible
+ # with the System V ABI.
+ ../Kernel/Arch/x86/common/Interrupts.cpp
+ ../Kernel/Syscall.cpp
+ )
+ set_source_files_properties(${KCOV_EXCLUDED_SOURCES} PROPERTIES COMPILE_FLAGS "-fno-sanitize-coverage=trace-pc")
+endif()
+
# Kernel Undefined Behavior Sanitizer (KUBSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")