diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -244,6 +244,76 @@ CFLAGS+= -mretpoline .endif +# +# Kernel Address SANitizer support +# +.if !empty(KASAN_ENABLED) +SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kasan \ + -fsanitize=kernel-address \ + -mllvm -asan-stack=true \ + -mllvm -asan-instrument-dynamic-allocas=true \ + -mllvm -asan-globals=true \ + -mllvm -asan-use-after-scope=true \ + -mllvm -asan-instrumentation-with-call-threshold=0 \ + -mllvm -asan-instrument-byval=false + +.if ${MACHINE_CPUARCH} == "aarch64" +# KASAN/ARM64 TODO: -asan-mapping-offset is calculated from: +# (VM_KERNEL_MIN_ADDRESS >> KASAN_SHADOW_SCALE_SHIFT) + $offset = KASAN_MIN_ADDRESS +# +# This is different than amd64, where we have a different +# KASAN_MIN_ADDRESS, and this offset value should eventually be +# upstreamed similar to: https://reviews.llvm.org/D98285 +# +SAN_CFLAGS+= -mllvm -asan-mapping-offset=0xdfff208000000000 +.elif ${MACHINE_CPUARCH} == "amd64" && \ + ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 180000 +# Work around https://github.com/llvm/llvm-project/issues/87923, which leads to +# an assertion failure compiling dtrace.c with asan enabled. +SAN_CFLAGS+= -mllvm -asan-use-stack-safety=0 +.endif +.endif + +# +# Kernel Concurrency SANitizer support +# +.if !empty(KCSAN_ENABLED) +SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kcsan \ + -fsanitize=thread +.endif + +# +# Kernel Memory SANitizer support +# +.if !empty(KMSAN_ENABLED) +# Disable -fno-sanitize-memory-param-retval until interceptors have been +# updated to work properly with it. +SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kmsan \ + -fsanitize=kernel-memory +.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 160000 +SAN_CFLAGS+= -fno-sanitize-memory-param-retval +.endif +.endif + +# +# Kernel Undefined Behavior SANitizer support +# +.if !empty(KUBSAN_ENABLED) +SAN_CFLAGS+= -fsanitize=undefined +.endif + +# +# Generic Kernel Coverage support +# +.if !empty(COVERAGE_ENABLED) +.if ${COMPILER_TYPE} == "clang" || \ + (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 80100) +SAN_CFLAGS+= -fsanitize-coverage=trace-pc,trace-cmp +.else +SAN_CFLAGS+= -fsanitize-coverage=trace-pc +.endif +.endif + # # Initialize stack variables on function entry # diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk --- a/sys/conf/kern.post.mk +++ b/sys/conf/kern.post.mk @@ -37,10 +37,6 @@ MKMODULESENV+= KCSAN_ENABLED="yes" .endif -.if defined(SAN_CFLAGS) -MKMODULESENV+= SAN_CFLAGS="${SAN_CFLAGS}" -.endif - .if defined(GCOV_CFLAGS) MKMODULESENV+= GCOV_CFLAGS="${GCOV_CFLAGS}" .endif diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -92,66 +92,12 @@ COMPAT_FREEBSD32_ENABLED!= grep COMPAT_FREEBSD32 opt_global.h || true ; echo KASAN_ENABLED!= grep KASAN opt_global.h || true ; echo -.if !empty(KASAN_ENABLED) -SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kasan \ - -fsanitize=kernel-address \ - -mllvm -asan-stack=true \ - -mllvm -asan-instrument-dynamic-allocas=true \ - -mllvm -asan-globals=true \ - -mllvm -asan-use-after-scope=true \ - -mllvm -asan-instrumentation-with-call-threshold=0 \ - -mllvm -asan-instrument-byval=false - -.if ${MACHINE_CPUARCH} == "aarch64" -# KASAN/ARM64 TODO: -asan-mapping-offset is calculated from: -# (VM_KERNEL_MIN_ADDRESS >> KASAN_SHADOW_SCALE_SHIFT) + $offset = KASAN_MIN_ADDRESS -# -# This is different than amd64, where we have a different -# KASAN_MIN_ADDRESS, and this offset value should eventually be -# upstreamed similar to: https://reviews.llvm.org/D98285 -# -SAN_CFLAGS+= -mllvm -asan-mapping-offset=0xdfff208000000000 -.elif ${MACHINE_CPUARCH} == "amd64" && \ - ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 180000 -# Work around https://github.com/llvm/llvm-project/issues/87923, which leads to -# an assertion failure compiling dtrace.c with asan enabled. -SAN_CFLAGS+= -mllvm -asan-use-stack-safety=0 -.endif -.endif - KCSAN_ENABLED!= grep KCSAN opt_global.h || true ; echo -.if !empty(KCSAN_ENABLED) -SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kcsan \ - -fsanitize=thread -.endif - KMSAN_ENABLED!= grep KMSAN opt_global.h || true ; echo -.if !empty(KMSAN_ENABLED) -# Disable -fno-sanitize-memory-param-retval until interceptors have been -# updated to work properly with it. -SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kmsan \ - -fsanitize=kernel-memory -.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 160000 -SAN_CFLAGS+= -fno-sanitize-memory-param-retval -.endif -.endif - KUBSAN_ENABLED!= grep KUBSAN opt_global.h || true ; echo -.if !empty(KUBSAN_ENABLED) -SAN_CFLAGS+= -fsanitize=undefined -.endif - COVERAGE_ENABLED!= grep COVERAGE opt_global.h || true ; echo -.if !empty(COVERAGE_ENABLED) -.if ${COMPILER_TYPE} == "clang" || \ - (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 80100) -SAN_CFLAGS+= -fsanitize-coverage=trace-pc,trace-cmp -.else -SAN_CFLAGS+= -fsanitize-coverage=trace-pc -.endif -.endif -CFLAGS+= ${SAN_CFLAGS} +CFLAGS+= ${SAN_CFLAGS} GCOV_ENABLED!= grep GCOV opt_global.h || true ; echo .if !empty(GCOV_ENABLED) diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -405,6 +405,11 @@ .endfor .endif +KASAN_ENABLED= ${KERN_OPTS:MKASAN} +KCSAN_ENABLED= ${KERN_OPTS:MKCSAN} +KMSAN_ENABLED= ${KERN_OPTS:MKMSAN} +KUBSAN_ENABLED= ${KERN_OPTS:MKUBSAN} + # Add the sanitizer C flags CFLAGS+= ${SAN_CFLAGS}