Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp415411pxk; Thu, 3 Sep 2020 03:13:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwgxHfgx10r2/bydP8FxiTIvbk0ljdoGtBPxmv9NweHVpHNIYC5mldHpbgjrBRQHlA2T8Fj X-Received: by 2002:aa7:ca46:: with SMTP id j6mr2179029edt.155.1599127996645; Thu, 03 Sep 2020 03:13:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599127996; cv=none; d=google.com; s=arc-20160816; b=08cgoKhc8z0Inme/QSd4TfvwLcl+IL40blV6B4vY8tTXOTojouIPWPhMVHZ8wBOn88 BClXEhkV22pH0EVdIKskiok4MdfJNhOTv/zzWvwBt3jCrChkt+HuwPpYxChQr9c2I6cM Uy2/IMYVKobu6xB1lnbS9bjTuer8WFPu3caClxokZp25KuvYa1mXZAxCCcpt0I3t6f+r o4gsvwKyzlTtgCl5kMOZL7XqB9N7IKmFqoHkzNnW3oPe7r0mIysixPm+DCVkEWB9O4G+ /Sl+WOfchhqnOrM1l26rDpPCatvGLUbcGCLCvkzhuXBGLfetzGvF6nzpBXknpzf2FARN QkSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=ZoMIGTV1ctQYLL+d/T5VVcxKm6i7PknYumwT4PH/nQw=; b=iMgKugkcMzNMn64Z7b3hcWC0HaCOFG4/9k/ehsATJrRJngayE1xJJrqSJy8BgxSVpQ F0h3U3E2Y3bYfz3NEgep/g2bDC2QNwYia2MtFKIPIFWTd9MFZcxDp1DNX+z9DZW98yWd e8AP11Uc8YgsFvsbcpNYkDdNHT8a3VW+mlelgbRtEBQp2cH/zMiZIsJq6ePkt5PxP7et l6J7ngbsC2U2kukeq3G3V7SOlka0bYjhzFI5H0rReyDFNGvjjkLmJ6OTTyvVxRXYk6h/ 8XOfUXYuYWsH2dwyCzGk/EYLuw43O0JRtaD96snRQnWrrvDDo4jrK9tbfbQ4nKnkSw/q M+4A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u13si1170535edp.336.2020.09.03.03.12.50; Thu, 03 Sep 2020 03:13:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727867AbgICKMI (ORCPT + 99 others); Thu, 3 Sep 2020 06:12:08 -0400 Received: from foss.arm.com ([217.140.110.172]:58190 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725984AbgICKMG (ORCPT ); Thu, 3 Sep 2020 06:12:06 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 82327101E; Thu, 3 Sep 2020 03:12:05 -0700 (PDT) Received: from [10.57.7.89] (unknown [10.57.7.89]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A82553F68F; Thu, 3 Sep 2020 03:12:03 -0700 (PDT) Subject: Re: [PATCH 1/4] kselftests/arm64: add a basic Pointer Authentication test To: Dave Martin Cc: linux-arm-kernel@lists.infradead.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Will Deacon , boian4o1@gmail.com, Catalin Marinas , amit.kachhap@arm.com, vincenzo.frascino@arm.com, Shuah Khan References: <20200828131606.7946-1-boyan.karatotev@arm.com> <20200828131606.7946-2-boyan.karatotev@arm.com> <20200902164858.GI6642@arm.com> From: Boyan Karatotev Message-ID: Date: Thu, 3 Sep 2020 11:12:02 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20200902164858.GI6642@arm.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 02/09/2020 17:49, Dave Martin wrote: > On Fri, Aug 28, 2020 at 02:16:03PM +0100, Boyan Karatotev wrote: >> PAuth signs and verifies return addresses on the stack. It does so by >> inserting a Pointer Authentication code (PAC) into some of the unused top >> bits of an address. This is achieved by adding paciasp/autiasp instructions >> at the beginning and end of a function. >> >> This feature is partially backwards compatible with earlier versions of the >> ARM architecture. To coerce the compiler into emitting fully backwards >> compatible code the main file is compiled to target an earlier ARM version. >> This allows the tests to check for the feature and print meaningful error >> messages instead of crashing. >> >> Add a test to verify that corrupting the return address results in a >> SIGSEGV on return. >> >> Cc: Shuah Khan >> Cc: Catalin Marinas >> Cc: Will Deacon >> Signed-off-by: Boyan Karatotev >> --- >> tools/testing/selftests/arm64/Makefile | 2 +- >> .../testing/selftests/arm64/pauth/.gitignore | 1 + >> tools/testing/selftests/arm64/pauth/Makefile | 22 ++++++++++++ >> tools/testing/selftests/arm64/pauth/helper.h | 10 ++++++ >> tools/testing/selftests/arm64/pauth/pac.c | 32 +++++++++++++++++ >> .../selftests/arm64/pauth/pac_corruptor.S | 36 +++++++++++++++++++ >> 6 files changed, 102 insertions(+), 1 deletion(-) >> create mode 100644 tools/testing/selftests/arm64/pauth/.gitignore >> create mode 100644 tools/testing/selftests/arm64/pauth/Makefile >> create mode 100644 tools/testing/selftests/arm64/pauth/helper.h >> create mode 100644 tools/testing/selftests/arm64/pauth/pac.c >> create mode 100644 tools/testing/selftests/arm64/pauth/pac_corruptor.S >> >> diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile >> index 93b567d23c8b..525506fd97b9 100644 >> --- a/tools/testing/selftests/arm64/Makefile >> +++ b/tools/testing/selftests/arm64/Makefile >> @@ -4,7 +4,7 @@ >> ARCH ?= $(shell uname -m 2>/dev/null || echo not) >> >> ifneq (,$(filter $(ARCH),aarch64 arm64)) >> -ARM64_SUBTARGETS ?= tags signal >> +ARM64_SUBTARGETS ?= tags signal pauth >> else >> ARM64_SUBTARGETS := >> endif >> diff --git a/tools/testing/selftests/arm64/pauth/.gitignore b/tools/testing/selftests/arm64/pauth/.gitignore >> new file mode 100644 >> index 000000000000..b557c916720a >> --- /dev/null >> +++ b/tools/testing/selftests/arm64/pauth/.gitignore >> @@ -0,0 +1 @@ >> +pac >> diff --git a/tools/testing/selftests/arm64/pauth/Makefile b/tools/testing/selftests/arm64/pauth/Makefile >> new file mode 100644 >> index 000000000000..785c775e5e41 >> --- /dev/null >> +++ b/tools/testing/selftests/arm64/pauth/Makefile >> @@ -0,0 +1,22 @@ >> +# SPDX-License-Identifier: GPL-2.0 >> +# Copyright (C) 2020 ARM Limited >> + >> +CFLAGS += -mbranch-protection=pac-ret >> + >> +TEST_GEN_PROGS := pac >> +TEST_GEN_FILES := pac_corruptor.o >> + >> +include ../../lib.mk >> + >> +# pac* and aut* instructions are not available on architectures berfore >> +# ARMv8.3. Therefore target ARMv8.3 wherever they are used directly >> +$(OUTPUT)/pac_corruptor.o: pac_corruptor.S >> + $(CC) -c $^ -o $@ $(CFLAGS) -march=armv8.3-a >> + >> +# when -mbranch-protection is enabled and the target architecture is ARMv8.3 or >> +# greater, gcc emits pac* instructions which are not in HINT NOP space, >> +# preventing the tests from occurring at all. Compile for ARMv8.2 so tests can >> +# run on earlier targets and print a meaningful error messages >> +$(OUTPUT)/pac: pac.c $(OUTPUT)/pac_corruptor.o >> + $(CC) $^ -o $@ $(CFLAGS) -march=armv8.2-a >> + >> diff --git a/tools/testing/selftests/arm64/pauth/helper.h b/tools/testing/selftests/arm64/pauth/helper.h >> new file mode 100644 >> index 000000000000..f777f88acf0a >> --- /dev/null >> +++ b/tools/testing/selftests/arm64/pauth/helper.h >> @@ -0,0 +1,10 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* Copyright (C) 2020 ARM Limited */ >> + >> +#ifndef _HELPER_H_ >> +#define _HELPER_H_ >> + >> +void pac_corruptor(void); >> + >> +#endif >> + >> diff --git a/tools/testing/selftests/arm64/pauth/pac.c b/tools/testing/selftests/arm64/pauth/pac.c >> new file mode 100644 >> index 000000000000..ed445050f621 >> --- /dev/null >> +++ b/tools/testing/selftests/arm64/pauth/pac.c >> @@ -0,0 +1,32 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// Copyright (C) 2020 ARM Limited >> + >> +#include >> +#include >> + >> +#include "../../kselftest_harness.h" >> +#include "helper.h" >> + >> +/* >> + * Tests are ARMv8.3 compliant. They make no provisions for features present in >> + * future version of the arm architecture >> + */ >> + >> +#define ASSERT_PAUTH_ENABLED() \ >> +do { \ >> + unsigned long hwcaps = getauxval(AT_HWCAP); \ >> + /* data key instructions are not in NOP space. This prevents a SIGILL */ \ > > >> + ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \ >> +} while (0) >> + >> + >> +/* check that a corrupted PAC results in SIGSEGV */ >> +TEST_SIGNAL(corrupt_pac, SIGSEGV) >> +{ >> + ASSERT_PAUTH_ENABLED(); >> + >> + pac_corruptor(); >> +} >> + >> +TEST_HARNESS_MAIN >> + >> diff --git a/tools/testing/selftests/arm64/pauth/pac_corruptor.S b/tools/testing/selftests/arm64/pauth/pac_corruptor.S >> new file mode 100644 >> index 000000000000..6a34ec23a034 >> --- /dev/null >> +++ b/tools/testing/selftests/arm64/pauth/pac_corruptor.S >> @@ -0,0 +1,36 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* Copyright (C) 2020 ARM Limited */ >> + >> +.global pac_corruptor >> + >> +.text >> +/* >> + * Corrupting a single bit of the PAC ensures the authentication will fail. It >> + * also guarantees no possible collision. TCR_EL1.TBI0 is set by default so no >> + * top byte PAC is tested >> + */ >> + pac_corruptor: >> + paciasp >> + >> + /* make stack frame */ >> + sub sp, sp, #16 >> + stp x29, lr, [sp] > > Nit: if respinning, you can optimise a few sequences of this sort, e.g. > > stp x29, lr, [sp, #-16]! > >> + mov x29, sp >> + >> + /* prepare mask for bit to be corrupted (bit 54) */ >> + mov x1, xzr >> + add x1, x1, #1 >> + lsl x1, x1, #54 > > Nit: > > mov x1, #1 << 54 Thank you for this, didn't know I could do it this way. > > but anyway, the logic operations can encode most simple bitmasks > directly as immediate operands, so you can skip this and just do > >> + >> + /* get saved lr, corrupt selected bit, put it back */ >> + ldr x0, [sp, #8] >> + eor x0, x0, x1 > > eor x0, x0, #1 << 54 > >> + str x0, [sp, #8] >> + >> + /* remove stack frame */ >> + ldp x29, lr, [sp] >> + add sp, sp, #16 > > ldp x29, lr, [sp], #16 > > [...] > > Actually, since there are no leaf nested function calls and no trap is > expected until the function returns (so backtracing in the middle of > this function is unlikely to be needed), could we optimise this whole > thing down to the following? > I suppose you're right. The intent was to emulate a c function but there really is no point in doing all this extra work. Will change it. > pac_corruptor: > paciasp > eor lr, lr, #1 << 53 > autiasp > ret > > Cheers > ---Dave > -- Regards, Boyan