[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 6/6] configure: add support for Control-Flow Integrity
From: |
Daniele Buono |
Subject: |
[PATCH v2 6/6] configure: add support for Control-Flow Integrity |
Date: |
Fri, 23 Oct 2020 16:06:44 -0400 |
This patch adds a flag to enable/disable control flow integrity checks
on indirect function calls.
This feature only allows indirect function calls at runtime to functions
with compatible signatures.
This feature is only provided by LLVM/Clang, and depends on link-time
optimization which is currently supported only with LLVM/Clang >= 6.0
We also add an option to enable a debugging version of cfi, with verbose
output in case of a CFI violation.
CFI on indirect function calls does not support calls to functions in
shared libraries (since they were not known at compile time), and such
calls are forbidden. QEMU relies on dlopen/dlsym when using modules,
so we make modules incompatible with CFI.
Signed-off-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
---
configure | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++
meson.build | 2 ++
2 files changed, 86 insertions(+)
diff --git a/configure b/configure
index e964040522..f996c4462e 100755
--- a/configure
+++ b/configure
@@ -272,6 +272,8 @@ debug_info="yes"
lto="false"
stack_protector=""
safe_stack=""
+cfi="no"
+cfi_debug="no"
use_containers="yes"
gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
@@ -1199,6 +1201,16 @@ for opt do
;;
--disable-safe-stack) safe_stack="no"
;;
+ --enable-cfi)
+ cfi="yes" ;
+ lto="true" ;
+ ;;
+ --disable-cfi) cfi="no"
+ ;;
+ --enable-cfi-debug) cfi_debug="yes"
+ ;;
+ --disable-cfi-debug) cfi_debug="no"
+ ;;
--disable-curses) curses="disabled"
;;
--enable-curses) curses="enabled"
@@ -1772,6 +1784,13 @@ disabled with --disable-FEATURE, default is enabled if
available:
sparse sparse checker
safe-stack SafeStack Stack Smash Protection. Depends on
clang/llvm >= 3.7 and requires coroutine backend ucontext.
+ cfi Enable Control-Flow Integrity for indirect function calls.
+ In case of a cfi violation, QEMU is terminated with SIGILL
+ Depends on lto and is incompatible with modules
+ Automatically enables Link-Time Optimization (lto)
+ cfi-debug In case of a cfi violation, a message containing the line
that
+ triggered the error is written to stderr. After the error,
+ QEMU is still terminated with SIGILL
gnutls GNUTLS cryptography support
nettle nettle cryptography support
@@ -5312,6 +5331,64 @@ EOF
CONFIGURE_CFLAGS="$QEMU_CFLAGS -flto"
CONFIGURE_LDFLAGS="$QEMU_LDFLAGS -flto"
fi
+
+########################################
+# cfi (Control Flow Integrity)
+
+if test "$cfi" = "yes"; then
+ # Compiler/Linker Flags that needs to be added for cfi:
+ # -fsanitize=cfi-icall to enable control-flow integrity checks on
+ # indirect function calls.
+ # -fsanitize-cfi-icall-generalize-pointers to allow indirect function calls
+ # with pointers of a different type (i.e. pass a void* to a
+ # function that expects a char*). Used in some spots in QEMU,
+ # with compile-time type checks done by macros
+ # -fno-sanitize-trap=cfi-icall, when debug is enabled, to display the
+ # position in the code that triggered a CFI violation
+
+ # Make sure that LTO is enabled
+ if test "$lto" != "true"; then
+ error_exit "Control Flow Integrity requires Link-Time Optimization (LTO)"
+ fi
+
+ test_cflag="-fsanitize=cfi-icall -fsanitize-cfi-icall-generalize-pointers"
+ test_ldflag="-fsanitize=cfi-icall"
+
+ if test "$cfi_debug" = "yes"; then
+ # Disable the default trap mechanism so that a error message is displayed
+ # when a CFI violation happens. The code is still terminated after the
+ # message
+ test_cflag="${test_cflag} -fno-sanitize-trap=cfi-icall"
+ test_ldflag="${test_ldflag} -fno-sanitize-trap=cfi-icall"
+ fi
+
+ # Check that cfi is supported.
+ cat > $TMPC << EOF
+int main(int argc, char *argv[]) {
+ return 0;
+}
+EOF
+ # Manually add -flto because even if is enabled, flags for it will be
+ # set up later by meson
+ if ! compile_prog "-Werror $test_cflag" "$test_ldflag"; then
+ error_exit "Control Flow Integrity is not supported by your compiler"
+ fi
+
+ # Check for incompatible options
+ if test "$modules" = "yes"; then
+ error_exit "Control Flow Integrity is not compatible with modules"
+ fi
+
+ #### All good, add the flags for CFI to our CFLAGS and LDFLAGS
+ # Flag needed both at compilation and at linking
+ QEMU_CFLAGS="$QEMU_CFLAGS $test_cflag"
+ QEMU_LDFLAGS="$QEMU_LDFLAGS $test_ldflag"
+else
+ if test "$cfi_debug" = "yes"; then
+ error_exit "Cannot enable Control Flow Integrity debugging since CFI is
not enabled"
+ fi
+fi
+
# See if __attribute__((alias)) is supported.
# This false for Xcode 9, but has been remedied for Xcode 10.
# Unfortunately, travis uses Xcode 9 by default.
@@ -6972,6 +7049,13 @@ if test "$safe_stack" = "yes"; then
echo "CONFIG_SAFESTACK=y" >> $config_host_mak
fi
+if test "$cfi" = "yes"; then
+ echo "CONFIG_CFI=y" >> $config_host_mak
+ if test "$cfi_debug" = "yes"; then
+ echo "CONFIG_CFI_DEBUG=y" >> $config_host_mak
+ fi
+fi
+
# If we're using a separate build tree, set it up now.
# DIRS are directories which we simply mkdir in the build tree;
# LINKS are things to symlink back into the source tree
diff --git a/meson.build b/meson.build
index 50e5c527df..be74a232a0 100644
--- a/meson.build
+++ b/meson.build
@@ -2071,6 +2071,8 @@ if targetos == 'windows'
summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
endif
summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
+summary_info += {'cfi support': config_host.has_key('CONFIG_CFI')}
+summary_info += {'cfi debug support': config_host.has_key('CONFIG_CFI_DEBUG')}
summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] ==
'1'}
summary_info += {'debug stack usage':
config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
--
2.17.1
- [PATCH v2 1/6] fuzz: Make fork_fuzz.ld compatible with LLVM's LLD, (continued)
- [PATCH v2 1/6] fuzz: Make fork_fuzz.ld compatible with LLVM's LLD, Daniele Buono, 2020/10/23
- [PATCH v2 2/6] configure: avoid new clang 11+ warnings, Daniele Buono, 2020/10/23
- [PATCH v2 3/6] configure: add option to enable LTO, Daniele Buono, 2020/10/23
- [PATCH v2 4/6] cfi: Initial support for cfi-icall in QEMU, Daniele Buono, 2020/10/23
- [PATCH v2 5/6] check-block: enable iotests with cfi-icall, Daniele Buono, 2020/10/23
- [PATCH v2 6/6] configure: add support for Control-Flow Integrity,
Daniele Buono <=
- Re: [PATCH v2 0/6] Add support for Control-Flow Integrity, Eric Blake, 2020/10/23