diff options
author | Daniele Buono <dbuono@linux.vnet.ibm.com> | 2020-12-04 18:06:12 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-01-02 21:03:35 +0100 |
commit | c905a3680dc1dae044ea6b9aaf9f0482e5ebf63c (patch) | |
tree | 1e70e38d8c7edee5be7794dd772da572b4e7393e /util | |
parent | cdad781d0945a39c936999b75ca18dbf066c1708 (diff) |
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 <dbuono@linux.vnet.ibm.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org
Message-Id: <20201204230615.2392-3-dbuono@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'util')
-rw-r--r-- | util/main-loop.c | 11 | ||||
-rw-r--r-- | util/oslib-posix.c | 11 |
2 files changed, 22 insertions, 0 deletions
diff --git a/util/main-loop.c b/util/main-loop.c index 6470f8eae3..6bfc7c46f5 100644 --- a/util/main-loop.c +++ b/util/main-loop.c @@ -33,6 +33,7 @@ #include "block/aio.h" #include "qemu/error-report.h" #include "qemu/queue.h" +#include "qemu/compiler.h" #ifndef _WIN32 #include <sys/wait.h> @@ -44,6 +45,16 @@ * use signalfd to listen for them. We rely on whatever the current signal * handler is to dispatch the signals when we receive them. */ +/* + * Disable CFI checks. + * We are going to call a signal hander directly. Such handler may or may not + * have been defined in our binary, so there's no guarantee that the pointer + * used to set the handler is a cfi-valid pointer. Since the handlers are + * stored in kernel memory, changing the handler to an attacker-defined + * function requires being able to call a sigaction() syscall, + * which is not as easy as overwriting a pointer in memory. + */ +QEMU_DISABLE_CFI static void sigfd_handler(void *opaque) { int fd = (intptr_t)opaque; diff --git a/util/oslib-posix.c b/util/oslib-posix.c index f15234b5c0..f1e2801b11 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -39,6 +39,7 @@ #include "qemu/thread.h" #include <libgen.h> #include "qemu/cutils.h" +#include "qemu/compiler.h" #ifdef CONFIG_LINUX #include <sys/syscall.h> @@ -773,6 +774,16 @@ void qemu_free_stack(void *stack, size_t sz) munmap(stack, sz); } +/* + * Disable CFI checks. + * We are going to call a signal hander directly. Such handler may or may not + * have been defined in our binary, so there's no guarantee that the pointer + * used to set the handler is a cfi-valid pointer. Since the handlers are + * stored in kernel memory, changing the handler to an attacker-defined + * function requires being able to call a sigaction() syscall, + * which is not as easy as overwriting a pointer in memory. + */ +QEMU_DISABLE_CFI void sigaction_invoke(struct sigaction *action, struct qemu_signalfd_siginfo *info) { |