Skip to content

Commit 87fb952

Browse files
committed
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Pull request # gpg: Signature made Wed 24 Jun 2020 11:01:57 BST # gpg: using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <[email protected]>" [full] # gpg: aka "Stefan Hajnoczi <[email protected]>" [full] # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/block-pull-request: block/nvme: support nested aio_poll() block/nvme: keep BDRVNVMeState pointer in NVMeQueuePair block/nvme: clarify that free_req_queue is protected by q->lock block/nvme: switch to a NVMeRequest freelist block/nvme: don't access CQE after moving cq.head block/nvme: drop tautologous assertion block/nvme: poll queues without q->lock check-block: enable iotests with SafeStack configure: add flags to support SafeStack coroutine: add check for SafeStack in sigaltstack coroutine: support SafeStack in ucontext backend minikconf: explicitly set encoding to UTF-8 Signed-off-by: Peter Maydell <[email protected]>
2 parents 10f7ffa + 7838c67 commit 87fb952

File tree

8 files changed

+283
-65
lines changed

8 files changed

+283
-65
lines changed

block/nvme.c

Lines changed: 158 additions & 60 deletions
Large diffs are not rendered by default.

block/trace-events

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ nvme_kick(void *s, int queue) "s %p queue %d"
158158
nvme_dma_flush_queue_wait(void *s) "s %p"
159159
nvme_error(int cmd_specific, int sq_head, int sqid, int cid, int status) "cmd_specific %d sq_head %d sqid %d cid %d status 0x%x"
160160
nvme_process_completion(void *s, int index, int inflight) "s %p queue %d inflight %d"
161-
nvme_process_completion_queue_busy(void *s, int index) "s %p queue %d"
161+
nvme_process_completion_queue_plugged(void *s, int index) "s %p queue %d"
162162
nvme_complete_command(void *s, int index, int cid) "s %p queue %d cid %d"
163163
nvme_submit_command(void *s, int index, int cid) "s %p queue %d cid %d"
164164
nvme_submit_command_raw(int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7) "%02x %02x %02x %02x %02x %02x %02x %02x"

configure

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ audio_win_int=""
307307
libs_qga=""
308308
debug_info="yes"
309309
stack_protector=""
310+
safe_stack=""
310311
use_containers="yes"
311312
gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
312313

@@ -1287,6 +1288,10 @@ for opt do
12871288
;;
12881289
--disable-stack-protector) stack_protector="no"
12891290
;;
1291+
--enable-safe-stack) safe_stack="yes"
1292+
;;
1293+
--disable-safe-stack) safe_stack="no"
1294+
;;
12901295
--disable-curses) curses="no"
12911296
;;
12921297
--enable-curses) curses="yes"
@@ -1829,6 +1834,8 @@ disabled with --disable-FEATURE, default is enabled if available:
18291834
debug-tcg TCG debugging (default is disabled)
18301835
debug-info debugging information
18311836
sparse sparse checker
1837+
safe-stack SafeStack Stack Smash Protection. Depends on
1838+
clang/llvm >= 3.7 and requires coroutine backend ucontext.
18321839
18331840
gnutls GNUTLS cryptography support
18341841
nettle nettle cryptography support
@@ -5573,6 +5580,67 @@ if test "$debug_stack_usage" = "yes"; then
55735580
fi
55745581
fi
55755582

