From c905a3680dc1dae044ea6b9aaf9f0482e5ebf63c Mon Sep 17 00:00:00 2001 From: Daniele Buono Date: Fri, 4 Dec 2020 18:06:12 -0500 Subject: cfi: Initial support for cfi-icall in QEMU LLVM/Clang, supports runtime checks for forward-edge Control-Flow Integrity (CFI). CFI on indirect function calls (cfi-icall) ensures that, in indirect function calls, the function called is of the right signature for the pointer type defined at compile time. For this check to work, the code must always respect the function signature when using function pointer, the function must be defined at compile time, and be compiled with link-time optimization. This rules out, for example, shared libraries that are dynamically loaded (given that functions are not known at compile time), and code that is dynamically generated at run-time. This patch: 1) Introduces the CONFIG_CFI flag to support cfi in QEMU 2) Introduces a decorator to allow the definition of "sensitive" functions, where a non-instrumented function may be called at runtime through a pointer. The decorator will take care of disabling cfi-icall checks on such functions, when cfi is enabled. 3) Marks functions currently in QEMU that exhibit such behavior, in particular: - The function in TCG that calls pre-compiled TBs - The function in TCI that interprets instructions - Functions in the plugin infrastructures that jump to callbacks - Functions in util that directly call a signal handler Signed-off-by: Daniele Buono Acked-by: Alex Bennée Signed-off-by: Paolo Bonzini --- accel/tcg/cpu-exec.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'accel') diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 8689c54499..fa325bb3d8 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -26,6 +26,7 @@ #include "exec/exec-all.h" #include "tcg/tcg.h" #include "qemu/atomic.h" +#include "qemu/compiler.h" #include "sysemu/qtest.h" #include "qemu/timer.h" #include "qemu/rcu.h" @@ -144,6 +145,16 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) #endif /* CONFIG USER ONLY */ /* Execute a TB, and fix up the CPU state afterwards if necessary */ +/* + * Disable CFI checks. + * TCG creates binary blobs at runtime, with the transformed code. + * A TB is a blob of binary code, created at runtime and called with an + * indirect function call. Since such function did not exist at compile time, + * the CFI runtime has no way to verify its signature and would fail. + * TCG is not considered a security-sensitive part of QEMU so this does not + * affect the impact of CFI in environment with high security requirements + */ +QEMU_DISABLE_CFI static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) { CPUArchState *env = cpu->env_ptr; -- cgit v1.2.3-55-g7522 From 3b9bd3f46b3b92501186acd18e81d3e8510b7b09 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 16 Dec 2020 13:27:58 +0100 Subject: remove TCG includes from common code Enable removing tcg/$tcg_arch from the include path when TCG is disabled. Move translate-all.h to include/exec, since stubs exist for the functions defined therein. Signed-off-by: Paolo Bonzini --- accel/stubs/tcg-stub.c | 1 - accel/tcg/cputlb.c | 2 +- accel/tcg/translate-all.c | 2 +- accel/tcg/translate-all.h | 39 --------------------------------------- accel/tcg/user-exec.c | 2 +- cpu.c | 2 +- hw/i386/kvmvapic.c | 1 - include/exec/translate-all.h | 39 +++++++++++++++++++++++++++++++++++++++ monitor/misc.c | 1 - softmmu/physmem.c | 3 +-- 10 files changed, 44 insertions(+), 48 deletions(-) delete mode 100644 accel/tcg/translate-all.h create mode 100644 include/exec/translate-all.h (limited to 'accel') diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c index e4bbf997aa..8c18d3eabd 100644 --- a/accel/stubs/tcg-stub.c +++ b/accel/stubs/tcg-stub.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "tcg/tcg.h" #include "exec/exec-all.h" void tb_flush(CPUState *cpu) diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index 42ab79c1a5..ced3dc077e 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -33,7 +33,7 @@ #include "exec/helper-proto.h" #include "qemu/atomic.h" #include "qemu/atomic128.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "trace/trace-root.h" #include "trace/mem.h" #ifdef CONFIG_PLUGIN diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index b7d50a73d4..a1803a1026 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -49,7 +49,7 @@ #include "exec/cputlb.h" #include "exec/tb-hash.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "qemu/bitmap.h" #include "qemu/error-report.h" #include "qemu/qemu-print.h" diff --git a/accel/tcg/translate-all.h b/accel/tcg/translate-all.h deleted file mode 100644 index a557b4e2bb..0000000000 --- a/accel/tcg/translate-all.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Translated block handling - * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ -#ifndef TRANSLATE_ALL_H -#define TRANSLATE_ALL_H - -#include "exec/exec-all.h" - - -/* translate-all.c */ -struct page_collection *page_collection_lock(tb_page_addr_t start, - tb_page_addr_t end); -void page_collection_unlock(struct page_collection *set); -void tb_invalidate_phys_page_fast(struct page_collection *pages, - tb_page_addr_t start, int len, - uintptr_t retaddr); -void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end); -void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr); - -#ifdef CONFIG_USER_ONLY -int page_unprotect(target_ulong address, uintptr_t pc); -#endif - -#endif /* TRANSLATE_ALL_H */ diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 293ee86ea4..1215b55ca0 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -23,7 +23,7 @@ #include "tcg/tcg.h" #include "qemu/bitops.h" #include "exec/cpu_ldst.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "exec/helper-proto.h" #include "qemu/atomic128.h" #include "trace/trace-root.h" diff --git a/cpu.c b/cpu.c index 0c485cdf2d..0b245cda2e 100644 --- a/cpu.c +++ b/cpu.c @@ -34,7 +34,7 @@ #include "sysemu/tcg.h" #include "sysemu/kvm.h" #include "sysemu/replay.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "exec/log.h" uintptr_t qemu_host_page_size; diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 077c3f4866..2c1898032e 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -21,7 +21,6 @@ #include "hw/sysbus.h" #include "hw/boards.h" #include "migration/vmstate.h" -#include "tcg/tcg.h" #include "qom/object.h" #define VAPIC_IO_PORT 0x7e diff --git a/include/exec/translate-all.h b/include/exec/translate-all.h new file mode 100644 index 0000000000..a557b4e2bb --- /dev/null +++ b/include/exec/translate-all.h @@ -0,0 +1,39 @@ +/* + * Translated block handling + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#ifndef TRANSLATE_ALL_H +#define TRANSLATE_ALL_H + +#include "exec/exec-all.h" + + +/* translate-all.c */ +struct page_collection *page_collection_lock(tb_page_addr_t start, + tb_page_addr_t end); +void page_collection_unlock(struct page_collection *set); +void tb_invalidate_phys_page_fast(struct page_collection *pages, + tb_page_addr_t start, int len, + uintptr_t retaddr); +void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end); +void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr); + +#ifdef CONFIG_USER_ONLY +int page_unprotect(target_ulong address, uintptr_t pc); +#endif + +#endif /* TRANSLATE_ALL_H */ diff --git a/monitor/misc.c b/monitor/misc.c index a5d4d4e4f4..a7650ed747 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -77,7 +77,6 @@ #include "qapi/qmp-event.h" #include "sysemu/cpus.h" #include "qemu/cutils.h" -#include "tcg/tcg.h" #if defined(TARGET_S390X) #include "hw/s390x/storage-keys.h" diff --git a/softmmu/physmem.c b/softmmu/physmem.c index 2cd1de4a2c..67b53d39e4 100644 --- a/softmmu/physmem.c +++ b/softmmu/physmem.c @@ -25,7 +25,6 @@ #include "cpu.h" #include "exec/exec-all.h" #include "exec/target_page.h" -#include "tcg/tcg.h" #include "hw/qdev-core.h" #include "hw/qdev-properties.h" #include "hw/boards.h" @@ -53,7 +52,7 @@ #include "qemu/rcu_queue.h" #include "qemu/main-loop.h" -#include "translate-all.h" +#include "exec/translate-all.h" #include "sysemu/replay.h" #include "exec/memory-internal.h" -- cgit v1.2.3-55-g7522 From 0a18911074a1b379540446c6a432b796ab7c436d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 17 Nov 2020 14:58:32 +0100 Subject: meson: cleanup Kconfig.host handling Build the array of command line arguments coming from config_host once for all targets. Add all accelerators to accel/Kconfig so that the command line arguments for accelerators can be computed easily in the existing "foreach sym: accelerators" loop. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini --- accel/Kconfig | 9 +++++++++ docs/devel/kconfig.rst | 19 +++++++++---------- meson.build | 43 +++++++++++++++++-------------------------- 3 files changed, 35 insertions(+), 36 deletions(-) (limited to 'accel') diff --git a/accel/Kconfig b/accel/Kconfig index 2ad94a3839..461104c771 100644 --- a/accel/Kconfig +++ b/accel/Kconfig @@ -1,3 +1,12 @@ +config WHPX + bool + +config HAX + bool + +config HVF + bool + config TCG bool diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst index 336ba0e8e5..cb2d7ffac0 100644 --- a/docs/devel/kconfig.rst +++ b/docs/devel/kconfig.rst @@ -288,21 +288,20 @@ they will include all these symbols and some help text on what they do. ---------------- In some special cases, a configurable element depends on host features -that are detected by QEMU's configure script; for example some devices -depend on the availability of KVM or on the presence of a library on -the host. +that are detected by QEMU's configure or ``meson.build`` scripts; for +example some devices depend on the availability of KVM or on the presence +of a library on the host. These symbols should be listed in ``Kconfig.host`` like this:: - config KVM + config TPM bool -and also listed as follows in the top-level Makefile's ``MINIKCONF_ARGS`` +and also listed as follows in the top-level meson.build's host_kconfig variable:: - MINIKCONF_ARGS = \ - $@ $*/config-devices.mak.d $< $(MINIKCONF_INPUTS) \ - CONFIG_KVM=$(CONFIG_KVM) \ - CONFIG_SPICE=$(CONFIG_SPICE) \ - CONFIG_TPM=$(CONFIG_TPM) \ + host_kconfig = \ + ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \ + ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \ + ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \ ... diff --git a/meson.build b/meson.build index 0e70fe7a89..d114a0137b 100644 --- a/meson.build +++ b/meson.build @@ -958,21 +958,19 @@ if link_language == 'cpp' } endif -kconfig_external_symbols = [ - 'CONFIG_KVM', - 'CONFIG_XEN', - 'CONFIG_TPM', - 'CONFIG_SPICE', - 'CONFIG_IVSHMEM', - 'CONFIG_OPENGL', - 'CONFIG_X11', - 'CONFIG_VHOST_USER', - 'CONFIG_VHOST_VDPA', - 'CONFIG_VHOST_KERNEL', - 'CONFIG_VIRTFS', - 'CONFIG_LINUX', - 'CONFIG_PVRDMA', -] +host_kconfig = \ + ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \ + ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \ + ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \ + ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \ + ('CONFIG_X11' in config_host ? ['CONFIG_X11=y'] : []) + \ + ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \ + ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \ + ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ + ('CONFIG_VIRTFS' in config_host ? ['CONFIG_VIRTFS=y'] : []) + \ + ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \ + ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host @@ -1007,7 +1005,7 @@ foreach target : target_dirs } endif - have_accel = false + accel_kconfig = [] foreach sym: accelerators if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) config_target += { sym: 'y' } @@ -1015,10 +1013,10 @@ foreach target : target_dirs if sym == 'CONFIG_XEN' and have_xen_pci_passthrough config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' } endif - have_accel = true + accel_kconfig += [ sym + '=y' ] endif endforeach - if not have_accel + if accel_kconfig.length() == 0 if default_targets continue endif @@ -1072,13 +1070,6 @@ foreach target : target_dirs configuration: config_target_data)} if target.endswith('-softmmu') - base_kconfig = [] - foreach sym : kconfig_external_symbols - if sym in config_target or sym in config_host - base_kconfig += '@0@=y'.format(sym) - endif - endforeach - config_devices_mak = target + '-config-devices.mak' config_devices_mak = configure_file( input: ['default-configs/devices' / target + '.mak', 'Kconfig'], @@ -1087,7 +1078,7 @@ foreach target : target_dirs capture: true, command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'], config_devices_mak, '@DEPFILE@', '@INPUT@', - base_kconfig]) + host_kconfig, accel_kconfig]) config_devices_data = configuration_data() config_devices = keyval.load(config_devices_mak) -- cgit v1.2.3-55-g7522