From nobody Tue Oct 28 01:50:39 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516059418717967.4253034571163; Mon, 15 Jan 2018 15:36:58 -0800 (PST) Received: from localhost ([::1]:44171 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ebEJ8-0002Ve-Mh for importer@patchew.org; Mon, 15 Jan 2018 18:36:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45840) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ebEHX-0001al-0E for qemu-devel@nongnu.org; Mon, 15 Jan 2018 18:35:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ebEHV-00030x-O0 for qemu-devel@nongnu.org; Mon, 15 Jan 2018 18:35:11 -0500 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:35967) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ebEHV-000301-E9 for qemu-devel@nongnu.org; Mon, 15 Jan 2018 18:35:09 -0500 Received: by mail-wm0-x244.google.com with SMTP id f3so5075252wmc.1 for ; Mon, 15 Jan 2018 15:35:09 -0800 (PST) Received: from 640k.lan (dynamic-adsl-78-12-229-84.clienti.tiscali.it. [78.12.229.84]) by smtp.gmail.com with ESMTPSA id u2sm1039193wrb.80.2018.01.15.15.35.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Jan 2018 15:35:07 -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=bwhvV520MkgOBJf+Qwr/G6cpvc8mPw73A97G4o775pU=; b=e04gU2myLMneu7Psd/1ITLfhEI8OX5nJ6EXbalKK6SG1JaEyAo685NkmyRB4AAnY6T Rr7JEOBwF04hNh3tILCh8/z1+z0tJFekRc1zR4dwT0L2trUE7pwEFh9ok1iEKwFjIeOY u/MdT24RhIT1sagdIPdZFK35WfPe65G7TxFIitQlBjDuQtWrUUi9PN12f3sd1i/4vyhC CAHhuzJ478+VUyWaFkv6Q4tGBBsFZxhobWOFuh+9f1JJEDX1Cek8OnBSotcT2VkOgGWz KFcgBtSwDDgnQSqYaI1ue3vL3AzaxXQQp6pFYp9TeSstiXEx42uomjEqL3mX62dsAw0h cQEA== 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=bwhvV520MkgOBJf+Qwr/G6cpvc8mPw73A97G4o775pU=; b=TZ6o4cSBxpkxklyzNflsIE0k4lfum4rT64d/OzI04AQJmb9n0uTQGN+rrZDrkBpw+V sTE1ftMrOQlp+eMyFrtusc4MYr//CCxbHLJkJzaWKgrh/bPY+GBQ0ZPtHC1MDSAOGVoy yYhIhiarwmjtuKUyOkV4Hl5mfzEGIHclsGQoh39W4lli/0eBX5ujEgeCqo5XXq1c5qNN gEapWzCk2ghGJZfGI3eKLbHcD4WO0RzdidzXrXcCjZ8WAlU1Ald1vNhytP/CNlQQ397z mvqYr+IGu8Dq6rvEpZKuS5AqB4rNNNwQELxJnYFQEgheLH/fA4Kzj+b6gwOfI/+M6h0y 8CKw== X-Gm-Message-State: AKwxyteCeJZ7h4brnFrp/5GzwueMqtrt/JU0HhInFAaL10L9XdvdNNmn OZFRqtVgK56x8ouNKukSMprSz7+n X-Google-Smtp-Source: ACJfBouESnuYNL3eod8wERMZ81u8fQobNgO/DNdo7KHhXX6SOxjQAGbW3Heak5UPUHlMJh/IYLriuQ== X-Received: by 10.28.157.206 with SMTP id g197mr6820976wme.96.1516059307949; Mon, 15 Jan 2018 15:35:07 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 16 Jan 2018 00:35:02 +0100 Message-Id: <1516059302-7169-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1516059302-7169-1-git-send-email-pbonzini@redhat.com> References: <1516059302-7169-1-git-send-email-pbonzini@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PULL 53/53] ucontext: annotate coroutine stack for ASAN X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 From: Marc-Andr=C3=A9 Lureau It helps ASAN to detect more leaks on coroutine stacks, as found in the following patch. A similar work would need to be done for sigaltstack & windows fibers to have similar coverage. Since ucontext is preferred, I didn't bother checking the other coroutine implementations for now. Signed-off-by: Marc-Andr=C3=83=C2=A9 Lureau Signed-off-by: Paolo Bonzini --- .travis.yml | 3 ++- configure | 41 ++++++++++++++++++++++++++++++++++++++-- include/qemu/compiler.h | 4 ++++ util/coroutine-ucontext.c | 48 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f583839..f2291e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,13 @@ addons: - libattr1-dev - libbrlapi-dev - libcap-ng-dev + - libgcc-6-dev - libgnutls-dev - libgtk-3-dev - libiscsi-dev - liblttng-ust-dev - - libnfs-dev - libncurses5-dev + - libnfs-dev - libnss3-dev - libpixman-1-dev - libpng12-dev diff --git a/configure b/configure index d033286..3007a2c 100755 --- a/configure +++ b/configure @@ -5186,18 +5186,51 @@ if compile_prog "" "" ; then fi =20 ########################################## +# checks for ASAN + +have_asan=3Dno +write_c_skeleton +if compile_prog "-fsanitize=3Daddress" ""; then + have_asan=3Dyes +fi + +have_asan_iface_h=3Dno +if check_include "sanitizer/asan_interface.h" ; then + have_asan_iface_h=3Dyes +fi + +have_asan_iface_fiber=3Dno +cat > $TMPC << EOF +#include +int main(void) { + __sanitizer_start_switch_fiber(0, 0, 0); + return 0; +} +EOF +if compile_prog "-fsanitize=3Daddress" "" ; then + have_asan_iface_fiber=3Dyes +fi + +########################################## # End of CC checks # After here, no more $cc or $ld runs =20 +write_c_skeleton if test "$gcov" =3D "yes" ; then CFLAGS=3D"-fprofile-arcs -ftest-coverage -g $CFLAGS" LDFLAGS=3D"-fprofile-arcs -ftest-coverage $LDFLAGS" elif test "$fortify_source" =3D "yes" ; then CFLAGS=3D"-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3D2 $CFLAGS" elif test "$debug" =3D "yes"; then - write_c_skeleton; - if compile_prog "-fsanitize=3Daddress" ""; then + if test "$have_asan" =3D "yes"; then CFLAGS=3D"-fsanitize=3Daddress $CFLAGS" + if test "$have_asan_iface_h" =3D "no" ; then + print_error "ASAN build enabled, but ASAN header missing." \ + "Without code annotation, the report may be inferior= ." + elif test "$have_asan_iface_fiber" =3D "no" ; then + print_error "ASAN build enabled, but ASAN header is too old." \ + "Without code annotation, the report may be inferior= ." + fi fi if compile_prog "-fsanitize=3Dundefined" ""; then CFLAGS=3D"-fsanitize=3Dundefined $CFLAGS" @@ -6320,6 +6353,10 @@ if test "$have_utmpx" =3D "yes" ; then echo "HAVE_UTMPX=3Dy" >> $config_host_mak fi =20 +if test "$have_asan_iface_fiber" =3D "yes" ; then + echo "HAVE_ASAN_IFACE_FIBER=3Dy" >> $config_host_mak +fi + if test "$ivshmem" =3D "yes" ; then echo "CONFIG_IVSHMEM=3Dy" >> $config_host_mak fi diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 340e5fd..5fcc4f7 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -111,4 +111,8 @@ #define GCC_FMT_ATTR(n, m) #endif =20 +#ifndef __has_feature +#define __has_feature(x) 0 /* compatibility with non-clang compilers */ +#endif + #endif /* COMPILER_H */ diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c index 6621f3f..96af7f5 100644 --- a/util/coroutine-ucontext.c +++ b/util/coroutine-ucontext.c @@ -31,6 +31,13 @@ #include #endif =20 +#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) +#ifdef HAVE_ASAN_IFACE_FIBER +#define CONFIG_ASAN 1 +#include +#endif +#endif + typedef struct { Coroutine base; void *stack; @@ -59,11 +66,37 @@ union cc_arg { int i[2]; }; =20 +static void finish_switch_fiber(void *fake_stack_save) +{ +#ifdef CONFIG_ASAN + const void *bottom_old; + size_t size_old; + + __sanitizer_finish_switch_fiber(fake_stack_save, &bottom_old, &size_ol= d); + + if (!leader.stack) { + leader.stack =3D (void *)bottom_old; + leader.stack_size =3D size_old; + } +#endif +} + +static void start_switch_fiber(void **fake_stack_save, + const void *bottom, size_t size) +{ +#ifdef CONFIG_ASAN + __sanitizer_start_switch_fiber(fake_stack_save, bottom, size); +#endif +} + static void coroutine_trampoline(int i0, int i1) { union cc_arg arg; CoroutineUContext *self; Coroutine *co; + void *fake_stack_save =3D NULL; + + finish_switch_fiber(NULL); =20 arg.i[0] =3D i0; arg.i[1] =3D i1; @@ -72,9 +105,13 @@ static void coroutine_trampoline(int i0, int i1) =20 /* Initialize longjmp environment and switch back the caller */ if (!sigsetjmp(self->env, 0)) { + start_switch_fiber(&fake_stack_save, + leader.stack, leader.stack_size); siglongjmp(*(sigjmp_buf *)co->entry_arg, 1); } =20 + finish_switch_fiber(fake_stack_save); + while (true) { co->entry(co->entry_arg); qemu_coroutine_switch(co, co->caller, COROUTINE_TERMINATE); @@ -87,6 +124,7 @@ Coroutine *qemu_coroutine_new(void) ucontext_t old_uc, uc; sigjmp_buf old_env; union cc_arg arg =3D {0}; + void *fake_stack_save =3D NULL; =20 /* The ucontext functions preserve signal masks which incurs a * system call overhead. sigsetjmp(buf, 0)/siglongjmp() does not @@ -122,8 +160,12 @@ Coroutine *qemu_coroutine_new(void) =20 /* swapcontext() in, siglongjmp() back out */ if (!sigsetjmp(old_env, 0)) { + start_switch_fiber(&fake_stack_save, co->stack, co->stack_size); swapcontext(&old_uc, &uc); } + + finish_switch_fiber(fake_stack_save); + return &co->base; } =20 @@ -169,13 +211,19 @@ qemu_coroutine_switch(Coroutine *from_, Coroutine *to= _, CoroutineUContext *from =3D DO_UPCAST(CoroutineUContext, base, from_); CoroutineUContext *to =3D DO_UPCAST(CoroutineUContext, base, to_); int ret; + void *fake_stack_save =3D NULL; =20 current =3D to_; =20 ret =3D sigsetjmp(from->env, 0); if (ret =3D=3D 0) { + start_switch_fiber(action =3D=3D COROUTINE_TERMINATE ? + NULL : &fake_stack_save, to->stack, to->stack_s= ize); siglongjmp(to->env, action); } + + finish_switch_fiber(fake_stack_save); + return ret; } =20 --=20 1.8.3.1