From 6e3875ebcf0e768332735f8306bf4625b30ab61c Mon Sep 17 00:00:00 2001 From: Ka Ho Ng Date: Sun, 10 Nov 2024 04:07:14 +0000 Subject: [PATCH] sys: move SAN and COVERAGE options handling to kern.mk This allows the flags to be picked up more easily when building external modules. Sponsored by: Juniper Networks, Inc. Reviewed by: markj (earlier) Differential Revision: https://reviews.freebsd.org/D45563 --- sys/conf/kern.mk | 80 +++++++++++++++++++++++++++++++++++++++++++ sys/conf/kern.post.mk | 4 --- sys/conf/kern.pre.mk | 64 ---------------------------------- sys/conf/kmod.mk | 6 ++-- 4 files changed, 84 insertions(+), 70 deletions(-) diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index 2f451f9286a6..5d07a1d9ad3c 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -247,6 +247,86 @@ CFLAGS+= -fstack-protector CFLAGS+= -mretpoline .endif +# +# Kernel Address SANitizer support +# +.if !empty(KASAN_ENABLED) +SAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kasan \ + -fsanitize=kernel-address +.if ${COMPILER_TYPE} == "clang" +SAN_CFLAGS+= -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 +.endif + +.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 +# +.if ${COMPILER_TYPE} == "clang" +SAN_CFLAGS+= -mllvm -asan-mapping-offset=0xdfff208000000000 +.else +SAN_CFLAGS+= -fasan-shadow-offset=0xdfff208000000000 +.endif +.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 # !empty(KASAN_ENABLED) + +# +# 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. +MSAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kmsan \ + -fsanitize=kernel-memory +.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 160000 +MSAN_CFLAGS+= -fno-sanitize-memory-param-retval +.endif +SAN_CFLAGS+= ${MSAN_CFLAGS} +.endif # !empty(KMSAN_ENABLED) + +# +# 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 # !empty(COVERAGE_ENABLED) + +# Add the sanitizer C flags +CFLAGS+= ${SAN_CFLAGS} + # # Initialize stack variables on function entry # diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk index 5f6ec2db498d..59e51c394a35 100644 --- a/sys/conf/kern.post.mk +++ b/sys/conf/kern.post.mk @@ -37,10 +37,6 @@ MKMODULESENV+= WITH_CTF="${WITH_CTF}" 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 index d0a66ceceae2..6ad9d209c70a 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -93,73 +93,9 @@ ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${CFLAGS} ${ASM_CFLAGS.${.IMPSRC:T}} 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 -.if ${COMPILER_TYPE} == "clang" -SAN_CFLAGS+= -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 -.endif - -.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 -# -.if ${COMPILER_TYPE} == "clang" -SAN_CFLAGS+= -mllvm -asan-mapping-offset=0xdfff208000000000 -.else -SAN_CFLAGS+= -fasan-shadow-offset=0xdfff208000000000 -.endif -.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. -MSAN_CFLAGS+= -DSAN_NEEDS_INTERCEPTORS -DSAN_INTERCEPTOR_PREFIX=kmsan \ - -fsanitize=kernel-memory -.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} >= 160000 -MSAN_CFLAGS+= -fno-sanitize-memory-param-retval -.endif -SAN_CFLAGS+= ${MSAN_CFLAGS} -.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} 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 index 03bf42f5b413..645c04cdd135 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -406,8 +406,10 @@ ${_src}: .endfor .endif -# Add the sanitizer C flags -CFLAGS+= ${SAN_CFLAGS} +KASAN_ENABLED= ${KERN_OPTS:MKASAN} +KCSAN_ENABLED= ${KERN_OPTS:MKCSAN} +KMSAN_ENABLED= ${KERN_OPTS:MKMSAN} +KUBSAN_ENABLED= ${KERN_OPTS:MKUBSAN} # Add the gcov flags CFLAGS+= ${GCOV_CFLAGS}