summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--Kernel/AddressSanitizer.cpp126
-rw-r--r--Kernel/AddressSanitizer.h37
-rw-r--r--Kernel/CMakeLists.txt8
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.