[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 19/55] configure,meson: support Control-Flow Integrity
From: |
Paolo Bonzini |
Subject: |
[PULL 19/55] configure,meson: support Control-Flow Integrity |
Date: |
Mon, 21 Dec 2020 15:44:11 +0100 |
From: Daniele Buono <dbuono@linux.vnet.ibm.com>
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.
All the checks are performed in meson.build. configure is only used to
forward the flags to meson
Signed-off-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
Message-Id: <20201204230615.2392-5-dbuono@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
configure | 22 ++++++++++++++++++++--
meson.build | 44 ++++++++++++++++++++++++++++++++++++++++++++
meson_options.txt | 4 ++++
3 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 55e77bf289..f470cdbe50 100755
--- a/configure
+++ b/configure
@@ -411,6 +411,8 @@ coroutine=""
coroutine_pool="$default_feature"
debug_stack_usage="no"
crypto_afalg="no"
+cfi="false"
+cfi_debug="false"
seccomp="$default_feature"
glusterfs="$default_feature"
glusterfs_xlator_opt="no"
@@ -1195,6 +1197,16 @@ for opt do
;;
--disable-safe-stack) safe_stack="no"
;;
+ --enable-cfi)
+ cfi="true";
+ lto="true";
+ ;;
+ --disable-cfi) cfi="false"
+ ;;
+ --enable-cfi-debug) cfi_debug="true"
+ ;;
+ --disable-cfi-debug) cfi_debug="false"
+ ;;
--disable-curses) curses="disabled"
;;
--enable-curses) curses="enabled"
@@ -1788,7 +1800,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
gcrypt libgcrypt cryptography support
@@ -6970,7 +6988,7 @@ NINJA=$ninja $meson setup \
-Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \
${staticpic:+-Db_staticpic=$staticpic} \
-Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false;
fi) \
- -Db_lto=$lto \
+ -Db_lto=$lto -Dcfi=$cfi -Dcfi_debug=$cfi_debug \
-Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \
-Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \
-Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \
diff --git a/meson.build b/meson.build
index d05d880114..94ef023ad1 100644
--- a/meson.build
+++ b/meson.build
@@ -773,6 +773,7 @@ elif get_option('vhost_user_blk_server').disabled() or not
have_system
have_vhost_user_blk_server = false
endif
+
if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
error('Cannot enable fuse-lseek while fuse is disabled')
endif
@@ -795,6 +796,46 @@ if not get_option('fuse_lseek').disabled()
endif
endif
+if get_option('cfi')
+ cfi_flags=[]
+ # Check for dependency on LTO
+ if not get_option('b_lto')
+ error('Selected Control-Flow Integrity but LTO is disabled')
+ endif
+ if config_host.has_key('CONFIG_MODULES')
+ error('Selected Control-Flow Integrity is not compatible with modules')
+ endif
+ # Check for cfi flags. CFI requires LTO so we can't use
+ # get_supported_arguments, but need a more complex "compiles" which allows
+ # custom arguments
+ if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
+ args: ['-flto', '-fsanitize=cfi-icall'] )
+ cfi_flags += '-fsanitize=cfi-icall'
+ else
+ error('-fsanitize=cfi-icall is not supported by the compiler')
+ endif
+ if cc.compiles('int main () { return 0; }',
+ name: '-fsanitize-cfi-icall-generalize-pointers',
+ args: ['-flto', '-fsanitize=cfi-icall',
+ '-fsanitize-cfi-icall-generalize-pointers'] )
+ cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
+ else
+ error('-fsanitize-cfi-icall-generalize-pointers is not supported by the
compiler')
+ endif
+ if get_option('cfi_debug')
+ if cc.compiles('int main () { return 0; }',
+ name: '-fno-sanitize-trap=cfi-icall',
+ args: ['-flto', '-fsanitize=cfi-icall',
+ '-fno-sanitize-trap=cfi-icall'] )
+ cfi_flags += '-fno-sanitize-trap=cfi-icall'
+ else
+ error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
+ endif
+ endif
+ add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp',
'objc'])
+ add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp',
'objc'])
+endif
+
#################
# config-host.h #
#################
@@ -831,6 +872,7 @@ config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
config_host_data.set('CONFIG_STATX', has_statx)
config_host_data.set('CONFIG_FUSE', fuse.found())
config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
+config_host_data.set('CONFIG_CFI', get_option('cfi'))
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
config_host_data.set('QEMU_VERSION_MAJOR',
meson.project_version().split('.')[0])
config_host_data.set('QEMU_VERSION_MINOR',
meson.project_version().split('.')[1])
@@ -2195,6 +2237,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': get_option('cfi')}
+summary_info += {'CFI debug support': get_option('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')}
diff --git a/meson_options.txt b/meson_options.txt
index f8f053b5c8..242e0769fb 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -35,6 +35,10 @@ option('xen_pci_passthrough', type: 'feature', value: 'auto',
description: 'Xen PCI passthrough support')
option('tcg', type: 'feature', value: 'auto',
description: 'TCG support')
+option('cfi', type: 'boolean', value: 'false',
+ description: 'Control-Flow Integrity (CFI)')
+option('cfi_debug', type: 'boolean', value: 'false',
+ description: 'Verbose errors in case of CFI violation')
option('cocoa', type : 'feature', value : 'auto',
description: 'Cocoa user interface (macOS only)')
--
2.29.2
- [PULL 11/55] configure: document --without-default-{features, devices}, (continued)
- [PULL 11/55] configure: document --without-default-{features, devices}, Paolo Bonzini, 2020/12/21
- [PULL 07/55] tests/tcg: build tests with -Werror, Paolo Bonzini, 2020/12/21
- [PULL 14/55] qom: Assert that objects being destroyed have no parent, Paolo Bonzini, 2020/12/21
- [PULL 16/55] configure,meson: add option to enable LTO, Paolo Bonzini, 2020/12/21
- [PULL 17/55] cfi: Initial support for cfi-icall in QEMU, Paolo Bonzini, 2020/12/21
- [PULL 33/55] configure: remove variable bogus_os, Paolo Bonzini, 2020/12/21
- [PULL 40/55] bzip2: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 39/55] glusterfs: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 15/55] target/i386: Check privilege level for protected mode 'int N' task gate, Paolo Bonzini, 2020/12/21
- [PULL 18/55] check-block: enable iotests with cfi-icall, Paolo Bonzini, 2020/12/21
- [PULL 19/55] configure,meson: support Control-Flow Integrity,
Paolo Bonzini <=
- [PULL 20/55] docs: Add CFI Documentation, Paolo Bonzini, 2020/12/21
- [PULL 29/55] meson: use pkg-config method for libudev, Paolo Bonzini, 2020/12/21
- [PULL 25/55] Makefile: add dummy target for build.ninja dependencies, Paolo Bonzini, 2020/12/21
- [PULL 43/55] libssh: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 48/55] zstd: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 50/55] virtfs: convert to meson, Paolo Bonzini, 2020/12/21
- [PULL 13/55] test-char: Destroy chardev correctly at char_file_test_internal(), Paolo Bonzini, 2020/12/21
- [PULL 35/55] configure: remove CONFIG_FILEVERSION and CONFIG_PRODUCTVERSION, Paolo Bonzini, 2020/12/21
- [PULL 27/55] meson: switch minimum meson version to 0.56.0, Paolo Bonzini, 2020/12/21
- [PULL 55/55] win32: drop fd registration to the main-loop on setting non-block, Paolo Bonzini, 2020/12/21