From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Daniele Buono <dbuono@linux.vnet.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [PATCH 2/2] configure: add support for Control-Flow Integrity
Date: Thu, 2 Jul 2020 14:12:04 +0100 [thread overview]
Message-ID: <20200702131204.GK1888119@redhat.com> (raw)
In-Reply-To: <0ed44c55-1f5d-6866-9555-82134ef628fb@linux.vnet.ibm.com>
On Thu, Jul 02, 2020 at 08:50:08AM -0400, Daniele Buono wrote:
>
>
> On 7/2/2020 5:52 AM, Daniel P. Berrangé wrote:
> > On Thu, Jul 02, 2020 at 01:49:48AM -0400, Daniele Buono wrote:
> > > This patch adds a flag to enable/disable control flow integrity checks
> > > on indirect function calls. This feature is only provided by LLVM/Clang
> > > v3.9 or higher, and only allows indirect function calls to functions
> > > with compatible signatures.
> > >
> > > 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.
> > >
> > > We introduce a blacklist file, to disable CFI checks in a limited number
> > > of TCG functions.
> > >
> > > The feature relies on link-time optimization (lto), which requires the
> > > use of the gold linker, and the LLVM versions of ar, ranlib and nm.
> > > This patch take care of checking that all the compiler toolchain
> > > dependencies are met.
> > >
> > > Signed-off-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
> > > ---
> > > cfi-blacklist.txt | 27 +++++++
> > > configure | 177 ++++++++++++++++++++++++++++++++++++++++++++++
> > > 2 files changed, 204 insertions(+)
> > > create mode 100644 cfi-blacklist.txt
> > >
> > > diff --git a/cfi-blacklist.txt b/cfi-blacklist.txt
> > > new file mode 100644
> > > index 0000000000..bf804431a5
> > > --- /dev/null
> > > +++ b/cfi-blacklist.txt
> > > @@ -0,0 +1,27 @@
> > > +# List of functions that should not be compiled with Control-Flow Integrity
> > > +
> > > +[cfi-icall]
> > > +# TCG creates binary blobs at runtime, with the transformed code.
> > > +# When it's time to execute it, the code is called with an indirect function
> > > +# call. Since such function did not exist at compile time, the runtime has no
> > > +# way to verify its signature. Disable CFI checks in the function that calls
> > > +# the binary blob
> > > +fun:cpu_tb_exec
> > > +
> > > +# TCI (Tiny Compiler Interpreter) is an interpreter for TCG pseudo code.
> > > +# One possible operation in the pseudo code is a call to binary code.
> > > +# Therefore, disable CFI checks in the interpreter function
> > > +fun:tcg_qemu_tb_exec
> > > +
> > > +# TCG Plugins Callback Functions. The mechanism rely on opening external
> > > +# shared libraries at runtime and get pointers to functions in such libraries
> > > +# Since these pointers are external to the QEMU binary, the runtime cannot
> > > +# verify their signature. Disable CFI Checks in all the functions that use
> > > +# such pointers.
> > > +fun:plugin_vcpu_cb__simple
> > > +fun:plugin_cb__simple
> > > +fun:plugin_cb__udata
> > > +fun:qemu_plugin_tb_trans_cb
> > > +fun:qemu_plugin_vcpu_syscall
> > > +fun:qemu_plugin_vcpu_syscall_ret
> > > +fun:plugin_load
> >
> > The need to maintain this list of functions makes me feel very
> > uneasy.
> >
> > How can we have any confidence that this list of functions is
> > accurate ? How will maintainers ensure that they correctly update
> > it as they are writing/changing code, and how will they test the
> > result ?
> >
> > It feels like it has the same general maint problem as the original
> > seccomp code we used, where we were never confident we had added
> > the right exceptions to let QEMU run without crashing when users
> > tickled some feature we forgot about.
> >
> >
> > Regards,
> > Daniel
> >
>
> I agree with you that keeping that list updated is a daunting task. In my
> opinion, however, it is not as difficult as a seccomp filter, for the
> following reasons:
>
> 1) Seccomp covers everything that runs in your process, including shared
> libraries that you have no control over. CFI covers only the code in the
> QEMU binary. So at least we don't have to guess what other libraries used by
> QEMU will or won't do during execution.
>
> 2) With seccomp you have to filter behavior that, while admissible, should
> not happen in your code. CFI can be seen as a run-time type checking system;
> if the signature of the function is wrong, that is a coding error... in
> theory. In practice, there is a corner-case because the type checking
> doesn't know the signature of code loaded or written at run-time, and that
> is why you have to use a CFI filter.
Can you elaborate on this function signature rules here ? Is this referring
to scenarios where you cast between 2 different function prototypes ?
I'm wondering if this applies to the way GLib's main loop source callbacks
are registered.
eg the g_source_set_callback method takes a callback with a signature
of "GSourceFunc" which is
gboolean (*)(void *)
but the way GSources are implemented means that each implementation gets
to define its own custom callback signature. So for example, in QIOChannel
we use
int (*)(struct QIOChannel *, enum <anonymous>, void *)
Thus, we always have an intentional bad function cast when invoking the
g_source_set_callback method.
GCC is able to warn about these if we add -Wcast-function-type, but we
don't do that because these bad casts are intentional.
eg
io/channel.c: In function ‘qio_channel_add_watch_full’:
io/channel.c:315:35: error: cast between incompatible function types from ‘QIOChannelFunc’ {aka ‘int (*)(struct QIOChannel *, enum <anonymous>, void *)’} to ‘gboolean (*)(void *)’ {aka ‘int (*)(void *)’} [-Werror=cast-function-type]
315 | g_source_set_callback(source, (GSourceFunc)func, user_data, notify);
| ^
io/channel.c: In function ‘qio_channel_wait’:
io/channel.c:507:27: error: cast between incompatible function types from ‘gboolean (*)(QIOChannel *, GIOCondition, void *)’ {aka ‘int (*)(struct QIOChannel *, enum <anonymous>, void *)’} to ‘gboolean (*)(void *)’ {aka ‘int (*)(void *)’} [-Werror=cast-function-type]
507 | (GSourceFunc)qio_channel_wait_complete,
| ^
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2020-07-02 13:12 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-02 5:49 [PATCH 0/2] Add support for Control-Flow Integrity Daniele Buono
2020-07-02 5:49 ` [PATCH 1/2] check-block: enable iotests with cfi-icall Daniele Buono
2020-07-02 5:49 ` [PATCH 2/2] configure: add support for Control-Flow Integrity Daniele Buono
2020-07-02 9:45 ` Paolo Bonzini
2020-07-02 12:19 ` Daniele Buono
2020-07-02 9:52 ` Daniel P. Berrangé
2020-07-02 12:50 ` Daniele Buono
2020-07-02 12:59 ` Paolo Bonzini
2020-07-02 13:38 ` Alexander Bulekov
2020-07-02 15:43 ` Daniele Buono
2020-08-10 19:01 ` Daniele Buono
2020-08-10 19:39 ` Paolo Bonzini
2020-08-10 21:33 ` Alexander Bulekov
2020-08-13 14:00 ` Daniele Buono
2020-07-02 13:12 ` Daniel P. Berrangé [this message]
2020-07-02 15:02 ` Daniele Buono
2020-07-16 21:57 ` Daniele Buono
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200702131204.GK1888119@redhat.com \
--to=berrange@redhat.com \
--cc=dbuono@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).