[PATCH v2 0/4] Add support for SafeStack

Daniele Buono posted 4 patches 3 years, 11 months ago
Test docker-mingw@fedora passed
Test checkpatch passed
Test asan passed
Test docker-quick@centos7 passed
Test FreeBSD passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20200529205122.714-1-dbuono@linux.vnet.ibm.com
Maintainers: Stefan Hajnoczi <stefanha@redhat.com>, Kevin Wolf <kwolf@redhat.com>
configure                    | 73 ++++++++++++++++++++++++++++++++++++
include/qemu/coroutine_int.h |  5 +++
tests/check-block.sh         | 12 +++++-
util/coroutine-sigaltstack.c |  4 ++
util/coroutine-ucontext.c    | 26 +++++++++++++
5 files changed, 119 insertions(+), 1 deletion(-)
[PATCH v2 0/4] Add support for SafeStack
Posted by Daniele Buono 3 years, 11 months ago
LLVM supports SafeStack instrumentation to protect against stack buffer
overflows, since version 3.7

From https://clang.llvm.org/docs/SafeStack.html:
"It works by separating the program stack into two distinct regions: the
safe stack and the unsafe stack. The safe stack stores return addresses,
register spills, and local variables that are always accessed in a safe
way, while the unsafe stack stores everything else. This separation
ensures that buffer overflows on the unsafe stack cannot be used to
overwrite anything on the safe stack."

Unfortunately, the use of two stack regions does not cope well with
QEMU's coroutines. The second stack region is not properly set up with
both ucontext and sigaltstack, so multiple coroutines end up sharing the
same memory area for the unsafe stack, causing undefined behaviors at
runtime (and most iochecks to fail).

This patch series fixes the implementation of the ucontext backend and
make sure that sigaltstack is never used if the compiler is applying
the SafeStack instrumentation. It also adds a configure flag to enable
SafeStack, and enables iotests when SafeStack is used.

Changes since v1:
 - CONFIG_SAFESTACK is now set up in configure, and not in the code
 - Added option for a --disable-safe-stack in configure
 - Configure checks if SafeStack is enabled by default in the compiler,
   and set the CONFIG_SAFESTACK accordingly
 - Updated some comments in the code and the commit log

NOTE: I kept configure as Patch #3. 
The reason is that the code changes will not be enabled without the
configure, making the code fully functional if only Patches #1 or #2 are
applied.
On the other hand, the configure patch will produce incorrect code if we
request SafeStack and the other patches are not applied.

Daniele Buono (4):
  coroutine: support SafeStack in ucontext backend
  coroutine: add check for SafeStack in sigaltstack
  configure: add flags to support SafeStack
  check-block: enable iotests with SafeStack

 configure                    | 73 ++++++++++++++++++++++++++++++++++++
 include/qemu/coroutine_int.h |  5 +++
 tests/check-block.sh         | 12 +++++-
 util/coroutine-sigaltstack.c |  4 ++
 util/coroutine-ucontext.c    | 26 +++++++++++++
 5 files changed, 119 insertions(+), 1 deletion(-)

-- 
2.26.2


Re: [PATCH v2 0/4] Add support for SafeStack
Posted by Daniele Buono 3 years, 10 months ago
Ping?