5583+
##################################################
5584+
# SafeStack
5585+
5586+
5587+
if test "$safe_stack" = "yes"; then
5588+
cat > $TMPC << EOF
5589+
int main(int argc, char *argv[])
5590+
{
5591+
#if ! __has_feature(safe_stack)
5592+
#error SafeStack Disabled
5593+
#endif
5594+
return 0;
5595+
}
5596+
EOF
5597+
flag="-fsanitize=safe-stack"
5598+
# Check that safe-stack is supported and enabled.
5599+
if compile_prog "-Werror $flag" "$flag"; then
5600+
# Flag needed both at compilation and at linking
5601+
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
5602+
QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
5603+
else
5604+
error_exit "SafeStack not supported by your compiler"
5605+
fi
5606+
if test "$coroutine" != "ucontext"; then
5607+
error_exit "SafeStack is only supported by the coroutine backend ucontext"
5608+
fi
5609+
else
5610+
cat > $TMPC << EOF
5611+
int main(int argc, char *argv[])
5612+
{
5613+
#if defined(__has_feature)
5614+
#if __has_feature(safe_stack)
5615+
#error SafeStack Enabled
5616+
#endif
5617+
#endif
5618+
return 0;
5619+
}
5620+
EOF
5621+
if test "$safe_stack" = "no"; then
5622+
# Make sure that safe-stack is disabled
5623+
if ! compile_prog "-Werror" ""; then
5624+
# SafeStack was already enabled, try to explicitly remove the feature
5625+
flag="-fno-sanitize=safe-stack"
5626+
if ! compile_prog "-Werror $flag" "$flag"; then
5627+
error_exit "Configure cannot disable SafeStack"
5628+
fi
5629+
QEMU_CFLAGS="$QEMU_CFLAGS $flag"
5630+
QEMU_LDFLAGS="$QEMU_LDFLAGS $flag"
5631+
fi
5632+
else # "$safe_stack" = ""
5633+
# Set safe_stack to yes or no based on pre-existing flags
5634+
if compile_prog "-Werror" ""; then
5635+
safe_stack="no"
5636+
else
5637+
safe_stack="yes"
5638+
if test "$coroutine" != "ucontext"; then
5639+
error_exit "SafeStack is only supported by the coroutine backend ucontext"
5640+
fi
5641+
fi
5642+
fi
5643+
fi
55765644

55775645
##########################################
55785646
# check if we have open_by_handle_at
@@ -6765,6 +6833,7 @@ echo "sparse enabled $sparse"
67656833
echo "strip binaries $strip_opt"
67666834
echo "profiler $profiler"
67676835
echo "static build $static"
6836+
echo "safe stack $safe_stack"
67686837
if test "$darwin" = "yes" ; then
67696838
echo "Cocoa support $cocoa"
67706839
fi
@@ -8370,6 +8439,10 @@ if test "$ccache_cpp2" = "yes"; then
83708439
echo "export CCACHE_CPP2=y" >> $config_host_mak
83718440
fi
83728441

8442+
if test "$safe_stack" = "yes"; then
8443+
echo "CONFIG_SAFESTACK=y" >> $config_host_mak
8444+
fi
8445+
83738446
# If we're using a separate build tree, set it up now.
83748447
# DIRS are directories which we simply mkdir in the build tree;
83758448
# LINKS are things to symlink back into the source tree

include/qemu/coroutine_int.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
#include "qemu/queue.h"
2929
#include "qemu/coroutine.h"
3030

31+
#ifdef CONFIG_SAFESTACK
32+
/* Pointer to the unsafe stack, defined by the compiler */
33+
extern __thread void *__safestack_unsafe_stack_ptr;
34+
#endif
35+
3136
#define COROUTINE_STACK_SIZE (1 << 20)
3237

