* [PATCH v2 0/2] topic: meson: add more compiler hardening flags @ 2024-01-03 12:34 Daniel P. Berrangé 2024-01-03 12:34 ` [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs Daniel P. Berrangé 2024-01-03 12:34 ` [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits Daniel P. Berrangé 0 siblings, 2 replies; 8+ messages in thread From: Daniel P. Berrangé @ 2024-01-03 12:34 UTC (permalink / raw) To: qemu-devel Cc: Thomas Huth, Paolo Bonzini, Daniel P. Berrangé, Philippe Mathieu-Daudé, Marc-André Lureau This brings more compiler hardening flags to the default QEMU build process. The proposed flags have already been adopted by default in the kernel build process. At some point it is hoped that distros might enable them globally, as they've done in the past with things like _FORTIFY_SOURCE. Meanwhile they are easy things to enable in QEMU which have negligible cost and clear benefits to hardening. Considering QEMU shows no signs of stoppping the flow of guest triggerable CVEs, investing in hardening is worthwhile. See the respective commit messages for details Changed in v2: * Fix spelling of -ftrivial-auto-var-init option Daniel P. Berrangé (2): meson: mitigate against ROP exploits with -fzero-call-used-regs meson: mitigate against use of uninitialize stack for exploits meson.build | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) -- 2.43.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs 2024-01-03 12:34 [PATCH v2 0/2] topic: meson: add more compiler hardening flags Daniel P. Berrangé @ 2024-01-03 12:34 ` Daniel P. Berrangé 2024-01-09 14:54 ` Markus Armbruster 2024-01-03 12:34 ` [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits Daniel P. Berrangé 1 sibling, 1 reply; 8+ messages in thread From: Daniel P. Berrangé @ 2024-01-03 12:34 UTC (permalink / raw) To: qemu-devel Cc: Thomas Huth, Paolo Bonzini, Daniel P. Berrangé, Philippe Mathieu-Daudé, Marc-André Lureau To quote wikipedia: "Return-oriented programming (ROP) is a computer security exploit technique that allows an attacker to execute code in the presence of security defenses such as executable space protection and code signing. In this technique, an attacker gains control of the call stack to hijack program control flow and then executes carefully chosen machine instruction sequences that are already present in the machine's memory, called "gadgets". Each gadget typically ends in a return instruction and is located in a subroutine within the existing program and/or shared library code. Chained together, these gadgets allow an attacker to perform arbitrary operations on a machine employing defenses that thwart simpler attacks." QEMU is by no means perfect with an ever growing set of CVEs from flawed hardware device emulation, which could potentially be exploited using ROP techniques. Since GCC 11 there has been a compiler option that can mitigate against this exploit technique: -fzero-call-user-regs To understand it refer to these two resources: https://www.jerkeby.se/newsletter/posts/rop-reduction-zero-call-user-regs/ https://gcc.gnu.org/pipermail/gcc-patches/2020-August/552262.html I used two programs to scan qemu-system-x86_64 for ROP gadgets: https://github.com/0vercl0k/rp https://github.com/JonathanSalwan/ROPgadget When asked to find 8 byte gadgets, the 'rp' tool reports: A total of 440278 gadgets found. You decided to keep only the unique ones, 156143 unique gadgets found. While the ROPgadget tool reports: Unique gadgets found: 353122 With the --ropchain argument, the latter attempts to use the found gadgets to product a chain that can execute arbitrary syscalls. With current QEMU it succeeds in this task, which is an undesirable situation. With QEMU modified to use -fzero-call-user-regs=used-gpr the 'rp' tool reports A total of 528991 gadgets found. You decided to keep only the unique ones, 121128 unique gadgets found. This is 22% fewer unique gadgets While the ROPgadget tool reports: Unique gadgets found: 328605 This is 7% fewer unique gadgets. Crucially though, despite this more modest reduction, the ROPgadget tool is no longer able to identify a chain of gadgets for executing arbitrary syscalls. It fails at the very first step, unable to find gadgets for populating registers for a future syscall. Having said that, more advanced tools do still manage to put together a viable ROP chain. Also this only takes into account QEMU code. QEMU links to many 3rd party shared libraries and ideally all of them would be compiled with this same hardening. That becomes a distro policy question though. In terms of performance impact, TCG was used as an evaluation test case. We're not interested in protecting TCG since it isn't designed to provide a security barrier, but it is performance sensitive code, so useful as a guide to how other areas of QEMU might be impacted. With the -fzero-call-user-regs=used-gpr argument present, using the real world test of booting a linux kernel and having init immediately poweroff, there is a ~1% slow down in performance under TCG. The QEMU binary size also grows by approximately 1%. By comparison, using the more aggressive -fzero-call-user-regs=all, results in a slowdown of over 25% in TCG, which is clearly not an acceptable impact, and a binary size increase of 5%. Considering that 'used-gpr' succesfully stopped ROPgadget assembling a chain, this more targetted protection is a justifiable hardening / performance tradeoff. Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- meson.build | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/meson.build b/meson.build index 6c77d9687d..eaa20d241d 100644 --- a/meson.build +++ b/meson.build @@ -433,6 +433,17 @@ if get_option('fuzzing') endif endif +# Check further flags that make QEMU more robust against malicious parties + +hardening_flags = [ + # Zero out registers used during a function call + # upon its return. This makes it harder to assemble + # ROP gadgets into something usable + '-fzero-call-used-regs=used-gpr', +] + +qemu_common_flags += cc.get_supported_arguments(hardening_flags) + add_global_arguments(qemu_common_flags, native: false, language: all_languages) add_global_link_arguments(qemu_ldflags, native: false, language: all_languages) -- 2.43.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs 2024-01-03 12:34 ` [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs Daniel P. Berrangé @ 2024-01-09 14:54 ` Markus Armbruster 2024-01-09 15:12 ` Daniel P. Berrangé 0 siblings, 1 reply; 8+ messages in thread From: Markus Armbruster @ 2024-01-09 14:54 UTC (permalink / raw) To: Daniel P. Berrangé Cc: qemu-devel, Thomas Huth, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau Daniel P. Berrangé <berrange@redhat.com> writes: > To quote wikipedia: > > "Return-oriented programming (ROP) is a computer security exploit > technique that allows an attacker to execute code in the presence > of security defenses such as executable space protection and code > signing. > > In this technique, an attacker gains control of the call stack to > hijack program control flow and then executes carefully chosen > machine instruction sequences that are already present in the > machine's memory, called "gadgets". Each gadget typically ends in > a return instruction and is located in a subroutine within the > existing program and/or shared library code. Chained together, > these gadgets allow an attacker to perform arbitrary operations > on a machine employing defenses that thwart simpler attacks." > > QEMU is by no means perfect with an ever growing set of CVEs from > flawed hardware device emulation, which could potentially be > exploited using ROP techniques. > > Since GCC 11 there has been a compiler option that can mitigate > against this exploit technique: > > -fzero-call-user-regs > > To understand it refer to these two resources: > > https://www.jerkeby.se/newsletter/posts/rop-reduction-zero-call-user-regs/ > https://gcc.gnu.org/pipermail/gcc-patches/2020-August/552262.html > > I used two programs to scan qemu-system-x86_64 for ROP gadgets: > > https://github.com/0vercl0k/rp > https://github.com/JonathanSalwan/ROPgadget > > When asked to find 8 byte gadgets, the 'rp' tool reports: > > A total of 440278 gadgets found. > You decided to keep only the unique ones, 156143 unique gadgets found. > > While the ROPgadget tool reports: > > Unique gadgets found: 353122 > > With the --ropchain argument, the latter attempts to use the found > gadgets to product a chain that can execute arbitrary syscalls. With > current QEMU it succeeds in this task, which is an undesirable > situation. > > With QEMU modified to use -fzero-call-user-regs=used-gpr the 'rp' tool > reports > > A total of 528991 gadgets found. > You decided to keep only the unique ones, 121128 unique gadgets found. > > This is 22% fewer unique gadgets > > While the ROPgadget tool reports: > > Unique gadgets found: 328605 > > This is 7% fewer unique gadgets. Crucially though, despite this more > modest reduction, the ROPgadget tool is no longer able to identify a > chain of gadgets for executing arbitrary syscalls. It fails at the > very first step, unable to find gadgets for populating registers for > a future syscall. Having said that, more advanced tools do still > manage to put together a viable ROP chain. > > Also this only takes into account QEMU code. QEMU links to many 3rd > party shared libraries and ideally all of them would be compiled with > this same hardening. That becomes a distro policy question though. > > In terms of performance impact, TCG was used as an evaluation test > case. We're not interested in protecting TCG since it isn't designed > to provide a security barrier, but it is performance sensitive code, > so useful as a guide to how other areas of QEMU might be impacted. > With the -fzero-call-user-regs=used-gpr argument present, using the > real world test of booting a linux kernel and having init immediately > poweroff, there is a ~1% slow down in performance under TCG. The QEMU > binary size also grows by approximately 1%. > > By comparison, using the more aggressive -fzero-call-user-regs=all, > results in a slowdown of over 25% in TCG, which is clearly not an > acceptable impact, and a binary size increase of 5%. > > Considering that 'used-gpr' succesfully stopped ROPgadget assembling > a chain, this more targetted protection is a justifiable hardening > / performance tradeoff. Have you also considered 'used-arg'? > Reviewed-by: Thomas Huth <thuth@redhat.com> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> > --- > meson.build | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/meson.build b/meson.build > index 6c77d9687d..eaa20d241d 100644 > --- a/meson.build > +++ b/meson.build > @@ -433,6 +433,17 @@ if get_option('fuzzing') > endif > endif > > +# Check further flags that make QEMU more robust against malicious parties > + > +hardening_flags = [ > + # Zero out registers used during a function call > + # upon its return. This makes it harder to assemble > + # ROP gadgets into something usable > + '-fzero-call-used-regs=used-gpr', > +] > + > +qemu_common_flags += cc.get_supported_arguments(hardening_flags) > + > add_global_arguments(qemu_common_flags, native: false, language: all_languages) > add_global_link_arguments(qemu_ldflags, native: false, language: all_languages) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs 2024-01-09 14:54 ` Markus Armbruster @ 2024-01-09 15:12 ` Daniel P. Berrangé 2024-01-11 12:03 ` Markus Armbruster 0 siblings, 1 reply; 8+ messages in thread From: Daniel P. Berrangé @ 2024-01-09 15:12 UTC (permalink / raw) To: Markus Armbruster Cc: qemu-devel, Thomas Huth, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau On Tue, Jan 09, 2024 at 03:54:07PM +0100, Markus Armbruster wrote: > Daniel P. Berrangé <berrange@redhat.com> writes: > > > To quote wikipedia: > > > > "Return-oriented programming (ROP) is a computer security exploit > > technique that allows an attacker to execute code in the presence > > of security defenses such as executable space protection and code > > signing. > > > > In this technique, an attacker gains control of the call stack to > > hijack program control flow and then executes carefully chosen > > machine instruction sequences that are already present in the > > machine's memory, called "gadgets". Each gadget typically ends in > > a return instruction and is located in a subroutine within the > > existing program and/or shared library code. Chained together, > > these gadgets allow an attacker to perform arbitrary operations > > on a machine employing defenses that thwart simpler attacks." > > > > QEMU is by no means perfect with an ever growing set of CVEs from > > flawed hardware device emulation, which could potentially be > > exploited using ROP techniques. > > > > Since GCC 11 there has been a compiler option that can mitigate > > against this exploit technique: > > > > -fzero-call-user-regs > > > > To understand it refer to these two resources: > > > > https://www.jerkeby.se/newsletter/posts/rop-reduction-zero-call-user-regs/ > > https://gcc.gnu.org/pipermail/gcc-patches/2020-August/552262.html > > > > I used two programs to scan qemu-system-x86_64 for ROP gadgets: > > > > https://github.com/0vercl0k/rp > > https://github.com/JonathanSalwan/ROPgadget > > > > When asked to find 8 byte gadgets, the 'rp' tool reports: > > > > A total of 440278 gadgets found. > > You decided to keep only the unique ones, 156143 unique gadgets found. > > > > While the ROPgadget tool reports: > > > > Unique gadgets found: 353122 > > > > With the --ropchain argument, the latter attempts to use the found > > gadgets to product a chain that can execute arbitrary syscalls. With > > current QEMU it succeeds in this task, which is an undesirable > > situation. > > > > With QEMU modified to use -fzero-call-user-regs=used-gpr the 'rp' tool > > reports > > > > A total of 528991 gadgets found. > > You decided to keep only the unique ones, 121128 unique gadgets found. > > > > This is 22% fewer unique gadgets > > > > While the ROPgadget tool reports: > > > > Unique gadgets found: 328605 > > > > This is 7% fewer unique gadgets. Crucially though, despite this more > > modest reduction, the ROPgadget tool is no longer able to identify a > > chain of gadgets for executing arbitrary syscalls. It fails at the > > very first step, unable to find gadgets for populating registers for > > a future syscall. Having said that, more advanced tools do still > > manage to put together a viable ROP chain. > > > > Also this only takes into account QEMU code. QEMU links to many 3rd > > party shared libraries and ideally all of them would be compiled with > > this same hardening. That becomes a distro policy question though. > > > > In terms of performance impact, TCG was used as an evaluation test > > case. We're not interested in protecting TCG since it isn't designed > > to provide a security barrier, but it is performance sensitive code, > > so useful as a guide to how other areas of QEMU might be impacted. > > With the -fzero-call-user-regs=used-gpr argument present, using the > > real world test of booting a linux kernel and having init immediately > > poweroff, there is a ~1% slow down in performance under TCG. The QEMU > > binary size also grows by approximately 1%. > > > > By comparison, using the more aggressive -fzero-call-user-regs=all, > > results in a slowdown of over 25% in TCG, which is clearly not an > > acceptable impact, and a binary size increase of 5%. > > > > Considering that 'used-gpr' succesfully stopped ROPgadget assembling > > a chain, this more targetted protection is a justifiable hardening > > / performance tradeoff. > > Have you also considered 'used-arg'? No, not in any detail. I was mostly guided by the writeup here: https://www.jerkeby.se/newsletter/posts/rop-reduction-zero-call-user-regs/ which indicates Linux chose 'used-gpr'. I figured if Kees Cook decide that was a good tradeoff for Linux, we might as well follow it. 'used-gpr' will target any general purpose registers that are used in a method. 'used-arg' will taget any registers used for parameters. IIUC, this makes 'used-gpr' be a slightly stronger protection as it covers register usage even for things which aren't args. > > > Reviewed-by: Thomas Huth <thuth@redhat.com> > > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> > > --- > > meson.build | 11 +++++++++++ > > 1 file changed, 11 insertions(+) > > > > diff --git a/meson.build b/meson.build > > index 6c77d9687d..eaa20d241d 100644 > > --- a/meson.build > > +++ b/meson.build > > @@ -433,6 +433,17 @@ if get_option('fuzzing') > > endif > > endif > > > > +# Check further flags that make QEMU more robust against malicious parties > > + > > +hardening_flags = [ > > + # Zero out registers used during a function call > > + # upon its return. This makes it harder to assemble > > + # ROP gadgets into something usable > > + '-fzero-call-used-regs=used-gpr', > > +] > > + > > +qemu_common_flags += cc.get_supported_arguments(hardening_flags) > > + > > add_global_arguments(qemu_common_flags, native: false, language: all_languages) > > add_global_link_arguments(qemu_ldflags, native: false, language: all_languages) > With 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 :| ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs 2024-01-09 15:12 ` Daniel P. Berrangé @ 2024-01-11 12:03 ` Markus Armbruster 0 siblings, 0 replies; 8+ messages in thread From: Markus Armbruster @ 2024-01-11 12:03 UTC (permalink / raw) To: Daniel P. Berrangé Cc: qemu-devel, Thomas Huth, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau Daniel P. Berrangé <berrange@redhat.com> writes: > On Tue, Jan 09, 2024 at 03:54:07PM +0100, Markus Armbruster wrote: >> Daniel P. Berrangé <berrange@redhat.com> writes: >> >> > To quote wikipedia: >> > >> > "Return-oriented programming (ROP) is a computer security exploit >> > technique that allows an attacker to execute code in the presence >> > of security defenses such as executable space protection and code >> > signing. >> > >> > In this technique, an attacker gains control of the call stack to >> > hijack program control flow and then executes carefully chosen >> > machine instruction sequences that are already present in the >> > machine's memory, called "gadgets". Each gadget typically ends in >> > a return instruction and is located in a subroutine within the >> > existing program and/or shared library code. Chained together, >> > these gadgets allow an attacker to perform arbitrary operations >> > on a machine employing defenses that thwart simpler attacks." >> > >> > QEMU is by no means perfect with an ever growing set of CVEs from >> > flawed hardware device emulation, which could potentially be >> > exploited using ROP techniques. >> > >> > Since GCC 11 there has been a compiler option that can mitigate >> > against this exploit technique: >> > >> > -fzero-call-user-regs >> > >> > To understand it refer to these two resources: >> > >> > https://www.jerkeby.se/newsletter/posts/rop-reduction-zero-call-user-regs/ >> > https://gcc.gnu.org/pipermail/gcc-patches/2020-August/552262.html >> > >> > I used two programs to scan qemu-system-x86_64 for ROP gadgets: >> > >> > https://github.com/0vercl0k/rp >> > https://github.com/JonathanSalwan/ROPgadget >> > >> > When asked to find 8 byte gadgets, the 'rp' tool reports: >> > >> > A total of 440278 gadgets found. >> > You decided to keep only the unique ones, 156143 unique gadgets found. >> > >> > While the ROPgadget tool reports: >> > >> > Unique gadgets found: 353122 >> > >> > With the --ropchain argument, the latter attempts to use the found >> > gadgets to product a chain that can execute arbitrary syscalls. With >> > current QEMU it succeeds in this task, which is an undesirable >> > situation. >> > >> > With QEMU modified to use -fzero-call-user-regs=used-gpr the 'rp' tool >> > reports >> > >> > A total of 528991 gadgets found. >> > You decided to keep only the unique ones, 121128 unique gadgets found. >> > >> > This is 22% fewer unique gadgets >> > >> > While the ROPgadget tool reports: >> > >> > Unique gadgets found: 328605 >> > >> > This is 7% fewer unique gadgets. Crucially though, despite this more >> > modest reduction, the ROPgadget tool is no longer able to identify a >> > chain of gadgets for executing arbitrary syscalls. It fails at the >> > very first step, unable to find gadgets for populating registers for >> > a future syscall. Having said that, more advanced tools do still >> > manage to put together a viable ROP chain. >> > >> > Also this only takes into account QEMU code. QEMU links to many 3rd >> > party shared libraries and ideally all of them would be compiled with >> > this same hardening. That becomes a distro policy question though. >> > >> > In terms of performance impact, TCG was used as an evaluation test >> > case. We're not interested in protecting TCG since it isn't designed >> > to provide a security barrier, but it is performance sensitive code, >> > so useful as a guide to how other areas of QEMU might be impacted. >> > With the -fzero-call-user-regs=used-gpr argument present, using the >> > real world test of booting a linux kernel and having init immediately >> > poweroff, there is a ~1% slow down in performance under TCG. The QEMU >> > binary size also grows by approximately 1%. >> > >> > By comparison, using the more aggressive -fzero-call-user-regs=all, >> > results in a slowdown of over 25% in TCG, which is clearly not an >> > acceptable impact, and a binary size increase of 5%. >> > >> > Considering that 'used-gpr' succesfully stopped ROPgadget assembling >> > a chain, this more targetted protection is a justifiable hardening >> > / performance tradeoff. >> >> Have you also considered 'used-arg'? > > No, not in any detail. I was mostly guided by the writeup here: > > https://www.jerkeby.se/newsletter/posts/rop-reduction-zero-call-user-regs/ > > which indicates Linux chose 'used-gpr'. I figured if Kees Cook > decide that was a good tradeoff for Linux, we might as well follow > it. Makes sense. > 'used-gpr' will target any general purpose registers > that are used in a method. 'used-arg' will taget any registers > used for parameters. IIUC, this makes 'used-gpr' be a slightly > stronger protection as it covers register usage even for things > which aren't args. The docs lead me to suspect it will *not* cover non-gpr registers that are used for passing arguments. Requires a calling convention that can pass arguments in non-gpr registers, such as floating-point and vector registers. I figure these are less useful for exploits than gprs. Thanks! [...] ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits 2024-01-03 12:34 [PATCH v2 0/2] topic: meson: add more compiler hardening flags Daniel P. Berrangé 2024-01-03 12:34 ` [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs Daniel P. Berrangé @ 2024-01-03 12:34 ` Daniel P. Berrangé 2024-01-09 14:48 ` Markus Armbruster 1 sibling, 1 reply; 8+ messages in thread From: Daniel P. Berrangé @ 2024-01-03 12:34 UTC (permalink / raw) To: qemu-devel Cc: Thomas Huth, Paolo Bonzini, Daniel P. Berrangé, Philippe Mathieu-Daudé, Marc-André Lureau When variables are used without being initialized, there is potential to take advantage of data that was pre-existing on the stack from an earlier call, to drive an exploit. It is good practice to always initialize variables, and the compiler can warn about flaws when -Wuninitialized is present. This warning, however, is by no means foolproof with its output varying depending on compiler version and which optimizations are enabled. The -ftrivial-auto-var-init option can be used to tell the compiler to always initialize all variables. This increases the security and predictability of the program, closing off certain attack vectors, reducing the risk of unsafe memory disclosure. While the option takes several possible values, using 'zero' is considered to be the option that is likely to lead to semantically correct or safe behaviour[1]. eg sizes/indexes are not likely to lead to out-of-bounds accesses when initialized to zero. Pointers are less likely to point something useful if initialized to zero. Even with -ftrivial-auto-var-init=zero set, GCC will still issue warnings with -Wuninitialized if it discovers a problem, so we are not loosing diagnostics for developers, just hardening runtime behaviour and making QEMU behave more predictably in case of hitting bad codepaths. [1] https://lists.llvm.org/pipermail/cfe-dev/2020-April/065221.html Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- meson.build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/meson.build b/meson.build index eaa20d241d..efc1b4dd14 100644 --- a/meson.build +++ b/meson.build @@ -440,6 +440,11 @@ hardening_flags = [ # upon its return. This makes it harder to assemble # ROP gadgets into something usable '-fzero-call-used-regs=used-gpr', + + # Initialize all stack variables to zero. This makes + # it harder to take advantage of uninitialized stack + # data to drive exploits + '-ftrivial-auto-var-init=zero', ] qemu_common_flags += cc.get_supported_arguments(hardening_flags) -- 2.43.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits 2024-01-03 12:34 ` [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits Daniel P. Berrangé @ 2024-01-09 14:48 ` Markus Armbruster 2024-01-09 14:53 ` Daniel P. Berrangé 0 siblings, 1 reply; 8+ messages in thread From: Markus Armbruster @ 2024-01-09 14:48 UTC (permalink / raw) To: Daniel P. Berrangé Cc: qemu-devel, Thomas Huth, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau Daniel P. Berrangé <berrange@redhat.com> writes: > When variables are used without being initialized, there is potential > to take advantage of data that was pre-existing on the stack from an > earlier call, to drive an exploit. > > It is good practice to always initialize variables, and the compiler > can warn about flaws when -Wuninitialized is present. This warning, > however, is by no means foolproof with its output varying depending > on compiler version and which optimizations are enabled. > > The -ftrivial-auto-var-init option can be used to tell the compiler > to always initialize all variables. This increases the security and > predictability of the program, closing off certain attack vectors, > reducing the risk of unsafe memory disclosure. > > While the option takes several possible values, using 'zero' is > considered to be the option that is likely to lead to semantically > correct or safe behaviour[1]. eg sizes/indexes are not likely to > lead to out-of-bounds accesses when initialized to zero. Pointers > are less likely to point something useful if initialized to zero. > > Even with -ftrivial-auto-var-init=zero set, GCC will still issue > warnings with -Wuninitialized if it discovers a problem, so we are > not loosing diagnostics for developers, just hardening runtime > behaviour and making QEMU behave more predictably in case of hitting > bad codepaths. > > [1] https://lists.llvm.org/pipermail/cfe-dev/2020-April/065221.html > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> > --- > meson.build | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/meson.build b/meson.build > index eaa20d241d..efc1b4dd14 100644 > --- a/meson.build > +++ b/meson.build > @@ -440,6 +440,11 @@ hardening_flags = [ > # upon its return. This makes it harder to assemble > # ROP gadgets into something usable > '-fzero-call-used-regs=used-gpr', > + > + # Initialize all stack variables to zero. This makes > + # it harder to take advantage of uninitialized stack > + # data to drive exploits > + '-ftrivial-auto-var-init=zero', > ] > > qemu_common_flags += cc.get_supported_arguments(hardening_flags) Have you tried to throw in -Wtrivial-auto-var-init? Documentation, for your convenience: ‘-Wtrivial-auto-var-init’ Warn when ‘-ftrivial-auto-var-init’ cannot initialize the automatic variable. A common situation is an automatic variable that is declared between the controlling expression and the first case label of a ‘switch’ statement. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits 2024-01-09 14:48 ` Markus Armbruster @ 2024-01-09 14:53 ` Daniel P. Berrangé 0 siblings, 0 replies; 8+ messages in thread From: Daniel P. Berrangé @ 2024-01-09 14:53 UTC (permalink / raw) To: Markus Armbruster Cc: qemu-devel, Thomas Huth, Paolo Bonzini, Philippe Mathieu-Daudé, Marc-André Lureau On Tue, Jan 09, 2024 at 03:48:42PM +0100, Markus Armbruster wrote: > Daniel P. Berrangé <berrange@redhat.com> writes: > > > When variables are used without being initialized, there is potential > > to take advantage of data that was pre-existing on the stack from an > > earlier call, to drive an exploit. > > > > It is good practice to always initialize variables, and the compiler > > can warn about flaws when -Wuninitialized is present. This warning, > > however, is by no means foolproof with its output varying depending > > on compiler version and which optimizations are enabled. > > > > The -ftrivial-auto-var-init option can be used to tell the compiler > > to always initialize all variables. This increases the security and > > predictability of the program, closing off certain attack vectors, > > reducing the risk of unsafe memory disclosure. > > > > While the option takes several possible values, using 'zero' is > > considered to be the option that is likely to lead to semantically > > correct or safe behaviour[1]. eg sizes/indexes are not likely to > > lead to out-of-bounds accesses when initialized to zero. Pointers > > are less likely to point something useful if initialized to zero. > > > > Even with -ftrivial-auto-var-init=zero set, GCC will still issue > > warnings with -Wuninitialized if it discovers a problem, so we are > > not loosing diagnostics for developers, just hardening runtime > > behaviour and making QEMU behave more predictably in case of hitting > > bad codepaths. > > > > [1] https://lists.llvm.org/pipermail/cfe-dev/2020-April/065221.html > > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> > > --- > > meson.build | 5 +++++ > > 1 file changed, 5 insertions(+) > > > > diff --git a/meson.build b/meson.build > > index eaa20d241d..efc1b4dd14 100644 > > --- a/meson.build > > +++ b/meson.build > > @@ -440,6 +440,11 @@ hardening_flags = [ > > # upon its return. This makes it harder to assemble > > # ROP gadgets into something usable > > '-fzero-call-used-regs=used-gpr', > > + > > + # Initialize all stack variables to zero. This makes > > + # it harder to take advantage of uninitialized stack > > + # data to drive exploits > > + '-ftrivial-auto-var-init=zero', > > ] > > > > qemu_common_flags += cc.get_supported_arguments(hardening_flags) > > Have you tried to throw in -Wtrivial-auto-var-init? > > Documentation, for your convenience: > > ‘-Wtrivial-auto-var-init’ > Warn when ‘-ftrivial-auto-var-init’ cannot initialize the automatic > variable. A common situation is an automatic variable that is > declared between the controlling expression and the first case > label of a ‘switch’ statement. No, I didn't notice that warning. I'll have a look if it reoprts any problems, but not optimistic since we probably have such code patterns. With 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 :| ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-01-11 12:04 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-01-03 12:34 [PATCH v2 0/2] topic: meson: add more compiler hardening flags Daniel P. Berrangé 2024-01-03 12:34 ` [PATCH v2 1/2] meson: mitigate against ROP exploits with -fzero-call-used-regs Daniel P. Berrangé 2024-01-09 14:54 ` Markus Armbruster 2024-01-09 15:12 ` Daniel P. Berrangé 2024-01-11 12:03 ` Markus Armbruster 2024-01-03 12:34 ` [PATCH v2 2/2] meson: mitigate against use of uninitialize stack for exploits Daniel P. Berrangé 2024-01-09 14:48 ` Markus Armbruster 2024-01-09 14:53 ` Daniel P. Berrangé
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).