Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

From Alex's pull request:
* improve cross-build KVM coverage
* new --without-default-features configure flag
* add __repr__ for ConsoleSocket for debugging
* build tcg tests with -Werror
* test 32 bit builds with fedora
* remove last traces of debian9
* hotfix for centos8 powertools repo

* Move lots of feature detection code to meson (Alex, myself)
* CFI and LTO support (Daniele)
* test-char dangling pointer (Eduardo)
* Build system and win32 fixes (Marc-André)
* Initialization fixes (myself)
* TCG include cleanup (Richard, myself)
* x86 'int N' fix (Peter)

# gpg: Signature made Wed 06 Jan 2021 09:21:25 GMT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream: (52 commits)
  win32: drop fd registration to the main-loop on setting non-block
  configure: move tests/qemu-iotests/common.env generation to meson
  meson.build: convert --with-default-devices to meson
  libattr: convert to meson
  cap_ng: convert to meson
  virtfs: convert to meson
  seccomp: convert to meson
  zstd: convert to meson
  lzfse: convert to meson
  snappy: convert to meson
  lzo: convert to meson
  rbd: convert to meson
  libnfs: convert to meson
  libiscsi: convert to meson
  bzip2: convert to meson
  glusterfs: convert to meson
  curl: convert to meson
  curl: remove compatibility code, require 7.29.0
  brlapi: convert to meson
  configure: remove CONFIG_FILEVERSION and CONFIG_PRODUCTVERSION
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	trace/meson.build
This commit is contained in:
Peter Maydell
2021-01-06 15:55:29 +00:00
67 changed files with 1013 additions and 874 deletions
+17 -5
View File
@@ -7,10 +7,10 @@
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-user
--target-list-exclude="aarch64-softmmu i386-softmmu microblaze-softmmu
mips-softmmu mipsel-softmmu mips64-softmmu ppc64-softmmu sh4-softmmu
xtensa-softmmu"
- make -j$(expr $(nproc) + 1) all check-build
--target-list-exclude="arm-softmmu cris-softmmu i386-softmmu
microblaze-softmmu mips-softmmu mipsel-softmmu mips64-softmmu
ppc-softmmu sh4-softmmu xtensa-softmmu"
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
# Job to cross-build specific accelerators.
#
@@ -37,7 +37,7 @@
- cd build
- PKG_CONFIG_PATH=$PKG_CONFIG_PATH
../configure --enable-werror $QEMU_CONFIGURE_OPTS --disable-system
- make -j$(expr $(nproc) + 1) all check-build
- make -j$(expr $(nproc) + 1) all check-build $MAKE_CHECK_ARGS
cross-armel-system:
extends: .cross_system_build_job
@@ -69,6 +69,18 @@ cross-arm64-user:
variables:
IMAGE: debian-arm64-cross
cross-i386-system:
extends: .cross_system_build_job
variables:
IMAGE: fedora-i386-cross
MAKE_CHECK_ARGS: check-qtest
cross-i386-user:
extends: .cross_user_build_job
variables:
IMAGE: fedora-i386-cross
MAKE_CHECK_ARGS: check
cross-mips-system:
extends: .cross_system_build_job
variables:
+14
View File
@@ -519,6 +519,20 @@ build-trace-ust-system:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --enable-trace-backends=ust --target-list=x86_64-softmmu
# Check our reduced build configurations
build-without-default-devices:
<<: *native_build_job_definition
variables:
IMAGE: centos8
CONFIGURE_ARGS: --without-default-devices --disable-user
build-without-default-features:
<<: *native_build_job_definition
variables:
IMAGE: debian-amd64
CONFIGURE_ARGS: --without-default-features --disable-user
MAKE_CHECK_ARGS: check-unit
check-patch:
stage: build
image: $CI_REGISTRY_IMAGE/qemu/centos8:latest
-8
View File
@@ -205,14 +205,6 @@ jobs:
- ${SRC_DIR}/scripts/travis/coverage-summary.sh
# We manually include builds which we disable "make check" for
- name: "GCC without-default-devices (softmmu)"
env:
- CONFIG="--without-default-devices --disable-user"
- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-default"
- TEST_CMD=""
# Using newer GCC with sanitizers
- name: "GCC9 with sanitizers (softmmu)"
dist: bionic
+2
View File
@@ -119,6 +119,8 @@ F: softmmu/cpus.c
F: cpus-common.c
F: accel/tcg/
F: accel/stubs/tcg-stub.c
F: util/cacheinfo.c
F: util/cacheflush.c
F: scripts/decodetree.py
F: docs/devel/decodetree.rst
F: include/exec/cpu*.h
+1
View File
@@ -133,6 +133,7 @@ Makefile.ninja: build.ninja
# A separate rule is needed for Makefile dependencies to avoid -n
build.ninja: build.ninja.stamp
$(build-files):
build.ninja.stamp: meson.stamp $(build-files)
$(NINJA) $(if $V,-v,) build.ninja && touch $@
endif
+9
View File
@@ -1,3 +1,12 @@
config WHPX
bool
config HAX
bool
config HVF
bool
config TCG
bool
-1
View File
@@ -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)
+11
View File
@@ -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;
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -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"
-28
View File
@@ -37,26 +37,6 @@
// #define DEBUG_VERBOSE
#if LIBCURL_VERSION_NUM >= 0x071000
/* The multi interface timer callback was introduced in 7.16.0 */
#define NEED_CURL_TIMER_CALLBACK
#define HAVE_SOCKET_ACTION
#endif
#ifndef HAVE_SOCKET_ACTION
/* If curl_multi_socket_action isn't available, define it statically here in
* terms of curl_multi_socket. Note that ev_bitmask will be ignored, which is
* less efficient but still safe. */
static CURLMcode __curl_multi_socket_action(CURLM *multi_handle,
curl_socket_t sockfd,
int ev_bitmask,
int *running_handles)
{
return curl_multi_socket(multi_handle, sockfd, running_handles);
}
#define curl_multi_socket_action __curl_multi_socket_action
#endif
#define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
CURLPROTO_FTP | CURLPROTO_FTPS)
@@ -140,7 +120,6 @@ typedef struct BDRVCURLState {
static void curl_clean_state(CURLState *s);
static void curl_multi_do(void *arg);
#ifdef NEED_CURL_TIMER_CALLBACK
/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
{
@@ -156,7 +135,6 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
}
return 0;
}
#endif
/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
@@ -433,7 +411,6 @@ static void curl_multi_do(void *arg)
static void curl_multi_timeout_do(void *arg)
{
#ifdef NEED_CURL_TIMER_CALLBACK
BDRVCURLState *s = (BDRVCURLState *)arg;
int running;
@@ -446,9 +423,6 @@ static void curl_multi_timeout_do(void *arg)
curl_multi_check_completion(s);
qemu_mutex_unlock(&s->mutex);
#else
abort();
#endif
}
/* Called with s->mutex held. */
@@ -598,10 +572,8 @@ static void curl_attach_aio_context(BlockDriverState *bs,
s->multi = curl_multi_init();
s->aio_context = new_context;
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
#ifdef NEED_CURL_TIMER_CALLBACK
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
#endif
}
static QemuOptsList runtime_opts = {
+11 -11
View File
@@ -60,7 +60,7 @@ block_ss.add(when: 'CONFIG_QED', if_true: files(
block_ss.add(when: [libxml2, 'CONFIG_PARALLELS'], if_true: files('parallels.c'))
block_ss.add(when: 'CONFIG_WIN32', if_true: files('file-win32.c', 'win32-aio.c'))
block_ss.add(when: 'CONFIG_POSIX', if_true: [files('file-posix.c'), coref, iokit])
block_ss.add(when: 'CONFIG_LIBISCSI', if_true: files('iscsi-opts.c'))
block_ss.add(when: libiscsi, if_true: files('iscsi-opts.c'))
block_ss.add(when: 'CONFIG_LINUX', if_true: files('nvme.c'))
block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
block_ss.add(when: 'CONFIG_SHEEPDOG', if_true: files('sheepdog.c'))
@@ -71,14 +71,14 @@ block_modules = {}
modsrc = []
foreach m : [
['CONFIG_CURL', 'curl', [curl, glib], 'curl.c'],
['CONFIG_GLUSTERFS', 'gluster', glusterfs, 'gluster.c'],
['CONFIG_LIBISCSI', 'iscsi', libiscsi, 'iscsi.c'],
['CONFIG_LIBNFS', 'nfs', libnfs, 'nfs.c'],
['CONFIG_LIBSSH', 'ssh', libssh, 'ssh.c'],
['CONFIG_RBD', 'rbd', rbd, 'rbd.c'],
[curl, 'curl', [curl, glib], 'curl.c'],
[glusterfs, 'gluster', glusterfs, 'gluster.c'],
[libiscsi, 'iscsi', libiscsi, 'iscsi.c'],
[libnfs, 'nfs', libnfs, 'nfs.c'],
[libssh, 'ssh', libssh, 'ssh.c'],
[rbd, 'rbd', rbd, 'rbd.c'],
]
if config_host.has_key(m[0])
if m[0].found()
if enable_modules
modsrc += files(m[3])
endif
@@ -91,10 +91,10 @@ endforeach
# those are not exactly regular block modules, so treat them apart
if 'CONFIG_DMG' in config_host
foreach m : [
['CONFIG_LZFSE', 'dmg-lzfse', liblzfse, 'dmg-lzfse.c'],
['CONFIG_BZIP2', 'dmg-bz2', [glib, libbzip2], 'dmg-bz2.c']
[liblzfse, 'dmg-lzfse', liblzfse, 'dmg-lzfse.c'],
[libbzip2, 'dmg-bz2', [glib, libbzip2], 'dmg-bz2.c']
]
if config_host.has_key(m[0])
if m[0].found()
module_ss = ss.source_set()
module_ss.add(when: m[2], if_true: files(m[3]))
block_modules += {m[1] : module_ss}
+1 -1
View File
@@ -29,7 +29,7 @@ softmmu_ss.add(files('msmouse.c', 'wctablet.c', 'testdev.c'))
chardev_modules = {}
if config_host.has_key('CONFIG_BRLAPI')
if brlapi.found()
module_ss = ss.source_set()
module_ss.add(when: [brlapi], if_true: [files('baum.c'), pixman])
chardev_modules += { 'baum': module_ss }
Vendored
+159 -597
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
if 'CONFIG_CURL' in config_host
if curl.found()
executable('elf2dmp', files('main.c', 'addrspace.c', 'download.c', 'pdb.c', 'qemu_elf.c'),
dependencies: [glib, curl],
install: true)
+1 -1
View File
@@ -1,4 +1,4 @@
if 'CONFIG_LIBISCSI' in config_host
if libiscsi.found()
executable('vhost-user-scsi', files('vhost-user-scsi.c'),
dependencies: [qemuutil, libiscsi, vhost_user],
build_by_default: targetos == 'linux',
+1 -1
View File
@@ -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;
+137
View File
@@ -0,0 +1,137 @@
============================
Control-Flow Integrity (CFI)
============================
This document describes the current control-flow integrity (CFI) mechanism in
QEMU. How it can be enabled, its benefits and deficiencies, and how it affects
new and existing code in QEMU
Basics
------
CFI is a hardening technique that focusing on guaranteeing that indirect
function calls have not been altered by an attacker.
The type used in QEMU is a forward-edge control-flow integrity that ensures
function calls performed through function pointers, always call a "compatible"
function. A compatible function is a function with the same signature of the
function pointer declared in the source code.
This type of CFI is entirely compiler-based and relies on the compiler knowing
the signature of every function and every function pointer used in the code.
As of now, the only compiler that provides support for CFI is Clang.
CFI is best used on production binaries, to protect against unknown attack
vectors.
In case of a CFI violation (i.e. call to a non-compatible function) QEMU will
terminate abruptly, to stop the possible attack.
Building with CFI
-----------------
NOTE: CFI requires the use of link-time optimization. Therefore, when CFI is
selected, LTO will be automatically enabled.
To build with CFI, the minimum requirement is Clang 6+. If you
are planning to also enable fuzzing, then Clang 11+ is needed (more on this
later).
Given the use of LTO, a version of AR that supports LLVM IR is required.
The easies way of doing this is by selecting the AR provided by LLVM::
AR=llvm-ar-9 CC=clang-9 CXX=lang++-9 /path/to/configure --enable-cfi
CFI is enabled on every binary produced.
If desired, an additional flag to increase the verbosity of the output in case
of a CFI violation is offered (``--enable-debug-cfi``).
Using QEMU built with CFI
-------------------------
A binary with CFI will work exactly like a standard binary. In case of a CFI
violation, the binary will terminate with an illegal instruction signal.
Incompatible code with CFI
--------------------------
As mentioned above, CFI is entirely compiler-based and therefore relies on
compile-time knowledge of the code. This means that, while generally supported
for most code, some specific use pattern can break CFI compatibility, and
create false-positives. The two main patterns that can cause issues are:
* Just-in-time compiled code: since such code is created at runtime, the jump
to the buffer containing JIT code will fail.
* Libraries loaded dynamically, e.g. with dlopen/dlsym, since the library was
not known at compile time.
Current areas of QEMU that are not entirely compatible with CFI are:
1. TCG, since the idea of TCG is to pre-compile groups of instructions at
runtime to speed-up interpretation, quite similarly to a JIT compiler
2. TCI, where the interpreter has to interpret the generic *call* operation
3. Plugins, since a plugin is implemented as an external library
4. Modules, since they are implemented as an external library
5. Directly calling signal handlers from the QEMU source code, since the
signal handler may have been provided by an external library or even plugged
at runtime.
Disabling CFI for a specific function
-------------------------------------
If you are working on function that is performing a call using an
incompatible way, as described before, you can selectively disable CFI checks
for such function by using the decorator ``QEMU_DISABLE_CFI`` at function
definition, and add an explanation on why the function is not compatible
with CFI. An example of the use of ``QEMU_DISABLE_CFI`` is provided here::
/*
* 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)
NOTE: CFI needs to be disabled at the **caller** function, (i.e. a compatible
cfi function that calls a non-compatible one), since the check is performed
when the function call is performed.
CFI and fuzzing
---------------
There is generally no advantage of using CFI and fuzzing together, because
they target different environments (production for CFI, debug for fuzzing).
CFI could be used in conjunction with fuzzing to identify a broader set of
bugs that may not end immediately in a segmentation fault or triggering
an assertion. However, other sanitizers such as address and ub sanitizers
can identify such bugs in a more precise way than CFI.
There is, however, an interesting use case in using CFI in conjunction with
fuzzing, that is to make sure that CFI is not triggering any false positive
in remote-but-possible parts of the code.
CFI can be enabled with fuzzing, but with some caveats:
1. Fuzzing relies on the linker performing function wrapping at link-time.
The standard BFD linker does not support function wrapping when LTO is
also enabled. The workaround is to use LLVM's lld linker.
2. Fuzzing also relies on a custom linker script, which is only supported by
lld with version 11+.
In other words, to compile with fuzzing and CFI, clang 11+ is required, and
lld needs to be used as a linker::
AR=llvm-ar-11 CC=clang-11 CXX=lang++-11 /path/to/configure --enable-cfi \
-enable-fuzzing --extra-ldflags="-fuse-ld=lld"
and then, compile the fuzzers as usual.
+3 -2
View File
@@ -15,14 +15,15 @@ Contents:
build-system
kconfig
testing
fuzzing
control-flow-integrity
loads-stores
memory
migration
atomics
stable-process
testing
qtest
fuzzing
decodetree
secure-coding-practices
tcg

Some files were not shown because too many files have changed in this diff Show More