3338
typedef enum {

scripts/minikconf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def do_include(self, include):
402402
if incl_abs_fname in self.data.previously_included:
403403
return
404404
try:
405-
fp = open(incl_abs_fname, 'r')
405+
fp = open(incl_abs_fname, 'rt', encoding='utf-8')
406406
except IOError as e:
407407
raise KconfigParserError(self,
408408
'%s: %s' % (e.strerror, include))
@@ -696,7 +696,7 @@ def scan_token(self):
696696
parser.do_assignment(name, value == 'y')
697697
external_vars.add(name[7:])
698698
else:
699-
fp = open(arg, 'r')
699+
fp = open(arg, 'rt', encoding='utf-8')
700700
parser.parse_file(fp)
701701
fp.close()
702702

@@ -705,7 +705,7 @@ def scan_token(self):
705705
if key not in external_vars and config[key]:
706706
print ('CONFIG_%s=y' % key)
707707

708-
deps = open(argv[2], 'w')
708+
deps = open(argv[2], 'wt', encoding='utf-8')
709709
for fname in data.previously_included:
710710
print ('%s: %s' % (argv[1], fname), file=deps)
711711
deps.close()

tests/check-block.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,17 @@ if grep -q "CONFIG_GPROF=y" config-host.mak 2>/dev/null ; then
2121
exit 0
2222
fi
2323

24-
if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then
24+
# Disable tests with any sanitizer except for SafeStack
25+
CFLAGS=$( grep "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null )
26+
SANITIZE_FLAGS=""
27+
#Remove all occurrencies of -fsanitize=safe-stack
28+
for i in ${CFLAGS}; do
29+
if [ "${i}" != "-fsanitize=safe-stack" ]; then
30+
SANITIZE_FLAGS="${SANITIZE_FLAGS} ${i}"
31+
fi
32+
done
33+
if echo ${SANITIZE_FLAGS} | grep -q "\-fsanitize" 2>/dev/null; then
34+
# Have a sanitize flag that is not allowed, stop
2535
echo "Sanitizers are enabled ==> Not running the qemu-iotests."
2636
exit 0
2737
fi

util/coroutine-sigaltstack.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include "qemu-common.h"
3131
#include "qemu/coroutine_int.h"
3232

33+
#ifdef CONFIG_SAFESTACK
34+
#error "SafeStack is not compatible with code run in alternate signal stacks"
35+
#endif
36+
3337
typedef struct {
3438
Coroutine base;
3539
void *stack;

util/coroutine-ucontext.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ typedef struct {
4545
Coroutine base;
4646
void *stack;
4747
size_t stack_size;
48+
#ifdef CONFIG_SAFESTACK
49+
/* Need an unsafe stack for each coroutine */
50+
void *unsafe_stack;
51+
size_t unsafe_stack_size;
52+
#endif
4853
sigjmp_buf env;
4954

5055
void *tsan_co_fiber;
@@ -179,6 +184,10 @@ Coroutine *qemu_coroutine_new(void)
179184
co = g_malloc0(sizeof(*co));
180185
co->stack_size = COROUTINE_STACK_SIZE;
181186
co->stack = qemu_alloc_stack(&co->stack_size);
187+
#ifdef CONFIG_SAFESTACK
188+
co->unsafe_stack_size = COROUTINE_STACK_SIZE;
189+
co->unsafe_stack = qemu_alloc_stack(&co->unsafe_stack_size);
190+
#endif
182191
co->base.entry_arg = &old_env; /* stash away our jmp_buf */
183192

184193
uc.uc_link = &old_uc;
@@ -203,6 +212,22 @@ Coroutine *qemu_coroutine_new(void)
203212
COROUTINE_YIELD,
204213
&fake_stack_save,
205214
co->stack, co->stack_size, co->tsan_co_fiber);
215+
216+
#ifdef CONFIG_SAFESTACK
217+
/*
218+
* Before we swap the context, set the new unsafe stack
219+
* The unsafe stack grows just like the normal stack, so start from
220+
* the last usable location of the memory area.
221+
* NOTE: we don't have to re-set the usp afterwards because we are
222+
* coming back to this context through a siglongjmp.
223+
* The compiler already wrapped the corresponding sigsetjmp call with
224+
* code that saves the usp on the (safe) stack before the call, and
225+
* restores it right after (which is where we return with siglongjmp).
226+
*/
227+
void *usp = co->unsafe_stack + co->unsafe_stack_size;
228+
__safestack_unsafe_stack_ptr = usp;
229+
#endif
230+
206231
swapcontext(&old_uc, &uc);
207232
}
208233

@@ -235,6 +260,9 @@ void qemu_coroutine_delete(Coroutine *co_)
235260
#endif
236261

237262
qemu_free_stack(co->stack, co->stack_size);
263+
#ifdef CONFIG_SAFESTACK
264+
qemu_free_stack(co->unsafe_stack, co->unsafe_stack_size);
265+
#endif
238266
g_free(co);
239267
}
240268

0 commit comments

Comments
 (0)