From patchwork Fri Sep 6 14:46:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Malcomson X-Patchwork-Id: 1159037 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-508501-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="x5y2NzPw"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.b="ijYMQ43u"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=armh.onmicrosoft.com header.i=@armh.onmicrosoft.com header.b="ijYMQ43u"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Q0ly6Hgqz9sN1 for ; Sat, 7 Sep 2019 00:47:58 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; q=dns; s=default; b=RCWZ0K0ljgQDtsuX iUOyusmZ0lvD2199lJ4vNGTpWmd0NkfexGAUrsO5HzCic5r09bIPg8rNXp6oSVzF nUMc0j7P+cJ4yfzO+qd16v5K5xc9hRfKDNR/7LTiGwOUMwF/XnJAHb9BD7y+q+7r TneZ4gZfhiCaGNKdknYywqcOnMs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:references:in-reply-to :content-type:mime-version; s=default; bh=+BoA39idUCLY1KiNjKrINp I8ERY=; b=x5y2NzPwhMNOiPue+Ot+rMSnf69Eb4N9nIRQwnotAxKF5fAgflUBBB 4WlgDbUSQE2DhhBbdux/QI+X5XmIBAKsKOAwS9NkrRjHzzW/A7xZkQr4ZVBtHUIT 1gp3d2kTTwzQlpUpiRlCJBOtimYCgXu0dk1XW6rsKDfTsKY5sIGMo= Received: (qmail 57357 invoked by alias); 6 Sep 2019 14:46:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 57237 invoked by uid 89); 6 Sep 2019 14:46:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: EUR03-AM5-obe.outbound.protection.outlook.com Received: from mail-eopbgr30052.outbound.protection.outlook.com (HELO EUR03-AM5-obe.outbound.protection.outlook.com) (40.107.3.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Sep 2019 14:46:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ao5Sg7oGIy1ci+mqV/zSudwrwiP+FFB4BOKnOtTeolk=; b=ijYMQ43uO+FXuLHcItIpznJt5T9Kll5ei7pbbFNun63dffWO0WrOtqS8P6Md+Y59uVdOCKr3HrcytLz4XE/l6Sl2tFkNvKU5gCOev8o8aFblMNPuU0cG7czh9l3yA4b/y7WbQYKkc8aoL0rWw/6V5kRXzHoSdG3NALbzI+HwMzw= Received: from VI1PR0802CA0022.eurprd08.prod.outlook.com (2603:10a6:800:aa::32) by AM0SPR01MB0036.eurprd08.prod.outlook.com (2603:10a6:208:d5::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2241.14; Fri, 6 Sep 2019 14:46:20 +0000 Received: from DB5EUR03FT017.eop-EUR03.prod.protection.outlook.com (2a01:111:f400:7e0a::201) by VI1PR0802CA0022.outlook.office365.com (2603:10a6:800:aa::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2241.13 via Frontend Transport; Fri, 6 Sep 2019 14:46:20 +0000 Authentication-Results: spf=temperror (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; gcc.gnu.org; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; gcc.gnu.org; dmarc=temperror action=none header.from=arm.com; Received-SPF: TempError (protection.outlook.com: error in processing during lookup of arm.com: DNS Timeout) Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DB5EUR03FT017.mail.protection.outlook.com (10.152.20.114) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2241.14 via Frontend Transport; Fri, 6 Sep 2019 14:46:18 +0000 Received: ("Tessian outbound ea3fc1501f20:v27"); Fri, 06 Sep 2019 14:46:18 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 3f48daa6dd930d9d X-CR-MTA-TID: 64aa7808 Received: from 93fd9dc78205.1 (cr-mta-lb-1.cr-mta-net [104.47.13.58]) by 64aa7808-outbound-1.mta.getcheckrecipient.com id A921A651-51D7-4B0D-BA4B-C81355CCA858.1; Fri, 06 Sep 2019 14:46:13 +0000 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04lp2058.outbound.protection.outlook.com [104.47.13.58]) by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 93fd9dc78205.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Fri, 06 Sep 2019 14:46:13 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iIqkKjydMF+g059PxlGO3OsO+qCxFnrnXsJq/dBMoMXoHKaKv8zLL9lCcpESUmpGc/2Fh8WQUx04d4WlYZlHfkn5Z3TG8cmf8hR26OGt4rXga+qXNGFe391wITYWYQZ38mgiYBLotn55uUpHHFOUf+9q1+8fKgGUvEYkUjkBcIZscwQvTP2l74QJthd7OdmpeizdcPFf7K7Uk0jtxc19sKykbvwCmME8FEBrcFpy7+m3YS/yYZEP4ua8mj9ATbFvobJu2GbnCBa+TJXxtCx/yC6gQEl/I/Q7CYY0qTaYaWxVK95RIqlUQpeY5wNWy0JXIsy9xXsq505hizyV60bsCQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ao5Sg7oGIy1ci+mqV/zSudwrwiP+FFB4BOKnOtTeolk=; b=oWL/qyLci6jobqxHnU/8KZDOWAzKkt8Pxb2sOHsRpBmOFxnrwnN9pyfRjfPWXeFN0wrw4HqcXeZX3R0y7fzxEYKl7y3TjOrLuKWNJTMR3e08F/5z6ULdi7FEuySLjHTz7JEXzLAddn3HgYu1ojJHTS32g7yO4bsaCHmbMvf30rUrV5GBaB+LimyO/SHahbC8j26MitrrL1z2gMBITXTTEYCmMeq8NLyB7inFRLcnkG+rzVeIrnm1lUot7dJct7YLCUhHwTaqkJ/JJK+4RZGyNjdObkG0991rkOmB5Wlv13jXD9LPM1zCDNYPIqspWT3Y3NhvHP5ZbUXKZE4RkbH9xA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ao5Sg7oGIy1ci+mqV/zSudwrwiP+FFB4BOKnOtTeolk=; b=ijYMQ43uO+FXuLHcItIpznJt5T9Kll5ei7pbbFNun63dffWO0WrOtqS8P6Md+Y59uVdOCKr3HrcytLz4XE/l6Sl2tFkNvKU5gCOev8o8aFblMNPuU0cG7czh9l3yA4b/y7WbQYKkc8aoL0rWw/6V5kRXzHoSdG3NALbzI+HwMzw= Received: from VI1PR08MB5471.eurprd08.prod.outlook.com (52.133.246.83) by VI1PR08MB3392.eurprd08.prod.outlook.com (20.177.58.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2241.14; Fri, 6 Sep 2019 14:46:10 +0000 Received: from VI1PR08MB5471.eurprd08.prod.outlook.com ([fe80::206a:65bd:e6a9:536b]) by VI1PR08MB5471.eurprd08.prod.outlook.com ([fe80::206a:65bd:e6a9:536b%2]) with mapi id 15.20.2241.018; Fri, 6 Sep 2019 14:46:10 +0000 From: Matthew Malcomson To: "gcc-patches@gcc.gnu.org" CC: "mliska@suse.cz" , "dodji@redhat.com" , nd , "kcc@google.com" , "jakub@redhat.com" , "dvyukov@google.com" Subject: [RFC][PATCH 5/X][libsanitizer] Introduce longjmp/setjmp interceptors to libhwasan Date: Fri, 6 Sep 2019 14:46:10 +0000 Message-ID: References: <156778058239.16148.17480879484406897649.scripted-patch-series@arm.com> In-Reply-To: <156778058239.16148.17480879484406897649.scripted-patch-series@arm.com> Authentication-Results-Original: spf=none (sender IP is ) smtp.mailfrom=Matthew.Malcomson@arm.com; X-Microsoft-Antispam-Untrusted: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600166)(711020)(4605104)(1401327)(4618075)(2017052603328)(49563074)(7193020); SRVR:VI1PR08MB3392; x-checkrecipientrouted: true x-ms-oob-tlc-oobclassifiers: OLM:8882;OLM:8882; X-Forefront-Antispam-Report-Untrusted: SFV:NSPM; SFS:(10009020)(4636009)(376002)(39860400002)(136003)(396003)(346002)(366004)(54534003)(199004)(189003)(66476007)(66556008)(64756008)(66446008)(7696005)(81166006)(52536014)(5660300002)(2501003)(14454004)(25786009)(52116002)(55016002)(478600001)(86362001)(4326008)(99936001)(8936002)(81156014)(6916009)(66946007)(71200400001)(71190400001)(8676002)(66616009)(3846002)(446003)(476003)(6116002)(33656002)(11346002)(76176011)(30864003)(2906002)(53936002)(186003)(9686003)(6436002)(66066001)(256004)(14444005)(5024004)(5640700003)(54906003)(386003)(6506007)(44832011)(486006)(7736002)(74316002)(305945005)(316002)(99286004)(26005)(2351001)(102836004); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR08MB3392; H:VI1PR08MB5471.eurprd08.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info-Original: ULPZE2MOBKFtPO8aJm8hvXRl4KpKURclSttAZSbrr+/J7wEHVy5AR7zseBkubzi5sXshRc+CkFot+QyzFxeFpGFjmY1BstKpqOOec27wVddobYxNGAPQlCW9ENfih68QZScVoeCtNBCnFd0ZWl92Sg19RVqglUF6xNkb0+1ldQHc/X1LNYqFZ2a3hdcCI042ri4E5LFLG2FR0EyD41BxE+SlGqk1oHmNQqjp1EFrtMpJmHZQg333jwb2oLHcKeip1yZ3LNtZJ0zZQNg1md3JzYwy8OjIBBk81Vb6Tv+40oCkdULer2qWBu6vZWY2kAwZRBcaUkkJMwg4xsGiwteInR7t/Rqq1uzo+mQDjizNX5/+scQf1ooo25jQdnpbdk0fdf41ZivC9qGEbRyL2ttClh4KRLr0G1cuNf/djbKxEnE= x-ms-exchange-transport-forked: True MIME-Version: 1.0 Original-Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Matthew.Malcomson@arm.com; X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5EUR03FT017.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 8cceec79-5adb-416b-3792-08d732d8f525 X-IsSubscribed: yes When using hwasan to tag parameters on the stack, we need to ensure that the shadow stack is cleared upon exit of a function. If this is not done, then accesses to an untagged memory region (e.g. parameters passed on the stack) can end up being checked against a shadow region that was coloured for a variable some time in the past. Ensuring that the shadow stack is cleared on normal function exit will be done by adding instrumentation to the function epilogue through the compiler. longjmp and setjmp are some abnormal methods of exiting the function that can't be handled in the compiler since they can be called in uninstrumented code to unwind past instrumented function frames. This patch introduces some interceptors for setjmp and longjmp. This pair of functions only behaves differently to the glibc version by uncolouring the stack between the point where longjmp was called and the destination stack pointer. The file hwasan_interceptors.cc aims to include as little system headers as possible, since it defines interceptors for system functions and hence needs to use its own data structures that are independent of the current platform. To avoid including signal.h yet still be able to handle sigsetjmp we manually define a __sigset_t structure and similarly we define data structures to use for the intercepting setjmp/longjmp. libsanitizer/ChangeLog: 2019-09-06 Matthew Malcomson * hwasan/Makefile.am: Add hwasan_setjmp.S. * hwasan/Makefile.in: Regenerate. * hwasan/hwasan_interceptors.cc (_SIGSET_NWORDS): (struct __sigset_t): New structure. (struct __jmp_buf_tag): New structure. (sigprocmask): Declaration of system function. (SIG_BLOCK): New. (SIG_SETMASK): New. (__sigjmp_save): New. (__hwasan_internal_longjmp): longjmp that clears shadow tags. (siglongjmp): New interceptors. (__libc_longjmp): New interceptors. (longjmp): New interceptors. * hwasan/hwasan_setjmp.S: New file. ############### Attachment also inlined for ease of reply ############### diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am index 3754f435ce0342f5c8051f6ea44273bb811c9659..36c0fc4d9e832dfc81c72d2d05c2b327589daee2 100644 --- a/libsanitizer/hwasan/Makefile.am +++ b/libsanitizer/hwasan/Makefile.am @@ -13,6 +13,7 @@ ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config toolexeclib_LTLIBRARIES = libhwasan.la hwasan_files = \ + hwasan_setjmp.S \ hwasan_allocator.cc \ hwasan.cc \ hwasan_dynamic_shadow.cc \ diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in index f89bc9e440502fcf8072d67aa61a4b63cd490b40..472fbf7d8d2a5311db8fe4c14376f9213cdddde4 100644 --- a/libsanitizer/hwasan/Makefile.in +++ b/libsanitizer/hwasan/Makefile.in @@ -145,10 +145,10 @@ am__DEPENDENCIES_1 = libhwasan_la_DEPENDENCIES = \ $(top_builddir)/sanitizer_common/libsanitizer_common.la \ $(am__append_1) $(am__append_2) $(am__DEPENDENCIES_1) -am__objects_1 = hwasan_allocator.lo hwasan.lo hwasan_dynamic_shadow.lo \ - hwasan_interceptors.lo hwasan_linux.lo hwasan_new_delete.lo \ - hwasan_poisoning.lo hwasan_report.lo hwasan_thread.lo \ - hwasan_thread_list.lo +am__objects_1 = hwasan_setjmp.lo hwasan_allocator.lo hwasan.lo \ + hwasan_dynamic_shadow.lo hwasan_interceptors.lo \ + hwasan_linux.lo hwasan_new_delete.lo hwasan_poisoning.lo \ + hwasan_report.lo hwasan_thread.lo hwasan_thread_list.lo am_libhwasan_la_OBJECTS = $(am__objects_1) libhwasan_la_OBJECTS = $(am_libhwasan_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -174,6 +174,16 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp am__depfiles_maybe = depfiles am__mv = mv -f +CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CCASFLAGS) $(CCASFLAGS) +AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) +am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) +am__v_CPPAS_0 = @echo " CPPAS " $@; +am__v_CPPAS_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ @@ -192,6 +202,24 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libhwasan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -380,6 +408,7 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \ ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config toolexeclib_LTLIBRARIES = libhwasan.la hwasan_files = \ + hwasan_setjmp.S \ hwasan_allocator.cc \ hwasan.cc \ hwasan_dynamic_shadow.cc \ @@ -439,7 +468,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .S .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -522,9 +551,31 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_new_delete.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_poisoning.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_report.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_setjmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_thread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_thread_list.Plo@am__quote@ +.S.o: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< + +.S.obj: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.S.lo: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< + .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po diff --git a/libsanitizer/hwasan/hwasan_interceptors.cc b/libsanitizer/hwasan/hwasan_interceptors.cc index 9a0770f563b7948644cb10cdd0f88edc79f786d5..2edfba5d4ba065ca1dd09400c182962ecff5d9ca 100644 --- a/libsanitizer/hwasan/hwasan_interceptors.cc +++ b/libsanitizer/hwasan/hwasan_interceptors.cc @@ -284,6 +284,107 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), &HwasanThreadStartFunc, A); return res; } + + +#if defined(__aarch64__) +/* + Setjmp and longjmp implementations are platform specific, and hence the + interception code is platform specific too. As yet we've only implemented + the interception for AArch64. + */ +# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) +typedef struct + { + unsigned long int __val[_SIGSET_NWORDS]; + } __sigset_t; + +#undef _SIGSET_NWORDS +typedef __sigset_t sigset_t; +typedef unsigned long long __jmp_buf [22]; +struct __jmp_buf_tag + { + /* NOTE: The machine-dependent definitions of `__sigsetjmp' + assume that a `jmp_buf' begins with a `__jmp_buf' and that + `__mask_was_saved' follows it. Do not move these members + or add others before it. */ + __jmp_buf __jmpbuf; /* Calling environment. */ + int __mask_was_saved; /* Saved the signal mask? */ + __sigset_t __saved_mask; /* Saved signal mask. */ + }; +typedef struct __jmp_buf_tag jmp_buf[1]; +typedef struct __jmp_buf_tag sigjmp_buf[1]; + +/* Get and/or change the set of blocked signals. */ +extern "C" int sigprocmask (int __how, const sigset_t *__restrict __set, + sigset_t *__restrict __oset); +#define SIG_BLOCK 0 +#define SIG_SETMASK 2 +extern "C" int __sigjmp_save (sigjmp_buf env, int savemask) +{ + env[0].__mask_was_saved = (savemask + && sigprocmask (SIG_BLOCK, (sigset_t *) 0, + (sigset_t *) &env[0].__saved_mask) == 0); + return 0; +} + +static void __attribute__ ((always_inline)) +__hwasan_internal_longjmp (__jmp_buf env, int retval) +{ + /* Clear all memory tags on the stack between here and where we're going. */ + unsigned long long stack_pointer = env[13]; + /* The stack pointer should never be tagged, so we don't need to clear the + tag for this function call. */ + __hwasan_handle_longjmp ((void *)stack_pointer); + + /* Run code for handling a longjmp. + Need to use a register that isn't going to be loaded from the environment + buffer -- hence why we need to specify the register to use. */ + register int retval_tmp asm ("x1") = retval; + register void *env_address asm ("x0") = &env[0]; + asm volatile ( + "ldp x19, x20, [%0, #0<<3];" + "ldp x21, x22, [%0, #2<<3];" + "ldp x23, x24, [%0, #4<<3];" + "ldp x25, x26, [%0, #6<<3];" + "ldp x27, x28, [%0, #8<<3];" + "ldp x29, x30, [%0, #10<<3];" + "ldp d8, d9, [%0, #14<<3];" + "ldp d10, d11, [%0, #16<<3];" + "ldp d12, d13, [%0, #18<<3];" + "ldp d14, d15, [%0, #20<<3];" + "ldr x5, [%0, #13<<3];" + "mov sp, x5;" + /* Return the value requested to return through arguments. + This should be in x1 given what we requested above. */ + "cmp %1, #0;" + "mov x0, #1;" + "csel x0, %1, x0, ne;" + "br x30;" : "+r" (env_address) : "r" (retval_tmp)); +} + +INTERCEPTOR(void, siglongjmp, sigjmp_buf env, int val) +{ + if (env[0].__mask_was_saved) + /* Restore the saved signal mask. */ + (void) sigprocmask (SIG_SETMASK, + (sigset_t *) &env[0].__saved_mask, + (sigset_t *) 0); + __hwasan_internal_longjmp (env[0].__jmpbuf, val); +} + +INTERCEPTOR(void, __libc_longjmp, jmp_buf env, int val) +{ + __hwasan_internal_longjmp (env[0].__jmpbuf, val); +} + +INTERCEPTOR(void, longjmp, jmp_buf env, int val) +{ + __hwasan_internal_longjmp (env[0].__jmpbuf, val); +} +#undef SIG_BLOCK +#undef SIG_SETMASK + +#endif // __aarch64__ #endif // HWASAN_WITH_INTERCEPTORS static void BeforeFork() { @@ -302,7 +403,6 @@ INTERCEPTOR(int, fork, void) { return pid; } - struct HwasanInterceptorContext { bool in_interceptor_scope; }; @@ -325,6 +425,11 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(fork); #if HWASAN_WITH_INTERCEPTORS +#if defined(__aarch64__) + INTERCEPT_FUNCTION(longjmp); + INTERCEPT_FUNCTION(__libc_longjmp); + INTERCEPT_FUNCTION(siglongjmp); +#endif INTERCEPT_FUNCTION(pthread_create); #endif diff --git a/libsanitizer/hwasan/hwasan_setjmp.S b/libsanitizer/hwasan/hwasan_setjmp.S new file mode 100644 index 0000000000000000000000000000000000000000..56add3e149abcc37ec23b8cdc8f4ba2cbc722c08 --- /dev/null +++ b/libsanitizer/hwasan/hwasan_setjmp.S @@ -0,0 +1,52 @@ +// We want to save the context of the calling function. +// That requires +// 1) No modification of the link register by this function. +// 2) No modification of the stack pointer by this function. +// 3) (no modification of any other saved register, but that's not really going +// to occur, and hence isn't as much of a worry). +// +// There's essentially no way to ensure that the compiler will not modify the +// stack pointer when compiling a C function. +// Hence we have to write this function in assembly. + +#if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__) + +.macro ENTRY symbol + .align 2 + .global \symbol + .type \symbol\(), %function +\symbol\(): + .cfi_startproc +.endm + +.macro END symbol + .cfi_endproc + .size \symbol, .-\symbol +.endm + +ENTRY _setjmp +mov x1, #0 +b 1f +END _setjmp + +ENTRY __sigsetjmp +1: + stp x19, x20, [x0, #0<<3] + stp x21, x22, [x0, #2<<3] + stp x23, x24, [x0, #4<<3] + stp x25, x26, [x0, #6<<3] + stp x27, x28, [x0, #8<<3] + stp x29, x30, [x0, #10<<3] + stp d8, d9, [x0, #14<<3] + stp d10, d11, [x0, #16<<3] + stp d12, d13, [x0, #18<<3] + stp d14, d15, [x0, #20<<3] + mov x2, sp + str x2, [x0, #13<<3] + // We always have the second argument to __sigjmp_save (savemask) set, since + // the _setjmp function above has set it for us as `false`. + // This function is defined in hwasan_interceptors.cc + b __sigjmp_save +END __sigsetjmp + +#endif diff --git a/libsanitizer/hwasan/Makefile.am b/libsanitizer/hwasan/Makefile.am index 3754f435ce0342f5c8051f6ea44273bb811c9659..36c0fc4d9e832dfc81c72d2d05c2b327589daee2 100644 --- a/libsanitizer/hwasan/Makefile.am +++ b/libsanitizer/hwasan/Makefile.am @@ -13,6 +13,7 @@ ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config toolexeclib_LTLIBRARIES = libhwasan.la hwasan_files = \ + hwasan_setjmp.S \ hwasan_allocator.cc \ hwasan.cc \ hwasan_dynamic_shadow.cc \ diff --git a/libsanitizer/hwasan/Makefile.in b/libsanitizer/hwasan/Makefile.in index f89bc9e440502fcf8072d67aa61a4b63cd490b40..472fbf7d8d2a5311db8fe4c14376f9213cdddde4 100644 --- a/libsanitizer/hwasan/Makefile.in +++ b/libsanitizer/hwasan/Makefile.in @@ -145,10 +145,10 @@ am__DEPENDENCIES_1 = libhwasan_la_DEPENDENCIES = \ $(top_builddir)/sanitizer_common/libsanitizer_common.la \ $(am__append_1) $(am__append_2) $(am__DEPENDENCIES_1) -am__objects_1 = hwasan_allocator.lo hwasan.lo hwasan_dynamic_shadow.lo \ - hwasan_interceptors.lo hwasan_linux.lo hwasan_new_delete.lo \ - hwasan_poisoning.lo hwasan_report.lo hwasan_thread.lo \ - hwasan_thread_list.lo +am__objects_1 = hwasan_setjmp.lo hwasan_allocator.lo hwasan.lo \ + hwasan_dynamic_shadow.lo hwasan_interceptors.lo \ + hwasan_linux.lo hwasan_new_delete.lo hwasan_poisoning.lo \ + hwasan_report.lo hwasan_thread.lo hwasan_thread_list.lo am_libhwasan_la_OBJECTS = $(am__objects_1) libhwasan_la_OBJECTS = $(am_libhwasan_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -174,6 +174,16 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp am__depfiles_maybe = depfiles am__mv = mv -f +CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CCASFLAGS) $(CCASFLAGS) +AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) +am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) +am__v_CPPAS_0 = @echo " CPPAS " $@; +am__v_CPPAS_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ @@ -192,6 +202,24 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libhwasan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -380,6 +408,7 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \ ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config toolexeclib_LTLIBRARIES = libhwasan.la hwasan_files = \ + hwasan_setjmp.S \ hwasan_allocator.cc \ hwasan.cc \ hwasan_dynamic_shadow.cc \ @@ -439,7 +468,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .S .cc .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -522,9 +551,31 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_new_delete.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_poisoning.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_report.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_setjmp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_thread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hwasan_thread_list.Plo@am__quote@ +.S.o: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< + +.S.obj: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.S.lo: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< + .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po diff --git a/libsanitizer/hwasan/hwasan_interceptors.cc b/libsanitizer/hwasan/hwasan_interceptors.cc index 9a0770f563b7948644cb10cdd0f88edc79f786d5..2edfba5d4ba065ca1dd09400c182962ecff5d9ca 100644 --- a/libsanitizer/hwasan/hwasan_interceptors.cc +++ b/libsanitizer/hwasan/hwasan_interceptors.cc @@ -284,6 +284,107 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), &HwasanThreadStartFunc, A); return res; } + + +#if defined(__aarch64__) +/* + Setjmp and longjmp implementations are platform specific, and hence the + interception code is platform specific too. As yet we've only implemented + the interception for AArch64. + */ +# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) +typedef struct + { + unsigned long int __val[_SIGSET_NWORDS]; + } __sigset_t; + +#undef _SIGSET_NWORDS +typedef __sigset_t sigset_t; +typedef unsigned long long __jmp_buf [22]; +struct __jmp_buf_tag + { + /* NOTE: The machine-dependent definitions of `__sigsetjmp' + assume that a `jmp_buf' begins with a `__jmp_buf' and that + `__mask_was_saved' follows it. Do not move these members + or add others before it. */ + __jmp_buf __jmpbuf; /* Calling environment. */ + int __mask_was_saved; /* Saved the signal mask? */ + __sigset_t __saved_mask; /* Saved signal mask. */ + }; +typedef struct __jmp_buf_tag jmp_buf[1]; +typedef struct __jmp_buf_tag sigjmp_buf[1]; + +/* Get and/or change the set of blocked signals. */ +extern "C" int sigprocmask (int __how, const sigset_t *__restrict __set, + sigset_t *__restrict __oset); +#define SIG_BLOCK 0 +#define SIG_SETMASK 2 +extern "C" int __sigjmp_save (sigjmp_buf env, int savemask) +{ + env[0].__mask_was_saved = (savemask + && sigprocmask (SIG_BLOCK, (sigset_t *) 0, + (sigset_t *) &env[0].__saved_mask) == 0); + return 0; +} + +static void __attribute__ ((always_inline)) +__hwasan_internal_longjmp (__jmp_buf env, int retval) +{ + /* Clear all memory tags on the stack between here and where we're going. */ + unsigned long long stack_pointer = env[13]; + /* The stack pointer should never be tagged, so we don't need to clear the + tag for this function call. */ + __hwasan_handle_longjmp ((void *)stack_pointer); + + /* Run code for handling a longjmp. + Need to use a register that isn't going to be loaded from the environment + buffer -- hence why we need to specify the register to use. */ + register int retval_tmp asm ("x1") = retval; + register void *env_address asm ("x0") = &env[0]; + asm volatile ( + "ldp x19, x20, [%0, #0<<3];" + "ldp x21, x22, [%0, #2<<3];" + "ldp x23, x24, [%0, #4<<3];" + "ldp x25, x26, [%0, #6<<3];" + "ldp x27, x28, [%0, #8<<3];" + "ldp x29, x30, [%0, #10<<3];" + "ldp d8, d9, [%0, #14<<3];" + "ldp d10, d11, [%0, #16<<3];" + "ldp d12, d13, [%0, #18<<3];" + "ldp d14, d15, [%0, #20<<3];" + "ldr x5, [%0, #13<<3];" + "mov sp, x5;" + /* Return the value requested to return through arguments. + This should be in x1 given what we requested above. */ + "cmp %1, #0;" + "mov x0, #1;" + "csel x0, %1, x0, ne;" + "br x30;" : "+r" (env_address) : "r" (retval_tmp)); +} + +INTERCEPTOR(void, siglongjmp, sigjmp_buf env, int val) +{ + if (env[0].__mask_was_saved) + /* Restore the saved signal mask. */ + (void) sigprocmask (SIG_SETMASK, + (sigset_t *) &env[0].__saved_mask, + (sigset_t *) 0); + __hwasan_internal_longjmp (env[0].__jmpbuf, val); +} + +INTERCEPTOR(void, __libc_longjmp, jmp_buf env, int val) +{ + __hwasan_internal_longjmp (env[0].__jmpbuf, val); +} + +INTERCEPTOR(void, longjmp, jmp_buf env, int val) +{ + __hwasan_internal_longjmp (env[0].__jmpbuf, val); +} +#undef SIG_BLOCK +#undef SIG_SETMASK + +#endif // __aarch64__ #endif // HWASAN_WITH_INTERCEPTORS static void BeforeFork() { @@ -302,7 +403,6 @@ INTERCEPTOR(int, fork, void) { return pid; } - struct HwasanInterceptorContext { bool in_interceptor_scope; }; @@ -325,6 +425,11 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(fork); #if HWASAN_WITH_INTERCEPTORS +#if defined(__aarch64__) + INTERCEPT_FUNCTION(longjmp); + INTERCEPT_FUNCTION(__libc_longjmp); + INTERCEPT_FUNCTION(siglongjmp); +#endif INTERCEPT_FUNCTION(pthread_create); #endif diff --git a/libsanitizer/hwasan/hwasan_setjmp.S b/libsanitizer/hwasan/hwasan_setjmp.S new file mode 100644 index 0000000000000000000000000000000000000000..56add3e149abcc37ec23b8cdc8f4ba2cbc722c08 --- /dev/null +++ b/libsanitizer/hwasan/hwasan_setjmp.S @@ -0,0 +1,52 @@ +// We want to save the context of the calling function. +// That requires +// 1) No modification of the link register by this function. +// 2) No modification of the stack pointer by this function. +// 3) (no modification of any other saved register, but that's not really going +// to occur, and hence isn't as much of a worry). +// +// There's essentially no way to ensure that the compiler will not modify the +// stack pointer when compiling a C function. +// Hence we have to write this function in assembly. + +#if HWASAN_WITH_INTERCEPTORS && defined(__aarch64__) + +.macro ENTRY symbol + .align 2 + .global \symbol + .type \symbol\(), %function +\symbol\(): + .cfi_startproc +.endm + +.macro END symbol + .cfi_endproc + .size \symbol, .-\symbol +.endm + +ENTRY _setjmp +mov x1, #0 +b 1f +END _setjmp + +ENTRY __sigsetjmp +1: + stp x19, x20, [x0, #0<<3] + stp x21, x22, [x0, #2<<3] + stp x23, x24, [x0, #4<<3] + stp x25, x26, [x0, #6<<3] + stp x27, x28, [x0, #8<<3] + stp x29, x30, [x0, #10<<3] + stp d8, d9, [x0, #14<<3] + stp d10, d11, [x0, #16<<3] + stp d12, d13, [x0, #18<<3] + stp d14, d15, [x0, #20<<3] + mov x2, sp + str x2, [x0, #13<<3] + // We always have the second argument to __sigjmp_save (savemask) set, since + // the _setjmp function above has set it for us as `false`. + // This function is defined in hwasan_interceptors.cc + b __sigjmp_save +END __sigsetjmp + +#endif