Message ID | 20190313124042.12855-4-pbonzini@redhat.com |
---|---|
State | New |
Headers | show |
Series | CET support | expand |
On 3/13/19 7:40 AM, Paolo Bonzini wrote: > CET requires object files to note which features are supported. The linker CET = ? > will merge them to the set of features that are supported by all object > files. The compiler creates these notes when the -fcf-protection option > is passed, but we have to blacklist some object files that only support > a subset of the full CET feature set. The next patches will improve the > situation so that QEMU can be built with full protection. > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > configure | 27 +++++++++++++++++++++++++++ > Makefile.target | 3 +++ > util/Makefile.objs | 5 +++++ > 3 files changed, 35 insertions(+) > > @@ -1757,6 +1762,7 @@ disabled with --disable-FEATURE, default is enabled if available: > lzfse support of lzfse compression library > (for reading lzfse-compressed dmg images) > seccomp seccomp support > + cet Control-flow Enforcement Technology Ah. Still, might be worth mentioning in the commit body as well.
On 13/03/19 13:59, Eric Blake wrote: > On 3/13/19 7:40 AM, Paolo Bonzini wrote: >> CET requires object files to note which features are supported. The linker > > CET = ? > >> will merge them to the set of features that are supported by all object >> files. The compiler creates these notes when the -fcf-protection option >> is passed, but we have to blacklist some object files that only support >> a subset of the full CET feature set. The next patches will improve the >> situation so that QEMU can be built with full protection. >> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> >> --- >> configure | 27 +++++++++++++++++++++++++++ >> Makefile.target | 3 +++ >> util/Makefile.objs | 5 +++++ >> 3 files changed, 35 insertions(+) >> > >> @@ -1757,6 +1762,7 @@ disabled with --disable-FEATURE, default is enabled if available: >> lzfse support of lzfse compression library >> (for reading lzfse-compressed dmg images) >> seccomp seccomp support >> + cet Control-flow Enforcement Technology > > Ah. Still, might be worth mentioning in the commit body as well. Actually I might change it to cf-protection, since that's what the GCC flag is named. Paolo
* Paolo Bonzini: > Actually I might change it to cf-protection, since that's what the GCC > flag is named. The GCC flag is supposed to generic, so that it can be used for similar features other architectures might provide. Your code looks rather x86-centric to me, so CET seems appropriate here. Thanks, Florian
On 13/03/19 14:31, Florian Weimer wrote: > * Paolo Bonzini: > >> Actually I might change it to cf-protection, since that's what the GCC >> flag is named. > > The GCC flag is supposed to generic, so that it can be used for similar > features other architectures might provide. Your code looks rather > x86-centric to me, so CET seems appropriate here. The configure option is generic. When enabled, the Makefiles will *disable* CET features selectively on object files that do not support that feature, and the disabled feature will propagate to the binary. Even without any further target-specific patches, user-mode emulation binaries will always have shadow stacks, because they don't need coroutines and don't include the problematic util/coroutine-ucontext.o object file. Likewise, system-mode emulation binaries will have indirect branch tracking if built without binary translation support (i.e. Xen/KVM only). What the next patches do is to enable the full set of control flow protections on all binaries on Intel targets. However, a subset can be made available without any target-specific code, and that part is supposed to be generic just like GCC's -fcf-protection flag. And yes, all this probably should go in more verbose commit messages... Paolo
On 3/13/19 5:40 AM, Paolo Bonzini wrote: > +########################################## > +# detect CET support in the toolchain > + > +if test "$cet" != no; then > + write_c_skeleton; > + if ! compile_prog "-fcf-protection" "" ; then > + if test "$cet" = yes; then > + feature_not_found "cet" 'CET is not supported by your toolchain' > + fi > + cet=no > + fi > +fi > +if test "$cet" = ""; then > + cet=yes > + QEMU_CFLAGS="-fcf-protection $QEMU_CFLAGS" > +fi Hmm. The gcc for aarch64 names the similar feature -mbranch-protection. I'm rather annoyed that the i386 gcc folk appropriated a generic -f name without actually making the feature generic at the same time. Thankfully the aarch64 version does not include shadow stacks, and so is less invasive into the normal abi -- ARM uses pointer authentication instead. r~
On 14/03/19 01:56, Richard Henderson wrote: > Hmm. The gcc for aarch64 names the similar feature -mbranch-protection. I'm > rather annoyed that the i386 gcc folk appropriated a generic -f name without > actually making the feature generic at the same time. Wouldn't -fcf-protection=branch also apply to ARM BTI? Pointer authentication can even be enabled by default on GCC 9 if I remember correctly, so it doesn't need an option at all. > Thankfully the aarch64 version does not include shadow stacks, and so is less > invasive into the normal abi -- ARM uses pointer authentication instead. Branch target authentication should probably should be one or more separate -fcf-protection options, but it is reasonable to make it generic as well. One could even implement a (much) weaker version of pointer authentication without hardware support. You could mangle the return address on entry and return, for example with a XOR/XOR or ADD/SUB of a per-thread datum, and likewise mangle function pointers with a per-process datum or with a hash based on the function's type signature. Both would need debugger support, and the latter would require modifying hand-written assembly. Paolo
On 3/14/19 3:46 AM, Paolo Bonzini wrote: > On 14/03/19 01:56, Richard Henderson wrote: >> Hmm. The gcc for aarch64 names the similar feature -mbranch-protection. I'm >> rather annoyed that the i386 gcc folk appropriated a generic -f name without >> actually making the feature generic at the same time. > > Wouldn't -fcf-protection=branch also apply to ARM BTI? It should, but doesn't. Which was sort of my point re non-coordination of development. r~
On 14/03/19 16:23, Richard Henderson wrote: > On 3/14/19 3:46 AM, Paolo Bonzini wrote: >> On 14/03/19 01:56, Richard Henderson wrote: >>> Hmm. The gcc for aarch64 names the similar feature -mbranch-protection. I'm >>> rather annoyed that the i386 gcc folk appropriated a generic -f name without >>> actually making the feature generic at the same time. >> >> Wouldn't -fcf-protection=branch also apply to ARM BTI? > > It should, but doesn't. Which was sort of my point re non-coordination of > development. I agree. We should open a GCC bug about it, to make sure that in the long run -fcf-protection does suffice on all architectures. Paolo
diff --git a/configure b/configure index 42a7e479fd..4470fe8e74 100755 --- a/configure +++ b/configure @@ -446,6 +446,7 @@ win_sdk="no" want_tools="yes" libiscsi="" libnfs="" +cet="no" # leave it disabled until we can test performance coroutine="" coroutine_pool="" debug_stack_usage="no" @@ -1246,6 +1247,10 @@ for opt do ;; --with-pkgversion=*) pkgversion="$optarg" ;; + --enable-cet) cet="yes" + ;; + --disable-cet) cet="no" + ;; --with-coroutine=*) coroutine="$optarg" ;; --disable-coroutine-pool) coroutine_pool="no" @@ -1757,6 +1762,7 @@ disabled with --disable-FEATURE, default is enabled if available: lzfse support of lzfse compression library (for reading lzfse-compressed dmg images) seccomp seccomp support + cet Control-flow Enforcement Technology coroutine-pool coroutine freelist (better performance) glusterfs GlusterFS backend tpm TPM support @@ -5074,6 +5080,23 @@ if have_backend "dtrace"; then fi fi +########################################## +# detect CET support in the toolchain + +if test "$cet" != no; then + write_c_skeleton; + if ! compile_prog "-fcf-protection" "" ; then + if test "$cet" = yes; then + feature_not_found "cet" 'CET is not supported by your toolchain' + fi + cet=no + fi +fi +if test "$cet" = ""; then + cet=yes + QEMU_CFLAGS="-fcf-protection $QEMU_CFLAGS" +fi + ########################################## # check and set a backend for coroutine @@ -6258,6 +6281,7 @@ echo "netmap support $netmap" echo "Linux AIO support $linux_aio" echo "ATTR/XATTR support $attr" echo "Install blobs $blobs" +echo "CET support $cet" echo "KVM support $kvm" echo "HAX support $hax" echo "HVF support $hvf" @@ -6468,6 +6492,9 @@ fi if test "$profiler" = "yes" ; then echo "CONFIG_PROFILER=y" >> $config_host_mak fi +if test "$cet" = "yes" ; then + echo "CONFIG_CET=y" >> $config_host_mak +fi if test "$slirp" != "no"; then echo "CONFIG_SLIRP=y" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak diff --git a/Makefile.target b/Makefile.target index d8048aab8f..fa143d7b4b 100644 --- a/Makefile.target +++ b/Makefile.target @@ -113,6 +113,9 @@ obj-y += exec.o obj-y += accel/ obj-$(CONFIG_TCG) += tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-gvec.o obj-$(CONFIG_TCG) += tcg/tcg-common.o tcg/optimize.o +ifeq ($(CONFIG_CET),y) +tcg/tcg.o-cflags := -fcf-protection=return +endif obj-$(CONFIG_TCG_INTERPRETER) += tcg/tci.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o obj-$(CONFIG_TCG) += fpu/softfloat.o diff --git a/util/Makefile.objs b/util/Makefile.objs index 0808d86a19..93a8397aae 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -39,6 +39,11 @@ util-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o util-obj-y += qemu-coroutine-sleep.o util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o coroutine-x86.o-cflags := -mno-red-zone +ifeq ($(CONFIG_CET),y) +coroutine-sigaltstack.o-cflags := -fcf-protection=branch +coroutine-ucontext.o-cflags := -fcf-protection=branch +coroutine-x86.o-cflags += -fcf-protection=branch +endif util-obj-y += buffer.o util-obj-y += timed-average.o util-obj-y += base64.o
CET requires object files to note which features are supported. The linker will merge them to the set of features that are supported by all object files. The compiler creates these notes when the -fcf-protection option is passed, but we have to blacklist some object files that only support a subset of the full CET feature set. The next patches will improve the situation so that QEMU can be built with full protection. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- configure | 27 +++++++++++++++++++++++++++ Makefile.target | 3 +++ util/Makefile.objs | 5 +++++ 3 files changed, 35 insertions(+)