diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | Kernel/AddressSanitizer.cpp | 126 | ||||
-rw-r--r-- | Kernel/AddressSanitizer.h | 37 | ||||
-rw-r--r-- | Kernel/CMakeLists.txt | 8 |
4 files changed, 172 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 07c51de0f6..8a05ac45a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(SERENITY_ARCH "i686" CACHE STRING "Target architecture for SerenityOS.") # Central location for all custom options used in the Serenity build. option(ENABLE_ADDRESS_SANITIZER "Enable address sanitizer testing in gcc/clang" FALSE) +option(ENABLE_KERNEL_ADDRESS_SANITIZER "Enable kernel address sanitizer testing in gcc/clang" FALSE) option(ENABLE_MEMORY_SANITIZER "Enable memory sanitizer testing in gcc/clang" FALSE) option(ENABLE_UNDEFINED_SANITIZER "Enable undefined behavior sanitizer testing in gcc/clang" FALSE) option(ENABLE_FUZZER_SANITIZER "Enable fuzzer sanitizer testing in clang" FALSE) diff --git a/Kernel/AddressSanitizer.cpp b/Kernel/AddressSanitizer.cpp new file mode 100644 index 0000000000..0cf79610d6 --- /dev/null +++ b/Kernel/AddressSanitizer.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2021, Brian Gianforcaro <b.gianfo@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__SANITIZE_ADDRESS__) + +# include <Kernel/AddressSanitizer.h> + +void Kernel::AddressSanitizer::shadow_va_check_load(unsigned long address, size_t size, void* return_address) +{ + (void)address; + (void)size; + (void)return_address; +} + +void Kernel::AddressSanitizer::shadow_va_check_store(unsigned long address, size_t size, void* return_address) +{ + (void)address; + (void)size; + (void)return_address; +} + +using namespace Kernel; +using namespace Kernel::AddressSanitizer; + +extern "C" { + +// Define a macro to easily declare the KASAN load and store callbacks for +// the various sizes of data type. +// +# define ADDRESS_SANITIZER_LOAD_STORE(size) \ + void __asan_load##size(unsigned long); \ + void __asan_load##size(unsigned long address) \ + { \ + shadow_va_check_load(address, size, __builtin_return_address(0)); \ + } \ + void __asan_load##size##_noabort(unsigned long); \ + void __asan_load##size##_noabort(unsigned long address) \ + { \ + shadow_va_check_load(address, size, __builtin_return_address(0)); \ + } \ + void __asan_store##size(unsigned long); \ + void __asan_store##size(unsigned long address) \ + { \ + shadow_va_check_store(address, size, __builtin_return_address(0)); \ + } \ + void __asan_store##size##_noabort(unsigned long); \ + void __asan_store##size##_noabort(unsigned long address) \ + { \ + shadow_va_check_store(address, size, __builtin_return_address(0)); \ + } + +ADDRESS_SANITIZER_LOAD_STORE(1); +ADDRESS_SANITIZER_LOAD_STORE(2); +ADDRESS_SANITIZER_LOAD_STORE(4); +ADDRESS_SANITIZER_LOAD_STORE(8); +ADDRESS_SANITIZER_LOAD_STORE(16); + +# undef ADDRESS_SANITIZER_LOAD_STORE + +void __asan_loadN(unsigned long, size_t); +void __asan_loadN(unsigned long address, size_t size) +{ + shadow_va_check_load(address, size, __builtin_return_address(0)); +} + +void __asan_loadN_noabort(unsigned long, size_t); +void __asan_loadN_noabort(unsigned long address, size_t size) +{ + shadow_va_check_load(address, size, __builtin_return_address(0)); +} + +void __asan_storeN(unsigned long, size_t); +void __asan_storeN(unsigned long address, size_t size) +{ + shadow_va_check_store(address, size, __builtin_return_address(0)); +} + +void __asan_storeN_noabort(unsigned long, size_t); +void __asan_storeN_noabort(unsigned long address, size_t size) +{ + shadow_va_check_store(address, size, __builtin_return_address(0)); +} + +// Performs shadow memory cleanup of the current thread's stack before a +// function marked with the [[noreturn]] attribute is called. +// +void __asan_handle_no_return(void); +void __asan_handle_no_return(void) +{ +} + +void __asan_before_dynamic_init(const char*); +void __asan_before_dynamic_init(const char* /* module_name */) +{ +} + +void __asan_after_dynamic_init(); +void __asan_after_dynamic_init() +{ +} +} + +#endif diff --git a/Kernel/AddressSanitizer.h b/Kernel/AddressSanitizer.h new file mode 100644 index 0000000000..5a9e021617 --- /dev/null +++ b/Kernel/AddressSanitizer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, Brian Gianforcaro<b.gianfo@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/Types.h> + +namespace Kernel::AddressSanitizer { + +void shadow_va_check_load(unsigned long address, size_t size, void* return_addr); + +void shadow_va_check_store(unsigned long address, size_t size, void* return_addr); + +} diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 5059dde24b..eee0c68e9d 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -10,6 +10,7 @@ set(KERNEL_SOURCES ACPI/Initialize.cpp ACPI/MultiProcessorParser.cpp ACPI/Parser.cpp + AddressSanitizer.cpp Arch/i386/CPU.cpp Arch/i386/ProcessorInfo.cpp Arch/i386/SafeMem.cpp @@ -307,6 +308,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-asynchronous-unwind-tables") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib -nostdinc -nostdinc++") +# Kernel Address Sanitize (KASAN) implementation is still a work in progress, this option +# is not currently meant to be used, besides when developing Kernel ASAN support. +# +if (ENABLE_KERNEL_ADDRESS_SANITIZER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=kernel-address") +endif() + add_compile_definitions(KERNEL) # HACK: This is a workaround for CLion to grok the kernel sources. |