Received: by 2002:ab2:69cc:0:b0:1fd:c486:4f03 with SMTP id n12csp275033lqp; Tue, 11 Jun 2024 04:23:37 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCXDDNWE2wJRBAsIHgE2/PqrwR8WVgiGBsrgO5uMr9HXVsSr6vC+coE29JEeQxwEO4iTy380LbnFIC0wWKMTYm9Yp8dQ34MOkBvvJin8SA== X-Google-Smtp-Source: AGHT+IGuTYyaxAixqweHHAtv9BF+4x3cBqluG67YWoILRsr26kX1NJZCKNlO1YnprtXUGpEv+cX9 X-Received: by 2002:a05:6a20:258f:b0:1b8:4107:ce3a with SMTP id adf61e73a8af0-1b84107d08amr4213976637.39.1718105017109; Tue, 11 Jun 2024 04:23:37 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1718105017; cv=pass; d=google.com; s=arc-20160816; b=NFwNHvefwK7PyI+QLtBtbAqL8xu3b7RcFZMc1uklH9G9zIOC81ZChm0STKZ67I4LVv +wmxWq5I14Q6zFhmgUGS2CcKLCf2Lst8dWfx8TJAPizUbRd8e7L0pwtKgQarBeiFleZA zYHbf+AYed02H4cR+0aCrrBdWZdi+qxMpm+m5nVyquMsYrkQpdUzr0KDr/bQ5dQP1QiR L0RUVqvcVBHkeRUa3L3mSRWHVXPARmgRYoNRcFfT2RSCdqlCQKRapuc1F/a9KPUWPcBC FTdt/uHIa89Nwgx4e2dKEQYS4ImM8oIyYjDnpXuGumjZo2pH/9l0HDAsMc61gmzfp9bc 9PDA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=XeZLakCDorMoOojFDcH2XECj59Oe2S6/T2Kzg6GOr6M=; fh=nmDo0evxWwTAvBlxNELHY/fYZbxD4K9pluaUjPt1MrQ=; b=M9EO+uA6ZjEudm89Z7dY/XC9yC8/L5EwyhhfpzlYFTwLcwxTSyK0cjZqTa0s2r0KeJ yNTBmyEig8adCYi+iH31K/cDNzgJlql7iCBt8aFTGnQtk4otQ3GxHO2aSkHWPHNNqqLd NDbQ+EAcKiTvSGJrmr0qWLyo/zZZpqKcb3mgOgGEsXa/mtZzuOlzuTgJ0RFvvOStJj8C 9bCmRq1h6sm9unndtwIBifB2vOD5a/7oJ7+7jEQhxw8JtFj/vcbcuxSWZrBhMd15nUeD DI1twwLbhm4XHoEkO+ldVY0s+1Ik4/JZJq1T3ktfNDd2stLAoTY5eq4+HZyXR5tqB0xe YIWg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=C6PPmhS0; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-209720-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-209720-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id 41be03b00d2f7-6ea6c7a34casi4593709a12.29.2024.06.11.04.23.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Jun 2024 04:23:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-209720-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=C6PPmhS0; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-209720-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-209720-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id A397B285CA3 for ; Tue, 11 Jun 2024 11:23:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2815417B435; Tue, 11 Jun 2024 11:22:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="C6PPmhS0" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 352F617B406; Tue, 11 Jun 2024 11:22:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718104975; cv=none; b=RydroMzldWIiLkikdjdhE7Eif66Ta/czf7zfMkfn5LSQFaR2kZc8h+JZgg+DQqwBSC/FKBQUNSypGNQBnRKgPnoSmoJdm5X6kUBt8TCgKMEqeV6oG69Gjox8/7ZnC8uCL0RCMZL4gNW/zeNwEUF8T1OjwHw2MwKgHpHrfuwGW8k= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718104975; c=relaxed/simple; bh=uOz/aMSFQPquNtZuA2x4QffKF4wgRighKr2eGEBffRo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ad1Q2GrtOAj+oUElJUxmS8RRp78TNnXhxWhSmypO0t/nvl+z8iXst8gnFILhEucxjzGSejAvH43lkvXaGgmT5MlfykOLRW8KGbJSLFRHUBJsK2KT5hI9g5wGoX+KOpiy/CqLig79HoeFaBznrDIUlRDOSfbDtyNUlTNcJQzoxgg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=C6PPmhS0; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id F32E6C2BD10; Tue, 11 Jun 2024 11:22:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1718104975; bh=uOz/aMSFQPquNtZuA2x4QffKF4wgRighKr2eGEBffRo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C6PPmhS0yMaw7TLJPy9/H9OLmF9VRJXlwCsSO7AS4NCWNlsWUHqqX+g/LWbOAwxuo spgegUBvy270a4/PpV2jDFb/n0thCGeuRos8dTBpScXqQs6Gz30aT8ze7fuQSe0JtD jf99lYJDf4+LzDQRmZzAY5/J5wg7nsgz3dciYCSWE+BUTe2A5X0btuEyotNfdJxzzw YhUe9hoiGDB5yV1z9SzQFD6xQHT4ug6lAqhUlwYcKYk5L6XaQHHPgynGH8EJzX+j+Q OFGcWuByCNCyO3rkgvLbnzbGFUgAg912Z0Y51ZsmqbSyEQVmBGODJqj7+DQPxrgYTo 64msYDsQiioiQ== From: Jiri Olsa To: Steven Rostedt , Masami Hiramatsu , Oleg Nesterov , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-man@vger.kernel.org, x86@kernel.org, bpf@vger.kernel.org, Song Liu , Yonghong Song , John Fastabend , Peter Zijlstra , Thomas Gleixner , "Borislav Petkov (AMD)" , Ingo Molnar , Andy Lutomirski , "Edgecombe, Rick P" , Deepak Gupta Subject: [PATCHv8 bpf-next 4/9] selftests/x86: Add return uprobe shadow stack test Date: Tue, 11 Jun 2024 13:21:53 +0200 Message-ID: <20240611112158.40795-5-jolsa@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240611112158.40795-1-jolsa@kernel.org> References: <20240611112158.40795-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Adding return uprobe test for shadow stack and making sure it's working properly. Borrowed some of the code from bpf selftests. Acked-by: Andrii Nakryiko Signed-off-by: Jiri Olsa --- .../testing/selftests/x86/test_shadow_stack.c | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/tools/testing/selftests/x86/test_shadow_stack.c b/tools/testing/selftests/x86/test_shadow_stack.c index ee909a7927f9..21af54d5f4ea 100644 --- a/tools/testing/selftests/x86/test_shadow_stack.c +++ b/tools/testing/selftests/x86/test_shadow_stack.c @@ -34,6 +34,7 @@ #include #include #include +#include /* * Define the ABI defines if needed, so people can run the tests @@ -734,6 +735,144 @@ int test_32bit(void) return !segv_triggered; } +static int parse_uint_from_file(const char *file, const char *fmt) +{ + int err, ret; + FILE *f; + + f = fopen(file, "re"); + if (!f) { + err = -errno; + printf("failed to open '%s': %d\n", file, err); + return err; + } + err = fscanf(f, fmt, &ret); + if (err != 1) { + err = err == EOF ? -EIO : -errno; + printf("failed to parse '%s': %d\n", file, err); + fclose(f); + return err; + } + fclose(f); + return ret; +} + +static int determine_uprobe_perf_type(void) +{ + const char *file = "/sys/bus/event_source/devices/uprobe/type"; + + return parse_uint_from_file(file, "%d\n"); +} + +static int determine_uprobe_retprobe_bit(void) +{ + const char *file = "/sys/bus/event_source/devices/uprobe/format/retprobe"; + + return parse_uint_from_file(file, "config:%d\n"); +} + +static ssize_t get_uprobe_offset(const void *addr) +{ + size_t start, end, base; + char buf[256]; + bool found = false; + FILE *f; + + f = fopen("/proc/self/maps", "r"); + if (!f) + return -errno; + + while (fscanf(f, "%zx-%zx %s %zx %*[^\n]\n", &start, &end, buf, &base) == 4) { + if (buf[2] == 'x' && (uintptr_t)addr >= start && (uintptr_t)addr < end) { + found = true; + break; + } + } + + fclose(f); + + if (!found) + return -ESRCH; + + return (uintptr_t)addr - start + base; +} + +static __attribute__((noinline)) void uretprobe_trigger(void) +{ + asm volatile (""); +} + +/* + * This test setups return uprobe, which is sensitive to shadow stack + * (crashes without extra fix). After executing the uretprobe we fail + * the test if we receive SIGSEGV, no crash means we're good. + * + * Helper functions above borrowed from bpf selftests. + */ +static int test_uretprobe(void) +{ + const size_t attr_sz = sizeof(struct perf_event_attr); + const char *file = "/proc/self/exe"; + int bit, fd = 0, type, err = 1; + struct perf_event_attr attr; + struct sigaction sa = {}; + ssize_t offset; + + type = determine_uprobe_perf_type(); + if (type < 0) { + if (type == -ENOENT) + printf("[SKIP]\tUretprobe test, uprobes are not available\n"); + return 0; + } + + offset = get_uprobe_offset(uretprobe_trigger); + if (offset < 0) + return 1; + + bit = determine_uprobe_retprobe_bit(); + if (bit < 0) + return 1; + + sa.sa_sigaction = segv_gp_handler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa, NULL)) + return 1; + + /* Setup return uprobe through perf event interface. */ + memset(&attr, 0, attr_sz); + attr.size = attr_sz; + attr.type = type; + attr.config = 1 << bit; + attr.config1 = (__u64) (unsigned long) file; + attr.config2 = offset; + + fd = syscall(__NR_perf_event_open, &attr, 0 /* pid */, -1 /* cpu */, + -1 /* group_fd */, PERF_FLAG_FD_CLOEXEC); + if (fd < 0) + goto out; + + if (sigsetjmp(jmp_buffer, 1)) + goto out; + + ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK); + + /* + * This either segfaults and goes through sigsetjmp above + * or succeeds and we're good. + */ + uretprobe_trigger(); + + printf("[OK]\tUretprobe test\n"); + err = 0; + +out: + ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK); + signal(SIGSEGV, SIG_DFL); + if (fd) + close(fd); + return err; +} + void segv_handler_ptrace(int signum, siginfo_t *si, void *uc) { /* The SSP adjustment caused a segfault. */ @@ -926,6 +1065,12 @@ int main(int argc, char *argv[]) goto out; } + if (test_uretprobe()) { + ret = 1; + printf("[FAIL]\turetprobe test\n"); + goto out; + } + return ret; out: -- 2.45.1