From nobody Tue Nov 18 09:04:41 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1608569699; cv=none; d=zohomail.com; s=zohoarc; b=ip/s3gPf3tuZBJ8SQZhZoTgsLQRWhAV2ITsETYXxxv14XOiW67NM1FBt/+0EPq0E2PjZeG4KfKXCJM94rkSG7hq9URtjt0dBau27llrdWw7Wz8QBh+37J69w6UzCs9mo5iuHqA4TQpw2egYZ+mrGEFunGVR0SArVN64yewUIE9U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1608569699; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=kJa5b37NoOOjx5BjBu3wk4ktmMHtcJ+x4xO2oRIBMmg=; b=NNGnHmQoZZ1Rh6qFQ6R1v5KU7NKZmgk335KTadI3051lSBSxfnql3f4BchWXOnWciFV5GNU0hT0OBqoQRLM+OA/6w12EqDu7Sn6x5uYdIpI6DsAUSux+Myh6Iahy39zH7RZei5C/nYj7MH1BWrJnnPkBeUinHzenOfEDAvlwEJc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1608569699338794.5558337876049; Mon, 21 Dec 2020 08:54:59 -0800 (PST) Received: from localhost ([::1]:38034 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1krMjp-0003qj-Qu for importer@patchew.org; Mon, 21 Dec 2020 10:04:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:42286) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1krMR6-0004pE-RW for qemu-devel@nongnu.org; Mon, 21 Dec 2020 09:45:22 -0500 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]:37449) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1krMQu-0007jK-1z for qemu-devel@nongnu.org; Mon, 21 Dec 2020 09:45:13 -0500 Received: by mail-wr1-x433.google.com with SMTP id i9so11318491wrc.4 for ; Mon, 21 Dec 2020 06:45:07 -0800 (PST) Received: from avogadro.lan ([2001:b07:6468:f312:c8dd:75d4:99ab:290a]) by smtp.gmail.com with ESMTPSA id l5sm27439627wrv.44.2020.12.21.06.45.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Dec 2020 06:45:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kJa5b37NoOOjx5BjBu3wk4ktmMHtcJ+x4xO2oRIBMmg=; b=maPSh4h99CFqTPG/1Kl4q/wwdH+JsoVbG3MU5JMg6QLUB3I+ql3w21ILgWM8kyxDyr 9eUhtK7LvZdR7FPhdrZiPPaujYmXJhfJWJd9TrCOcaeeqB19T+72SO7H+bOeTi0pQq02 q0L2DKLPNAMxVeIN7lL/QhsXn1wrkwmZw5gjfmgrfrcdJ0rNJJzYNH6+OyK0FjD/GGFf NI2T4PpPdmlnRiF5YwrW5wy2g5z2B/JtY+7j/ELiM0dfAUDWRAUzxXk73MaJoAyPZ4pP xCyjsZChe/1pcxuQq+SG4qWdVvd23CZV0r+7gUF03JSCl0FIs+vvQy2hjlPyHtSeIZSg t5tA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=kJa5b37NoOOjx5BjBu3wk4ktmMHtcJ+x4xO2oRIBMmg=; b=FwZ6knX114nJBhj24JewFj2WrlYTQbuLeGJJnHpy76HY8li1uDU5Kxeb5Wv9U5yUq2 sgr6cI6oqd4LNaapsycPzh/DWExa8l7GeWaGQC2WOSZwCM9uocKMSC8G4vBm+yTkr5f6 IKTrOq4lEm6Jz3yCcZoXo7nItX2eo0ZkzmMxIrWo0pdZLLVIjMGB7D4o8S26Vrec2B0p Cn2cgd2JIg9i8G2FhhKwde9woHALG12nZqYNhnAedqrPhlst6YinsZxlxtpgAP3RgE0L ILAnbUN60nKzUYHq30fUhHNqhYtky7fj0r0jj4k+BE7g5shbLfIy0wWuxobWQCN3W+Yo 4rkw== X-Gm-Message-State: AOAM531tljx3RAXfpNKj0CwohDdtWpGeqYBDKNM9echpowJCdDMHxq5b YaUTsaHl1jsamqb7NepMAUZQPSXN0jI= X-Google-Smtp-Source: ABdhPJzAmeg4aUZe5u5YjwgVIliOz0FirijPdHYBvUcujy3+9jaMarxaKkOhmo2a22u8z9vmLba+aQ== X-Received: by 2002:adf:f891:: with SMTP id u17mr19249942wrp.253.1608561906240; Mon, 21 Dec 2020 06:45:06 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 19/55] configure,meson: support Control-Flow Integrity Date: Mon, 21 Dec 2020 15:44:11 +0100 Message-Id: <20201221144447.26161-20-pbonzini@redhat.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201221144447.26161-1-pbonzini@redhat.com> References: <20201221144447.26161-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::433; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x433.google.com X-Spam_score_int: 5 X-Spam_score: 0.5 X-Spam_bar: / X-Spam_report: (0.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.25, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, LONGWORDS=2.035, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniele Buono Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" From: Daniele Buono This patch adds a flag to enable/disable control flow integrity checks on indirect function calls. This feature only allows indirect function calls at runtime to functions with compatible signatures. This feature is only provided by LLVM/Clang, and depends on link-time optimization which is currently supported only with LLVM/Clang >=3D 6.0 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. All the checks are performed in meson.build. configure is only used to forward the flags to meson Signed-off-by: Daniele Buono Message-Id: <20201204230615.2392-5-dbuono@linux.vnet.ibm.com> Signed-off-by: Paolo Bonzini --- configure | 22 ++++++++++++++++++++-- meson.build | 44 ++++++++++++++++++++++++++++++++++++++++++++ meson_options.txt | 4 ++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 55e77bf289..f470cdbe50 100755 --- a/configure +++ b/configure @@ -411,6 +411,8 @@ coroutine=3D"" coroutine_pool=3D"$default_feature" debug_stack_usage=3D"no" crypto_afalg=3D"no" +cfi=3D"false" +cfi_debug=3D"false" seccomp=3D"$default_feature" glusterfs=3D"$default_feature" glusterfs_xlator_opt=3D"no" @@ -1195,6 +1197,16 @@ for opt do ;; --disable-safe-stack) safe_stack=3D"no" ;; + --enable-cfi) + cfi=3D"true"; + lto=3D"true"; + ;; + --disable-cfi) cfi=3D"false" + ;; + --enable-cfi-debug) cfi_debug=3D"true" + ;; + --disable-cfi-debug) cfi_debug=3D"false" + ;; --disable-curses) curses=3D"disabled" ;; --enable-curses) curses=3D"enabled" @@ -1788,7 +1800,13 @@ disabled with --disable-FEATURE, default is enabled = if available sparse sparse checker safe-stack SafeStack Stack Smash Protection. Depends on clang/llvm >=3D 3.7 and requires coroutine backend ucont= ext. - + cfi Enable Control-Flow Integrity for indirect function call= s. + In case of a cfi violation, QEMU is terminated with SIGI= LL + Depends on lto and is incompatible with modules + Automatically enables Link-Time Optimization (lto) + cfi-debug In case of a cfi violation, a message containing the lin= e that + triggered the error is written to stderr. After the erro= r, + QEMU is still terminated with SIGILL gnutls GNUTLS cryptography support nettle nettle cryptography support gcrypt libgcrypt cryptography support @@ -6970,7 +6988,7 @@ NINJA=3D$ninja $meson setup \ -Db_pie=3D$(if test "$pie" =3D yes; then echo true; else echo fals= e; fi) \ ${staticpic:+-Db_staticpic=3D$staticpic} \ -Db_coverage=3D$(if test "$gcov" =3D yes; then echo true; else ech= o false; fi) \ - -Db_lto=3D$lto \ + -Db_lto=3D$lto -Dcfi=3D$cfi -Dcfi_debug=3D$cfi_debug \ -Dmalloc=3D$malloc -Dmalloc_trim=3D$malloc_trim -Dsparse=3D$sparse= \ -Dkvm=3D$kvm -Dhax=3D$hax -Dwhpx=3D$whpx -Dhvf=3D$hvf \ -Dxen=3D$xen -Dxen_pci_passthrough=3D$xen_pci_passthrough -Dtcg=3D= $tcg \ diff --git a/meson.build b/meson.build index d05d880114..94ef023ad1 100644 --- a/meson.build +++ b/meson.build @@ -773,6 +773,7 @@ elif get_option('vhost_user_blk_server').disabled() or = not have_system have_vhost_user_blk_server =3D false endif =20 + if get_option('fuse').disabled() and get_option('fuse_lseek').enabled() error('Cannot enable fuse-lseek while fuse is disabled') endif @@ -795,6 +796,46 @@ if not get_option('fuse_lseek').disabled() endif endif =20 +if get_option('cfi') + cfi_flags=3D[] + # Check for dependency on LTO + if not get_option('b_lto') + error('Selected Control-Flow Integrity but LTO is disabled') + endif + if config_host.has_key('CONFIG_MODULES') + error('Selected Control-Flow Integrity is not compatible with modules') + endif + # Check for cfi flags. CFI requires LTO so we can't use + # get_supported_arguments, but need a more complex "compiles" which allo= ws + # custom arguments + if cc.compiles('int main () { return 0; }', name: '-fsanitize=3Dcfi-ical= l', + args: ['-flto', '-fsanitize=3Dcfi-icall'] ) + cfi_flags +=3D '-fsanitize=3Dcfi-icall' + else + error('-fsanitize=3Dcfi-icall is not supported by the compiler') + endif + if cc.compiles('int main () { return 0; }', + name: '-fsanitize-cfi-icall-generalize-pointers', + args: ['-flto', '-fsanitize=3Dcfi-icall', + '-fsanitize-cfi-icall-generalize-pointers'] ) + cfi_flags +=3D '-fsanitize-cfi-icall-generalize-pointers' + else + error('-fsanitize-cfi-icall-generalize-pointers is not supported by th= e compiler') + endif + if get_option('cfi_debug') + if cc.compiles('int main () { return 0; }', + name: '-fno-sanitize-trap=3Dcfi-icall', + args: ['-flto', '-fsanitize=3Dcfi-icall', + '-fno-sanitize-trap=3Dcfi-icall'] ) + cfi_flags +=3D '-fno-sanitize-trap=3Dcfi-icall' + else + error('-fno-sanitize-trap=3Dcfi-icall is not supported by the compil= er') + endif + endif + add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', '= objc']) + add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cp= p', 'objc']) +endif + ################# # config-host.h # ################# @@ -831,6 +872,7 @@ config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_t= rim) config_host_data.set('CONFIG_STATX', has_statx) config_host_data.set('CONFIG_FUSE', fuse.found()) config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) +config_host_data.set('CONFIG_CFI', get_option('cfi')) config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version(= ))) config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('= .')[0]) config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('= .')[1]) @@ -2195,6 +2237,8 @@ if targetos =3D=3D 'windows' summary_info +=3D {'QGA MSI support': config_host.has_key('CONFIG_QGA_= MSI')} endif summary_info +=3D {'seccomp support': config_host.has_key('CONFIG_SECCOM= P')} +summary_info +=3D {'CFI support': get_option('cfi')} +summary_info +=3D {'CFI debug support': get_option('cfi_debug')} summary_info +=3D {'coroutine backend': config_host['CONFIG_COROUTINE_BACK= END']} summary_info +=3D {'coroutine pool': config_host['CONFIG_COROUTINE_POOL= '] =3D=3D '1'} summary_info +=3D {'debug stack usage': config_host.has_key('CONFIG_DEBUG_= STACK_USAGE')} diff --git a/meson_options.txt b/meson_options.txt index f8f053b5c8..242e0769fb 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -35,6 +35,10 @@ option('xen_pci_passthrough', type: 'feature', value: 'a= uto', description: 'Xen PCI passthrough support') option('tcg', type: 'feature', value: 'auto', description: 'TCG support') +option('cfi', type: 'boolean', value: 'false', + description: 'Control-Flow Integrity (CFI)') +option('cfi_debug', type: 'boolean', value: 'false', + description: 'Verbose errors in case of CFI violation') =20 option('cocoa', type : 'feature', value : 'auto', description: 'Cocoa user interface (macOS only)') --=20 2.29.2