On 5/29/2020 4:51 PM, Daniele Buono wrote:
> LLVM supports SafeStack instrumentation to protect against stack buffer
> overflows, since version 3.7
> 
>>From https://clang.llvm.org/docs/SafeStack.html:
> "It works by separating the program stack into two distinct regions: the
> safe stack and the unsafe stack. The safe stack stores return addresses,
> register spills, and local variables that are always accessed in a safe
> way, while the unsafe stack stores everything else. This separation
> ensures that buffer overflows on the unsafe stack cannot be used to
> overwrite anything on the safe stack."
> 
> Unfortunately, the use of two stack regions does not cope well with
> QEMU's coroutines. The second stack region is not properly set up with
> both ucontext and sigaltstack, so multiple coroutines end up sharing the
> same memory area for the unsafe stack, causing undefined behaviors at
> runtime (and most iochecks to fail).
> 
> This patch series fixes the implementation of the ucontext backend and
> make sure that sigaltstack is never used if the compiler is applying
> the SafeStack instrumentation. It also adds a configure flag to enable
> SafeStack, and enables iotests when SafeStack is used.
> 
> Changes since v1:
>   - CONFIG_SAFESTACK is now set up in configure, and not in the code
>   - Added option for a --disable-safe-stack in configure
>   - Configure checks if SafeStack is enabled by default in the compiler,
>     and set the CONFIG_SAFESTACK accordingly
>   - Updated some comments in the code and the commit log
> 
> NOTE: I kept configure as Patch #3.
> The reason is that the code changes will not be enabled without the
> configure, making the code fully functional if only Patches #1 or #2 are
> applied.
> On the other hand, the configure patch will produce incorrect code if we
> request SafeStack and the other patches are not applied.
> 
> Daniele Buono (4):
>    coroutine: support SafeStack in ucontext backend
>    coroutine: add check for SafeStack in sigaltstack
>    configure: add flags to support SafeStack
>    check-block: enable iotests with SafeStack
> 
>   configure                    | 73 ++++++++++++++++++++++++++++++++++++
>   include/qemu/coroutine_int.h |  5 +++
>   tests/check-block.sh         | 12 +++++-
>   util/coroutine-sigaltstack.c |  4 ++
>   util/coroutine-ucontext.c    | 26 +++++++++++++
>   5 files changed, 119 insertions(+), 1 deletion(-)
> 

Re: [PATCH v2 0/4] Add support for SafeStack
Posted by Stefan Hajnoczi 3 years, 10 months ago
On Fri, May 29, 2020 at 04:51:18PM -0400, Daniele Buono wrote:
> LLVM supports SafeStack instrumentation to protect against stack buffer
> overflows, since version 3.7
> 
> From https://clang.llvm.org/docs/SafeStack.html:
> "It works by separating the program stack into two distinct regions: the
> safe stack and the unsafe stack. The safe stack stores return addresses,
> register spills, and local variables that are always accessed in a safe
> way, while the unsafe stack stores everything else. This separation
> ensures that buffer overflows on the unsafe stack cannot be used to
> overwrite anything on the safe stack."
> 
> Unfortunately, the use of two stack regions does not cope well with
> QEMU's coroutines. The second stack region is not properly set up with
> both ucontext and sigaltstack, so multiple coroutines end up sharing the
> same memory area for the unsafe stack, causing undefined behaviors at
> runtime (and most iochecks to fail).
> 
> This patch series fixes the implementation of the ucontext backend and
> make sure that sigaltstack is never used if the compiler is applying
> the SafeStack instrumentation. It also adds a configure flag to enable
> SafeStack, and enables iotests when SafeStack is used.
> 
> Changes since v1:
>  - CONFIG_SAFESTACK is now set up in configure, and not in the code
>  - Added option for a --disable-safe-stack in configure
>  - Configure checks if SafeStack is enabled by default in the compiler,
>    and set the CONFIG_SAFESTACK accordingly
>  - Updated some comments in the code and the commit log
> 
> NOTE: I kept configure as Patch #3. 
> The reason is that the code changes will not be enabled without the
> configure, making the code fully functional if only Patches #1 or #2 are
> applied.
> On the other hand, the configure patch will produce incorrect code if we
> request SafeStack and the other patches are not applied.
> 
> Daniele Buono (4):
>   coroutine: support SafeStack in ucontext backend
>   coroutine: add check for SafeStack in sigaltstack
>   configure: add flags to support SafeStack
>   check-block: enable iotests with SafeStack
> 
>  configure                    | 73 ++++++++++++++++++++++++++++++++++++
>  include/qemu/coroutine_int.h |  5 +++
>  tests/check-block.sh         | 12 +++++-
>  util/coroutine-sigaltstack.c |  4 ++
>  util/coroutine-ucontext.c    | 26 +++++++++++++
>  5 files changed, 119 insertions(+), 1 deletion(-)
> 
> -- 
> 2.26.2
> 
> 

Thanks, applied to my block tree:
https://github.com/stefanha/qemu/commits/block

Stefan