From patchwork Sun Jun 23 11:23:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708570 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 1405612BF1B; Sun, 23 Jun 2024 11:26:09 +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=1719141970; cv=none; b=jsq7B0891K1fJ81VRoGyawp9Sb8kam3e576N4m9JQUOMSBoiCs6UNmwF3I0RFhpO0IFmRmbkCbZr9ZV4ZRUK1zM5Yg8YIvHqh0i2H6wKrKgZ942xvvZHMFVUsuuFjrm7NP4/NFFd9knNMiXD5lL31kIuoTmHMz1dBhE6J13eGCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719141970; c=relaxed/simple; bh=wg70GnzKrhp9dkteytxJEie2tAvypKkmqJWIs8mga50=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Ap1xeQEArV71oYmaRIqWAkRTFGe4wmTcA/ELCr2evwJf29aYfBXHw+/rNz0VoPW+KxR/6zx5FLN8trHtBOA5OVp/Oa9OY6DRlmffYsg5mqlzWd5/7ahjigdKTskoIwqrvrFkpbpb6xVZ/YIP29ordnCoRxmXY0yaGBbvaOFBURo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oAfq89hP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oAfq89hP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25A2CC4AF0D; Sun, 23 Jun 2024 11:26:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719141969; bh=wg70GnzKrhp9dkteytxJEie2tAvypKkmqJWIs8mga50=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oAfq89hP2V7Zvzi+qkcMkzK5hhZHD4wMbMVmJvWGJmmXKDqWXsDEau63viloqDc1R W2KaoxxQlKUJnfe5WdY9xy8MvU9WGRjDbAb0cVMXZwMDf7205Y1gqARDIejUZug95M 15QmGK8dlQReS3D8G9JJCpAs0FyfzhRfc8AHWcwR8TTVRLEU8nnhaNyo2MRQlN8Rvp UEzyPcZgdP86izQ+eHeqwJPXxSjNmXcEVo8+iiOkfmd324ncO6sdCpnqCS3K7F8HZg hzKjkNMkWXq85+qb7YJocbqrvkYLAHyxWq0rUfr7h+K1HAUjk56jvdc00qTfdWCMtW A54dAtebRTJcg== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:43 +0100 Subject: [PATCH RFT v6 1/9] Documentation: userspace-api: Add shadow stack API documentation Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-1-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=2837; i=broonie@kernel.org; h=from:subject:message-id; bh=wg70GnzKrhp9dkteytxJEie2tAvypKkmqJWIs8mga50=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAY+LYldXTGeJ8hQ2+ThQ+Z7M+FrBp8cmI4lrLKE cLryo6WJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGPgAKCRAk1otyXVSH0D9tB/ 4oWCxsAyuN/gQ2nuegfiWIPqYREm59mR5jOChMT0q3+9gYJLQUbelzu91ysU78+o2bTryhhf+sve/S p9+5pa1bZQzx6cfv4mdU7kX4FOlUpvKFyRK2A1z8SLkO3RMvc5IOO0n/MoW2Xwh+SAYjP8jHZXMs+q 79W2l0l+DO7Ds4oFPRq0a0mKoTvCtE2a8G7k2aFPuSn0hlUwf8GpJybXwnvMrh+X/TTqFH8fNyAHho LjK6z1qVBrb6xcleorx/em5iXwyF110OWZ2RhBtN6wjEnCSgev8df/h/eKpjcul16jPKTSKUUH/3SO +GMVWV/GVyVinsBMRF5kkj3f906d5E X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB There are a number of architectures with shadow stack features which we are presenting to userspace with as consistent an API as we can (though there are some architecture specifics). Especially given that there are some important considerations for userspace code interacting directly with the feature let's provide some documentation covering the common aspects. Signed-off-by: Mark Brown --- Documentation/userspace-api/index.rst | 1 + Documentation/userspace-api/shadow_stack.rst | 41 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst index 5926115ec0ed..d60a6dc0cbcf 100644 --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst @@ -59,6 +59,7 @@ Everything else ELF netlink/index + shadow_stack sysfs-platform_profile vduse futex2 diff --git a/Documentation/userspace-api/shadow_stack.rst b/Documentation/userspace-api/shadow_stack.rst new file mode 100644 index 000000000000..c576ad3d7ec1 --- /dev/null +++ b/Documentation/userspace-api/shadow_stack.rst @@ -0,0 +1,41 @@ +============= +Shadow Stacks +============= + +Introduction +============ + +Several architectures have features which provide backward edge +control flow protection through a hardware maintained stack, only +writeable by userspace through very limited operations. This feature +is referred to as shadow stacks on Linux, on x86 it is part of Intel +Control Enforcement Technology (CET), on arm64 it is Guarded Control +Stacks feature (FEAT_GCS) and for RISC-V it is the Zicfiss extension. +It is expected that this feature will normally be managed by the +system dynamic linker and libc in ways broadly transparent to +application code, this document covers interfaces and considerations. + + +Enabling +======== + +Shadow stacks default to disabled when a userspace process is +executed, they can be enabled for the current thread with a syscall: + + - For x86 the ARCH_SHSTK_ENABLE arch_prctl() + +It is expected that this will normally be done by the dynamic linker. +Any new threads created by a thread with shadow stacks enabled will +themselves have shadow stacks enabled. + + +Enablement considerations +========================= + +- Returning from the function that enables shadow stacks without first + disabling them will cause a shadow stack exception. This includes + any syscall wrapper or other library functions, the syscall will need + to be inlined. +- A lock feature allows userspace to prevent disabling of shadow stacks. +- Those that change the stack context like longjmp() or use of ucontext + changes on signal return will need support from libc. From patchwork Sun Jun 23 11:23:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708571 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 BC6B112F5A0; Sun, 23 Jun 2024 11:26:15 +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=1719141975; cv=none; b=UO3aQd8QDog4E+YyydbZIOcfTJxKG+hStkCWIUiXUP7WBT4G0C0aMkBSJwSQ9BhWTqLjK+LVl9Gk9tP1L/I1VOBIEEmMzWX19R85X01zr2sXWHIw6YvhtfsWEWYnkbWop/nTHgqa1BTiEbw4QHySAK08+M7bSrugmUYMD4r2BJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719141975; c=relaxed/simple; bh=vdpMp/+tnPvEc9LtWm/ZG/N3nxsEXfR9pkA/QLvguxA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dMz3FmXyndalEqewVhhPL6JFYJDf6XhDnI0pEn6rqC4orksercEctdQKHzNlJgrByXNTuXV/nDHLCl5HQr4YLpXBa21nQ7vVN68QfhrPCShSK3oyLZ1BGzXx8Tl3lArcb9cJeiy3FncW8QHgqEbGV8SA7KsXyO8f7Gz11rhflQ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SS73007s; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SS73007s" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E84AC2BD10; Sun, 23 Jun 2024 11:26:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719141975; bh=vdpMp/+tnPvEc9LtWm/ZG/N3nxsEXfR9pkA/QLvguxA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SS73007sXpGrFYgeeVqYMkqLQRsjqSpp+E5s13Nb4eFA3vCYoTVVAOe0zfZJXWorv 0IHFQs38qF5UHgj7aguVjZak4VrPElWXGuDEBJI0ljvYRvUvSMVMNG3B6N2JRO61l8 6HgadLv0NKBnmbQ7fGu/CEmSEW4jKC83nm/KQdH6SrPkbr5H9tNRIfSOuQfdTcZ4Sq Lydmf7HnxosKUmSahC3qJCT+W1YcmNXPOFnZiYsg+7EzJNiWX/1woZb3KXLHO5Ykav RU/RO9rFaivtRJnXYcAw+J8v+5462OgXvFtdE353abrFqUtjLy2kg40SxP+mphS7p1 Io+Fae55I3Vig== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:44 +0100 Subject: [PATCH RFT v6 2/9] selftests: Provide helper header for shadow stack testing Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-2-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=2590; i=broonie@kernel.org; h=from:subject:message-id; bh=vdpMp/+tnPvEc9LtWm/ZG/N3nxsEXfR9pkA/QLvguxA=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAY/iyJ36oAkQ+01RwmYOsHL/R0DgvRMZuhj+hnp V5Y7qEeJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGPwAKCRAk1otyXVSH0OnlB/ 9jHwEVByCzimHbnZtHu5Egj3RWJ/+NSl/rryKln0lQhh4oRNQo6KoalkNXkkg//lbRWS8oiccA2t5S 6kFDwzI0WOHpoYLsx1NnP8DuyzvcWLCZQAbyy5Pgh6UTwE0yDCni/4thIbm6GpaVvOdey70t/qtC4f z9/14xn10BE4S278lOv+wEJmk7oQrrWOE3UdVf+ZUjk+fierSxM04vr3pYfne682+RkNyMNYGLFwbz Y4GqrGlkE96jm0pYLelp8jj7JL/9sL4Xdto7uyuM6itGUcC/iU8Z0so2UuzdExLlu/gTlw7EIdATdj y76x/CrpDWIhswQy/OBwnVLowAvKfp X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB While almost all users of shadow stacks should be relying on the dynamic linker and libc to enable the feature there are several low level test programs where it is useful to enable without any libc support, allowing testing without full system enablement. This low level testing is helpful during bringup of the support itself, and also in enabling coverage by automated testing without needing all system components in the target root filesystems to have enablement. Provide a header with helpers for this purpose, intended for use only by test programs directly exercising shadow stack interfaces. Reviewed-by: Rick Edgecombe Signed-off-by: Mark Brown --- tools/testing/selftests/ksft_shstk.h | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tools/testing/selftests/ksft_shstk.h b/tools/testing/selftests/ksft_shstk.h new file mode 100644 index 000000000000..85d0747c1802 --- /dev/null +++ b/tools/testing/selftests/ksft_shstk.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Helpers for shadow stack enablement, this is intended to only be + * used by low level test programs directly exercising interfaces for + * working with shadow stacks. + * + * Copyright (C) 2024 ARM Ltd. + */ + +#ifndef __KSFT_SHSTK_H +#define __KSFT_SHSTK_H + +#include + +/* This is currently only defined for x86 */ +#ifndef SHADOW_STACK_SET_TOKEN +#define SHADOW_STACK_SET_TOKEN (1ULL << 0) +#endif + +static bool shadow_stack_enabled; + +#ifdef __x86_64__ +#define ARCH_SHSTK_ENABLE 0x5001 +#define ARCH_SHSTK_SHSTK (1ULL << 0) + +#define ARCH_PRCTL(arg1, arg2) \ +({ \ + long _ret; \ + register long _num asm("eax") = __NR_arch_prctl; \ + register long _arg1 asm("rdi") = (long)(arg1); \ + register long _arg2 asm("rsi") = (long)(arg2); \ + \ + asm volatile ( \ + "syscall\n" \ + : "=a"(_ret) \ + : "r"(_arg1), "r"(_arg2), \ + "0"(_num) \ + : "rcx", "r11", "memory", "cc" \ + ); \ + _ret; \ +}) + +#define ENABLE_SHADOW_STACK +static inline __attribute__((always_inline)) void enable_shadow_stack(void) +{ + int ret = ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK); + if (ret == 0) + shadow_stack_enabled = true; +} + +#endif + +#ifndef __NR_map_shadow_stack +#define __NR_map_shadow_stack 453 +#endif + +#ifndef ENABLE_SHADOW_STACK +static inline void enable_shadow_stack(void) { } +#endif + +#endif + + From patchwork Sun Jun 23 11:23:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708572 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 E04FA12FB2F; Sun, 23 Jun 2024 11:26:21 +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=1719141982; cv=none; b=Gl0ckdiyuc31rZ9kjAuPtgE8kghGL9YDahu3PZrj7iiC9hEp9II1hUA2ZPLD+u/1/oZzpsWTp9VvG+xrp88KSSoKWJnhMW6XnMm01xv3GgmVGwa4LJNbHGj4Js+mrCzml7xirh+dpIMJ2gfispDxrmRJhFZWxbabZieQPcw6V34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719141982; c=relaxed/simple; bh=+PP7awu1pf/fG6tcaOdbFq8gDfVEQNboirY/ny0xMww=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mqyUziaZ9Dr34q0qr5CmRvHxKUHvJTee4ueTb1qKZFQFcXsj/rYRSNYhAyxPZ27GpVpd1xRKK7tzIpRwjPKLH5R+EgiteDXGm+R3rjxqg56WNTKIIRoLq393XfFhgXwCh/4NPwO58tSqmRP7SyX6NnYJV0hnwNghEFI1PuaKvY8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=H0r6uerl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="H0r6uerl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11F5FC4AF0A; Sun, 23 Jun 2024 11:26:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719141981; bh=+PP7awu1pf/fG6tcaOdbFq8gDfVEQNboirY/ny0xMww=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=H0r6uerltPnfEq1VtK/OllBbSkAWbUCOTFZ6W1zCos7T9+sNn4UwUrrLW9A+4OQUR ajFuSs/ejl5VKIWBT75tpM3SF1MbSRkh4f27GVCqJnmZIetdp4rfrv+hjheimHjbPA BX60jBXDeRN0K9jpHCnBKIlVuxb0XpvLlbezraC9+unyOZcRfCMk9aW4X79+4whyvD 8OiPGr05yDn5s+hpwK7VaWHuKOtuMv7O28ID5M59Ftk7tmPsKFely9VIW7+WxDQfGG 8or/XijzOYjcTmL+iI9sy9I9438q6N8HmtrSlFAaAT0DFEaI1k/hYx6hxJJ/4wH6Hy ybHWJ7srtt3XA== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:45 +0100 Subject: [PATCH RFT v6 3/9] mm: Introduce ARCH_HAS_USER_SHADOW_STACK Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-3-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook , David Hildenbrand X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=2437; i=broonie@kernel.org; h=from:subject:message-id; bh=+PP7awu1pf/fG6tcaOdbFq8gDfVEQNboirY/ny0xMww=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZAkwpp+R8wFIKgWo2CycAiyTshvHjPn/iDZmop jlzBrJSJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGQAAKCRAk1otyXVSH0Pk6B/ 0bGimYO7ZisG6Hh4arA8DQuFSyN8VsytcZkbccpGW0gw7qz3FKlGBF4L0dlty/LTH14EUMeWDMsP8Z eOB1lD0lwL9ZHS0GZx1l5d78yAR9u2QB8Ln2wvlP7C3zDlhVOqkJR4uREQn3hKm/CdnA5+JZJHtPth IQwUItWLRnOApQ3qhDI2IqK4GOcJL9/iLXVck94NG/4MbxbLC//wMy+K76dcmIbBO/yPM1d8/yMiW8 DzmlEdlqLNKfYxzU6EYxgpB1Euq4tOvEP2ky7tXVNFS2w+QUSnQqRybE9UZxcH3lq16hxh3BugH/rE ggIUSE61xfmZIRyKh/tnBxJSpS+ior X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Since multiple architectures have support for shadow stacks and we need to select support for this feature in several places in the generic code provide a generic config option that the architectures can select. Suggested-by: David Hildenbrand Acked-by: David Hildenbrand Reviewed-by: Deepak Gupta Reviewed-by: Rick Edgecombe Signed-off-by: Mark Brown --- arch/x86/Kconfig | 1 + fs/proc/task_mmu.c | 2 +- include/linux/mm.h | 2 +- mm/Kconfig | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1d7122a1883e..4a5e40d4c14e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1949,6 +1949,7 @@ config X86_USER_SHADOW_STACK depends on AS_WRUSS depends on X86_64 select ARCH_USES_HIGH_VMA_FLAGS + select ARCH_HAS_USER_SHADOW_STACK select X86_CET help Shadow stack protection is a hardware feature that detects function diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index f8d35f993fe5..1b56c1077507 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -704,7 +704,7 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR [ilog2(VM_UFFD_MINOR)] = "ui", #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ -#ifdef CONFIG_X86_USER_SHADOW_STACK +#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK [ilog2(VM_SHADOW_STACK)] = "ss", #endif }; diff --git a/include/linux/mm.h b/include/linux/mm.h index 9849dfda44d4..5ec7bc355657 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -342,7 +342,7 @@ extern unsigned int kobjsize(const void *objp); #endif #endif /* CONFIG_ARCH_HAS_PKEYS */ -#ifdef CONFIG_X86_USER_SHADOW_STACK +#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK /* * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of * support core mm. diff --git a/mm/Kconfig b/mm/Kconfig index b4cb45255a54..45416916dec1 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1249,6 +1249,12 @@ config IOMMU_MM_DATA config EXECMEM bool +config ARCH_HAS_USER_SHADOW_STACK + bool + help + The architecture has hardware support for userspace shadow call + stacks (eg, x87 CET, arm64 GCS or RISC-V Zicfiss). + source "mm/damon/Kconfig" endmenu From patchwork Sun Jun 23 11:23:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708573 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 0FE5B12FB2F; Sun, 23 Jun 2024 11:26:27 +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=1719141988; cv=none; b=bcmqNsjNIUMoNUai5kKUjIGxNZ8WBRubezHbjRP76W8CHrSMQ20dxE85Qtmnw5VWx1Rzfvv3wH0w9eQmfdTB+XVEWRGM5hmoXlJ9BDFyNAZ19d8klwGwKqwYkHvmZctrY0RaZp1PZXJVsW8w/TLROE1C42DZjHalSTUyCuCKStc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719141988; c=relaxed/simple; bh=vgYZJQTtzTV+0K6VAfXB2QvqhBocp9Mhfxvvr3RAmRE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fad890hiUa6RHIEY8Yg6eNhhNbgqagKlazBLrOsTSFF2RT0NiMq8U5ZOqzEq7YfnC9hNTKFCdnpmR6VS70Umuieprvl+g8IJ12MSWIujCGNbqvhHbRN2qel8WurkrpeQIwKA/xzdxWsmY/ikBA07RNjbyw70uue8wq1CTNUBOaU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tjty4ucT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tjty4ucT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 288FAC2BD10; Sun, 23 Jun 2024 11:26:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719141987; bh=vgYZJQTtzTV+0K6VAfXB2QvqhBocp9Mhfxvvr3RAmRE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tjty4ucTxRC1OVKOmat2S9/tD8jfs5v1DX1YxCasckKPe8aG2NJeEPpBu/vIMdE+A gJmWAh+oJWbZ2nSGMFRkQqGxnv73ntiFaSED2dAxOeEFOVIpvMhucx354dNRBu0wcX P0GTmlCdrsPvGOJoOiZASCms+k9e/npSZNus7GE9Ii5u9uNZCqC5RzAaBn6EwxSwQb OgXigpwd9aIimEJHkI4pVMF+1kpWuuDbaFMViV7rwAa80+Yfew4j3WWIlX4N4APG5U e1eCsRMyYQNzvZ18wMIQOxK5B2uv/HILZaAtKYVaGrt18UNjJeOaVdLIs3gpYw8HwI hqcj78l/6lkOg== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:46 +0100 Subject: [PATCH RFT v6 4/9] fork: Add shadow stack support to clone3() Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-4-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=14271; i=broonie@kernel.org; h=from:subject:message-id; bh=vgYZJQTtzTV+0K6VAfXB2QvqhBocp9Mhfxvvr3RAmRE=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZB6kG8u5JhU7xUMDkJBd03vKjTYvP5UsAJ6l96 2zf9JlSJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGQQAKCRAk1otyXVSH0ApBB/ 4idJbZOorp/g41oJsCveltBI1aI2lFLuLRRxIFZ+UdvX+luw0gATNHauJp1RwvgNQwcd7sogivrBcy J3wcDZY4n1cZTMhbt3lrrfFhy1cdi7xnajoLPHgjrmXU23bT8t2JtxT5J8pMtZsLEpSQtlrxo06J4d GMJWR1z0jD2h0cp5t4CtE9R3Qc5vf+OKbFiHVvCo9bW0Z+5DSiBO2ZiA7nszl3dj2XyGqVD/cj5nE6 xbj/1mh2GjDx0yK/Fmbe/STqCssJi3xQ1rS7VpQKUay6WOcBUyTfD3tMDMoOJRHgybFtVtJH6Uc7zT 8BiflZbEtWSMnS9KNvYG1i7T5Q+TAN X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Unlike with the normal stack there is no API for configuring the the shadow stack for a new thread, instead the kernel will dynamically allocate a new shadow stack with the same size as the normal stack. This appears to be due to the shadow stack series having been in development since before the more extensible clone3() was added rather than anything more deliberate. Add parameters to clone3() specifying the location and size of a shadow stack for the newly created process. If no shadow stack is specified then the existing implicit allocation behaviour is maintained. If a stack is specified then it is required to have an architecture defined token placed on the stack, this will be consumed by the new task. If the token is not provided then this will be reported as a segmentation fault with si_code SEGV_CPERR, as a runtime shadow stack protection error would be. This allows architectures to implement the validation of the token in the child process context. If the architecture does not support shadow stacks the shadow stack parameters must be zero, architectures that do support the feature are expected to enforce the same requirement on individual systems that lack shadow stack support. Update the existing x86 implementation to pay attention to the newly added arguments, in order to maintain compatibility we use the existing behaviour if no shadow stack is specified. Minimal validation is done of the supplied parameters, detailed enforcement is left to when the thread is executed. Since we are now using more fields from the kernel_clone_args we pass that into the shadow stack code rather than individual fields. At present this implementation does not consume the shadow stack token atomically as would be desirable, it uses a separate read and write. Signed-off-by: Mark Brown --- arch/x86/include/asm/shstk.h | 11 +++-- arch/x86/kernel/process.c | 2 +- arch/x86/kernel/shstk.c | 104 +++++++++++++++++++++++++++++++++---------- include/linux/sched/task.h | 13 ++++++ include/uapi/linux/sched.h | 13 ++++-- kernel/fork.c | 76 ++++++++++++++++++++++++++----- 6 files changed, 176 insertions(+), 43 deletions(-) diff --git a/arch/x86/include/asm/shstk.h b/arch/x86/include/asm/shstk.h index 42fee8959df7..8be7b0a909c3 100644 --- a/arch/x86/include/asm/shstk.h +++ b/arch/x86/include/asm/shstk.h @@ -6,6 +6,7 @@ #include struct task_struct; +struct kernel_clone_args; struct ksignal; #ifdef CONFIG_X86_USER_SHADOW_STACK @@ -16,8 +17,8 @@ struct thread_shstk { long shstk_prctl(struct task_struct *task, int option, unsigned long arg2); void reset_thread_features(void); -unsigned long shstk_alloc_thread_stack(struct task_struct *p, unsigned long clone_flags, - unsigned long stack_size); +unsigned long shstk_alloc_thread_stack(struct task_struct *p, + const struct kernel_clone_args *args); void shstk_free(struct task_struct *p); int setup_signal_shadow_stack(struct ksignal *ksig); int restore_signal_shadow_stack(void); @@ -26,8 +27,10 @@ static inline long shstk_prctl(struct task_struct *task, int option, unsigned long arg2) { return -EINVAL; } static inline void reset_thread_features(void) {} static inline unsigned long shstk_alloc_thread_stack(struct task_struct *p, - unsigned long clone_flags, - unsigned long stack_size) { return 0; } + const struct kernel_clone_args *args) +{ + return 0; +} static inline void shstk_free(struct task_struct *p) {} static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; } static inline int restore_signal_shadow_stack(void) { return 0; } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index b8441147eb5e..f206e997f91d 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -207,7 +207,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) * is disabled, new_ssp will remain 0, and fpu_clone() will know not to * update it. */ - new_ssp = shstk_alloc_thread_stack(p, clone_flags, args->stack_size); + new_ssp = shstk_alloc_thread_stack(p, args); if (IS_ERR_VALUE(new_ssp)) return PTR_ERR((void *)new_ssp); diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c index 6f1e9883f074..953cc0893097 100644 --- a/arch/x86/kernel/shstk.c +++ b/arch/x86/kernel/shstk.c @@ -191,44 +191,102 @@ void reset_thread_features(void) current->thread.features_locked = 0; } -unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, unsigned long clone_flags, - unsigned long stack_size) +int arch_shstk_post_fork(struct task_struct *t, struct kernel_clone_args *args) +{ + /* + * SSP is aligned, so reserved bits and mode bit are a zero, just mark + * the token 64-bit. + */ + struct mm_struct *mm; + unsigned long addr; + u64 expected; + u64 val; + int ret = -EINVAL;; + + addr = args->shadow_stack + args->shadow_stack_size - sizeof(u64); + expected = (addr - SS_FRAME_SIZE) | BIT(0); + + mm = get_task_mm(t); + if (!mm) + return -EFAULT; + + /* This should really be an atomic cpmxchg. It is not. */ + if (access_remote_vm(mm, addr, &val, sizeof(val), + FOLL_FORCE) != sizeof(val)) + goto out; + + if (val != expected) + goto out; + val = 0; + if (access_remote_vm(mm, addr, &val, sizeof(val), + FOLL_FORCE | FOLL_WRITE) != sizeof(val)) + goto out; + + ret = 0; + +out: + mmput(mm); + return ret; +} + +unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, + const struct kernel_clone_args *args) { struct thread_shstk *shstk = &tsk->thread.shstk; + unsigned long clone_flags = args->flags; unsigned long addr, size; /* * If shadow stack is not enabled on the new thread, skip any - * switch to a new shadow stack. + * implicit switch to a new shadow stack and reject attempts to + * explciitly specify one. */ - if (!features_enabled(ARCH_SHSTK_SHSTK)) - return 0; + if (!features_enabled(ARCH_SHSTK_SHSTK)) { + if (args->shadow_stack || args->shadow_stack_size) + return (unsigned long)ERR_PTR(-EINVAL); - /* - * For CLONE_VFORK the child will share the parents shadow stack. - * Make sure to clear the internal tracking of the thread shadow - * stack so the freeing logic run for child knows to leave it alone. - */ - if (clone_flags & CLONE_VFORK) { - shstk->base = 0; - shstk->size = 0; return 0; } /* - * For !CLONE_VM the child will use a copy of the parents shadow - * stack. + * If the user specified a shadow stack then do some basic + * validation and use it, otherwise fall back to a default + * shadow stack size if the clone_flags don't indicate an + * allocation is unneeded. */ - if (!(clone_flags & CLONE_VM)) - return 0; + if (args->shadow_stack) { + addr = args->shadow_stack; + size = args->shadow_stack_size; + } else { + /* + * For CLONE_VFORK the child will share the parents + * shadow stack. Make sure to clear the internal + * tracking of the thread shadow stack so the freeing + * logic run for child knows to leave it alone. + */ + if (clone_flags & CLONE_VFORK) { + shstk->base = 0; + shstk->size = 0; + return 0; + } - size = adjust_shstk_size(stack_size); - addr = alloc_shstk(0, size, 0, false); - if (IS_ERR_VALUE(addr)) - return addr; + /* + * For !CLONE_VM the child will use a copy of the + * parents shadow stack. + */ + if (!(clone_flags & CLONE_VM)) + return 0; - shstk->base = addr; - shstk->size = size; + size = args->stack_size; + size = adjust_shstk_size(size); + addr = alloc_shstk(0, size, 0, false); + if (IS_ERR_VALUE(addr)) + return addr; + + /* We allocated the shadow stack, we should deallocate it. */ + shstk->base = addr; + shstk->size = size; + } return addr + size; } diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index d362aacf9f89..56b2013d7fe5 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -43,6 +43,8 @@ struct kernel_clone_args { void *fn_arg; struct cgroup *cgrp; struct css_set *cset; + unsigned long shadow_stack; + unsigned long shadow_stack_size; }; /* @@ -230,4 +232,15 @@ static inline void task_unlock(struct task_struct *p) DEFINE_GUARD(task_lock, struct task_struct *, task_lock(_T), task_unlock(_T)) +#ifdef CONFIG_ARCH_HAS_USER_SHADOW_STACK +int arch_shstk_post_fork(struct task_struct *p, + struct kernel_clone_args *args); +#else +static inline int arch_shstk_post_fork(struct task_struct *p, + struct kernel_clone_args *args) +{ + return 0; +} +#endif + #endif /* _LINUX_SCHED_TASK_H */ diff --git a/include/uapi/linux/sched.h b/include/uapi/linux/sched.h index 3bac0a8ceab2..8b7af52548fd 100644 --- a/include/uapi/linux/sched.h +++ b/include/uapi/linux/sched.h @@ -84,6 +84,10 @@ * kernel's limit of nested PID namespaces. * @cgroup: If CLONE_INTO_CGROUP is specified set this to * a file descriptor for the cgroup. + * @shadow_stack: Pointer to the memory allocated for the child + * shadow stack. + * @shadow_stack_size: Specify the size of the shadow stack for + * the child process. * * The structure is versioned by size and thus extensible. * New struct members must go at the end of the struct and @@ -101,12 +105,15 @@ struct clone_args { __aligned_u64 set_tid; __aligned_u64 set_tid_size; __aligned_u64 cgroup; + __aligned_u64 shadow_stack; + __aligned_u64 shadow_stack_size; }; #endif -#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ -#define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */ -#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ +#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ +#define CLONE_ARGS_SIZE_VER1 80 /* sizeof second published struct */ +#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ +#define CLONE_ARGS_SIZE_VER3 104 /* sizeof fourth published struct */ /* * Scheduling policies diff --git a/kernel/fork.c b/kernel/fork.c index 99076dbe27d8..d7c5769942f8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -125,6 +125,11 @@ */ #define MAX_THREADS FUTEX_TID_MASK +/* + * Require that shadow stacks can store at least one element + */ +#define SHADOW_STACK_SIZE_MIN sizeof(void *) + /* * Protected counters by write_lock_irq(&tasklist_lock) */ @@ -2745,6 +2750,19 @@ struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node) return copy_process(NULL, 0, node, &args); } +static void shstk_post_fork(struct task_struct *p, + struct kernel_clone_args *args) +{ + if (!IS_ENABLED(CONFIG_ARCH_HAS_USER_SHADOW_STACK)) + return; + + if (!args->shadow_stack) + return; + + if (arch_shstk_post_fork(p, args) != 0) + force_sig_fault_to_task(SIGSEGV, SEGV_CPERR, NULL, p); +} + /* * Ok, this is the main fork-routine. * @@ -2806,6 +2824,8 @@ pid_t kernel_clone(struct kernel_clone_args *args) */ trace_sched_process_fork(current, p); + shstk_post_fork(p, args); + pid = get_task_pid(p, PIDTYPE_PID); nr = pid_vnr(pid); @@ -2957,7 +2977,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, CLONE_ARGS_SIZE_VER1); BUILD_BUG_ON(offsetofend(struct clone_args, cgroup) != CLONE_ARGS_SIZE_VER2); - BUILD_BUG_ON(sizeof(struct clone_args) != CLONE_ARGS_SIZE_VER2); + BUILD_BUG_ON(offsetofend(struct clone_args, shadow_stack_size) != + CLONE_ARGS_SIZE_VER3); + BUILD_BUG_ON(sizeof(struct clone_args) != CLONE_ARGS_SIZE_VER3); if (unlikely(usize > PAGE_SIZE)) return -E2BIG; @@ -2990,16 +3012,18 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs, return -EINVAL; *kargs = (struct kernel_clone_args){ - .flags = args.flags, - .pidfd = u64_to_user_ptr(args.pidfd), - .child_tid = u64_to_user_ptr(args.child_tid), - .parent_tid = u64_to_user_ptr(args.parent_tid), - .exit_signal = args.exit_signal, - .stack = args.stack, - .stack_size = args.stack_size, - .tls = args.tls, - .set_tid_size = args.set_tid_size, - .cgroup = args.cgroup, + .flags = args.flags, + .pidfd = u64_to_user_ptr(args.pidfd), + .child_tid = u64_to_user_ptr(args.child_tid), + .parent_tid = u64_to_user_ptr(args.parent_tid), + .exit_signal = args.exit_signal, + .stack = args.stack, + .stack_size = args.stack_size, + .tls = args.tls, + .set_tid_size = args.set_tid_size, + .cgroup = args.cgroup, + .shadow_stack = args.shadow_stack, + .shadow_stack_size = args.shadow_stack_size, }; if (args.set_tid && @@ -3040,6 +3064,34 @@ static inline bool clone3_stack_valid(struct kernel_clone_args *kargs) return true; } +/** + * clone3_shadow_stack_valid - check and prepare shadow stack + * @kargs: kernel clone args + * + * Verify that shadow stacks are only enabled if supported. + */ +static inline bool clone3_shadow_stack_valid(struct kernel_clone_args *kargs) +{ + if (kargs->shadow_stack) { + if (!kargs->shadow_stack_size) + return false; + + if (kargs->shadow_stack_size < SHADOW_STACK_SIZE_MIN) + return false; + + if (kargs->shadow_stack_size > rlimit(RLIMIT_STACK)) + return false; + + /* + * The architecture must check support on the specific + * machine. + */ + return IS_ENABLED(CONFIG_ARCH_HAS_USER_SHADOW_STACK); + } else { + return !kargs->shadow_stack_size; + } +} + static bool clone3_args_valid(struct kernel_clone_args *kargs) { /* Verify that no unknown flags are passed along. */ @@ -3062,7 +3114,7 @@ static bool clone3_args_valid(struct kernel_clone_args *kargs) kargs->exit_signal) return false; - if (!clone3_stack_valid(kargs)) + if (!clone3_stack_valid(kargs) || !clone3_shadow_stack_valid(kargs)) return false; return true; From patchwork Sun Jun 23 11:23:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708574 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 EA3F2135A6C; Sun, 23 Jun 2024 11:26:33 +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=1719141994; cv=none; b=GnJGlkErEC/BiNrJxGh3bxn/cTN7ZMOFMcfVo5VxAI76xuOD2dn4004X+lbDNWwYUgyeArgInJ7L/1mswRtfM2QZOUVaIWW32nuc1ltn9RqodokMgjyqE+E1tsHawc8cW6BhDmfpX2IO+UuliXkftVVAQtHpCfcKZongjosWYgA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719141994; c=relaxed/simple; bh=A6PuiVWBdiPH6Nr/YX1UnFJ8RTIAC1FidWNruHY9Zks=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gtfbsfsYMMs/w9ssXq2+7hR0BxDVgaYr9Yj1/KwUXNipp95gBnvk/dbECwx2sA2uKWAW5gqIymTAl2tRSX2B8hqehD3z9tKi/G8bQkHmmT8YV8xQyBdjbAZXD/5plkqyz/6k79AAgJhLcW3qp5fADSn2HLoEk8dP+juSbaLvRBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NGjsBkwI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NGjsBkwI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 111FFC4AF0F; Sun, 23 Jun 2024 11:26:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719141993; bh=A6PuiVWBdiPH6Nr/YX1UnFJ8RTIAC1FidWNruHY9Zks=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=NGjsBkwIcvBhTSmRb8zXzzpwfmks29t54lBO5zwqYR1uD1dmFeWtH7zjyDEOrh9YH j7MXeL0EDzzImO9A5giZ7ir7bgBhYz/REwLGTQZnUErCZVDy4/OOXFfEzpZAiEcW5s bNWRjw1QnmsxHJoCuiJoi9Z+bG4w1ofUPfdHjGutNcYbFy6MOiMHbLK9bZi9bqJo8j vf8Ii4mM7cz3TDWQUchS1vAgw/o7ogMqAqVxRiIUPxHhmhthOZowMftFEgO+5TK2WS 83tlqrfZec2Y91oSzLlEkUdqG6C6DxPiGhFUvNeqkZoeDdU5F/b0ce5ybNI3SK8Ga6 IPwuX+c/J2ZPA== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:47 +0100 Subject: [PATCH RFT v6 5/9] selftests/clone3: Remove redundant flushes of output streams Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-5-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=926; i=broonie@kernel.org; h=from:subject:message-id; bh=A6PuiVWBdiPH6Nr/YX1UnFJ8RTIAC1FidWNruHY9Zks=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZBbxtMxkm5nJrZt3r3WGuB46BeS32RoItol67u OvGTisWJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGQQAKCRAk1otyXVSH0CD1B/ 49gxwS5b9BoCUU9Ib5yucTVOuhEDooM9ckUWmw898AfP1G2Nk2J6S0JfBhDmGDxWtDoRrmsKL+BW+7 xxkqLzgDdXb1xmM9yLrI10e0bOQ2SSy531HlsT8D0d2CFKaqoLZqtqyadFcfJAl4qi3nkg5UNNv70H J+Zy822syXvd3awup2/HiXlTcvL6YI6d2yxq40QiT9Q8TvnubKZryi4TDE0SYF5rK/5/xFAw1XKoQG NGclsCd2NQ1mgoadOYmgbUlm+u0v2Te0u6kNDrEEmvIykb/wBaNmf65CVVEy7KZoVXrYmijkwOZxVs R5jWH64jz9VtFMxcyycLzV4pICbFiT X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Since there were widespread issues with output not being flushed the kselftest framework was modified to explicitly set the output streams unbuffered in commit 58e2847ad2e6 ("selftests: line buffer test program's stdout") so there is no need to explicitly flush in the clone3 tests. Signed-off-by: Mark Brown --- tools/testing/selftests/clone3/clone3_selftests.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/testing/selftests/clone3/clone3_selftests.h index 3d2663fe50ba..39b5dcba663c 100644 --- a/tools/testing/selftests/clone3/clone3_selftests.h +++ b/tools/testing/selftests/clone3/clone3_selftests.h @@ -35,8 +35,6 @@ struct __clone_args { static pid_t sys_clone3(struct __clone_args *args, size_t size) { - fflush(stdout); - fflush(stderr); return syscall(__NR_clone3, args, size); } From patchwork Sun Jun 23 11:23:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708575 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 8AF6112F37B; Sun, 23 Jun 2024 11:26:39 +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=1719141999; cv=none; b=Hjqr7D9UxhvWIbMDov9BAVxl61S35TPfF1QMiIVwdAWCLdVX6xj4qxYZ1vF5vfV5rpwxHoNLE4YCK9lpFm3STJPbVjlvBLci0J8N9d0hEWBaE6kW7/xllzVkEctvWCXFj6GAVedndM7y2eSBavm5TZy8pJzqQfjTBnwp/WX4sNE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719141999; c=relaxed/simple; bh=7/H/C/HH1SlOixEC1xQKfbpAfSVTyHxGoHTFJYjOHFU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fPjzTAr+S0oRMP93dKFAN7M3s4p/qQqVJhKOrgMJYau1XcmjNfvJXhZzSvNpCnj/VqoI0Fx+dENoFfItXe16TOL+dn3zOxlpcgeIfr8PGc8MYzfx3gEKEto9w2d8+5Rs4PVw0YeyzioItoar9k6sp+d5MSGaHe+CqLnxKUf60lA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=I7IEHGix; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="I7IEHGix" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EB8C4C32782; Sun, 23 Jun 2024 11:26:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719141999; bh=7/H/C/HH1SlOixEC1xQKfbpAfSVTyHxGoHTFJYjOHFU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=I7IEHGixAPs2a6q8MLdK2jf3cqsyOO8ijhPK/5AHhZipeIWQgSzeYgTYX9+URYdI8 tLr327go1wYNpTcpSfNcbb41pbf1XWVjbPIt2947ScnL3RwJwcjeYQ9xh867IHkJpw ktFn9XOBztPupsLyp77bhlfBdd/DA2EQc80ii6r8OXQ2kQySw0Y06p3s8xvsoKB+03 34693blvECySL6E/l/2OXY4LTH13dtHXol8L0XZja/Nz29BK0VJD+L0VKvTYEJIb1l 1Mi28Qlimw151CRNC99N8uLI992qOuzujVNmT3ZTlPbltVh53ZIEe3bT26bbTAXLTJ LhxTkfywloT8g== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:48 +0100 Subject: [PATCH RFT v6 6/9] selftests/clone3: Factor more of main loop into test_clone3() Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-6-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=3743; i=broonie@kernel.org; h=from:subject:message-id; bh=7/H/C/HH1SlOixEC1xQKfbpAfSVTyHxGoHTFJYjOHFU=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZCsvJt0x+3cTE17o3ZOr/CaDbwL0GxZ4nc4wF4 F1WgVKaJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGQgAKCRAk1otyXVSH0MmPB/ 9pOJ7W5wXQka5mnlJRk8I91FA/LeHqxR9tWkzcLvTX2d3Z37Au0pKUWIaf/aHjVvyN+fXGicCrHpAb qWEsBX+bM6H2RayqPuqiRrOxaXDUlGxDmQlHiG6ugFtO4SIXFuytrVCQWEyGuGBwqwzQ7LPl98LuVW aE9Ft8+b2I58uyaaLMIxS4AM9fsvVHvlo3crZ+TN2AqXVaDBS2wYQcwgvNQB+YNol0ESRwgQ3rIW8i tDXf5NrquJt7ABjiKjqoF/FpswfC8W9kZiytpx9DwzaDnBudCFRbSyeZPjIMDwG2dnBD+5W7ougb+A QxyYBTUfaLt70IsNjQvdkwNDPuVJ1f X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB In order to make it easier to add more configuration for the tests and more support for runtime detection of when tests can be run pass the structure describing the tests into test_clone3() rather than picking the arguments out of it and have that function do all the per-test work. No functional change. Signed-off-by: Mark Brown --- tools/testing/selftests/clone3/clone3.c | 77 ++++++++++++++++----------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c index e61f07973ce5..e066b201fa64 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -30,6 +30,19 @@ enum test_mode { CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG, }; +typedef bool (*filter_function)(void); +typedef size_t (*size_function)(void); + +struct test { + const char *name; + uint64_t flags; + size_t size; + size_function size_function; + int expected; + enum test_mode test_mode; + filter_function filter; +}; + static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) { struct __clone_args args = { @@ -109,30 +122,40 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) return 0; } -static bool test_clone3(uint64_t flags, size_t size, int expected, - enum test_mode test_mode) +static void test_clone3(const struct test *test) { + size_t size; int ret; + if (test->filter && test->filter()) { + ksft_test_result_skip("%s\n", test->name); + return; + } + + if (test->size_function) + size = test->size_function(); + else + size = test->size; + + ksft_print_msg("Running test '%s'\n", test->name); + ksft_print_msg( "[%d] Trying clone3() with flags %#" PRIx64 " (size %zu)\n", - getpid(), flags, size); - ret = call_clone3(flags, size, test_mode); + getpid(), test->flags, size); + ret = call_clone3(test->flags, size, test->test_mode); ksft_print_msg("[%d] clone3() with flags says: %d expected %d\n", - getpid(), ret, expected); - if (ret != expected) { + getpid(), ret, test->expected); + if (ret != test->expected) { ksft_print_msg( "[%d] Result (%d) is different than expected (%d)\n", - getpid(), ret, expected); - return false; + getpid(), ret, test->expected); + ksft_test_result_fail("%s\n", test->name); + return; } - return true; + ksft_test_result_pass("%s\n", test->name); } -typedef bool (*filter_function)(void); -typedef size_t (*size_function)(void); - static bool not_root(void) { if (getuid() != 0) { @@ -160,16 +183,6 @@ static size_t page_size_plus_8(void) return getpagesize() + 8; } -struct test { - const char *name; - uint64_t flags; - size_t size; - size_function size_function; - int expected; - enum test_mode test_mode; - filter_function filter; -}; - static const struct test tests[] = { { .name = "simple clone3()", @@ -319,24 +332,8 @@ int main(int argc, char *argv[]) ksft_set_plan(ARRAY_SIZE(tests)); test_clone3_supported(); - for (i = 0; i < ARRAY_SIZE(tests); i++) { - if (tests[i].filter && tests[i].filter()) { - ksft_test_result_skip("%s\n", tests[i].name); - continue; - } - - if (tests[i].size_function) - size = tests[i].size_function(); - else - size = tests[i].size; - - ksft_print_msg("Running test '%s'\n", tests[i].name); - - ksft_test_result(test_clone3(tests[i].flags, size, - tests[i].expected, - tests[i].test_mode), - "%s\n", tests[i].name); - } + for (i = 0; i < ARRAY_SIZE(tests); i++) + test_clone3(&tests[i]); ksft_finished(); } From patchwork Sun Jun 23 11:23:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708576 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 BBC2212FB16; Sun, 23 Jun 2024 11:26:45 +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=1719142005; cv=none; b=O3cB8u7/DeJ6+FSuWX/gWwuSVQGEg/IJsP7YsMTu6rBQi0WWMS7v/PcN/ipoEAn+tS/+yrg182BtcIiynGH/+WI+8Mj4gmnPnkaBaCXAoBhZo9m3qjMAHTZJb+/5pf+VDd9wZ3jRlyX3yT5Z1nUGvwgNMe6tsmHXFKwN8ezALeY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719142005; c=relaxed/simple; bh=Ns+1fxdSm08kdtmE5k60TaoPkn5o0cedh5wov4OMD2s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZpfHfySnybt8lK3t7JuGe8t4eWz1YG3nl0zx3NjfA8Q0bmmbPRtrABawB7c5/tzDeCo/HMaYFkO9dUTYOLa2XFMbQ6wscZ5Uoh9YMusTkf1A2XoIj+hSMzVQKEeW7/9Kekutwd60h0cmo6nXjqzKICSFeAmyN/AD4I4mxlbtSqU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IFLZPbce; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IFLZPbce" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D18E5C4AF07; Sun, 23 Jun 2024 11:26:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719142005; bh=Ns+1fxdSm08kdtmE5k60TaoPkn5o0cedh5wov4OMD2s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=IFLZPbcetrCj5BKukxAaS+ERdRqTx9aaoOECDGIuHu1wh6+4VNQ/12T1gBSZSQiq/ NnZZHjNHZk32/n2TMMuonqxRQLiIKOlJF9C1LxTq3jBcKbUG5FgiFxNwfFzTmnOwDM vYgpxyGEx8H2cpEl+SNelgzPz3vxpSrygcnt3DOrYvGnjqbMaaQNgmaaI7kBOmBcwd 0qdOHw9lG/7fOzuqP0Dx/MdURLbX3695SVilwjOMxZpsr+nKSCwHMdu/dCWDPVNCIN R9+BrGdoFHFsnpGdYD+2vGVBpfDuITh04q0d7be2sL5PDq0QTAqe2wm6Mgd7xbvg5F 10n/GfZciezZg== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:49 +0100 Subject: [PATCH RFT v6 7/9] selftests/clone3: Explicitly handle child exits due to signals Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-7-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=1097; i=broonie@kernel.org; h=from:subject:message-id; bh=Ns+1fxdSm08kdtmE5k60TaoPkn5o0cedh5wov4OMD2s=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZDuosQZSpfuY3XJTQ1dqm+pascfylx6In79ck1 oArKUXGJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGQwAKCRAk1otyXVSH0K8zB/ 9L6I/i+8gYUI6kQtVp7l7ltMHJLuzpPbpQXr/49cOdLz3OIHrt4ya0tG/QYpqcTb62W2Nw3cdTs2ku K4SjKs6FTNzvF6CYCJR5OX0+YV4cZ5But9VUCNEY/ABMcDgGYNqoVHE9T6qS60opli5VQ3XW5+RYon NVlS0547Frnp0g/FtW8+qk8DF0eoWrudqtmWIQZ6jT4UIJYEC+iuEv9GI35ZJo79rfJOgBc02LTFm2 XRzNoNQNMbpwWtvPZkY0pIR2EtW3pbCF1dCOOd3zAUTuYv1S5YZEy56gmJ1G3RcFr56I5ykv5jysrM BkpMZs71zcY9q13gbuH+063NebCnHA X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB In order to improve diagnostics and allow tests to explicitly look for signals check to see if the child exited due to a signal and if it did print the code and return it as a positive value, distinct from the negative errnos currently returned. Signed-off-by: Mark Brown --- tools/testing/selftests/clone3/clone3.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c index e066b201fa64..3b3a08e6a34d 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -111,6 +111,13 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) ksft_print_msg("waitpid() returned %s\n", strerror(errno)); return -errno; } + + if (WIFSIGNALED(status)) { + ksft_print_msg("Child exited with signal %d\n", + WTERMSIG(status)); + return WTERMSIG(status); + } + if (!WIFEXITED(status)) { ksft_print_msg("Child did not exit normally, status 0x%x\n", status); From patchwork Sun Jun 23 11:23:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708577 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 ADDFE13775B; Sun, 23 Jun 2024 11:26:51 +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=1719142011; cv=none; b=bHDqsYGx2HQs6Beamv7XakFZqHGgH5gAwNOLAwr7/SZUxhI5eYXTvNnDa7BWVQ1LFzv4wE1kRUJOLrzszndlOlqokrTQTBSn1lzH2HKvU1YPb7Vnx80+tGqOfAV9S+47DqJGiSB4WYPMLyomVaQARmnzpD/IQQDkHJ/WZIT6O0A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719142011; c=relaxed/simple; bh=OrLlJZLIdpu8469ekNLVgxT7+eFxGI9yqTN5LZeTdZg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YpueI2jehFqWQoTjmt7S9kljWFHkcP/wb8c4TmIqThb9OdRvC7zW0L8z4LAaQZMRlNjU+BL2a6gO5NqJppP9OEvntznbfTqIxSjXPRxuEDkRjsMuS4GQmB5A4GZ7os6Kgut3yrYCxxImB+ZpIXD7UMPM0Y8R1pUdxUpA3eaI7z8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fUuIeJrr; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="fUuIeJrr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C0A83C32782; Sun, 23 Jun 2024 11:26:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719142011; bh=OrLlJZLIdpu8469ekNLVgxT7+eFxGI9yqTN5LZeTdZg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fUuIeJrreq3hb97SXBQCpnlHZpUeS0dkR+e53R3tVQbKmx1RyfgraVPl0khleh5SH Zsi7jP94n+It2a1gCbSZPlaADPE3R6/D2X10ha3hfVVfKOXkOurCQXo18xSVhucyPh DD+6TXOlu3MnIY4+R7akZaU3KCLCRRZghe1NMt0A4K5gN02l/HjCiSCMKmuTcFcEKN k8Z7LSNdtWMP1AomIrysiuOa38rSbIaRtJvBY4uw4TfWK6qRLy5smptuKxLZoWnkT8 huSUdI46HuBqzdHoEPq6n/e+CMmoIjFffNIe9TO+Ll/1i43adtQQhB3rbfmRHZgRNG 129rdPTAmP8mg== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:50 +0100 Subject: [PATCH RFT v6 8/9] selftests/clone3: Allow tests to flag if -E2BIG is a valid error code Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-8-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=1887; i=broonie@kernel.org; h=from:subject:message-id; bh=OrLlJZLIdpu8469ekNLVgxT7+eFxGI9yqTN5LZeTdZg=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZEOoxjXEAkG0hIViajWG+I9U+cB9UUff/zNYM0 /8m4BrCJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGRAAKCRAk1otyXVSH0HqlB/ 4hycTEhYrVKpxMlmbk9vT8IxxIZbTM+SmMjs9ow79mXaEA57UDoozZAcUqd0T1uK/l6dbb13GirVYX PfECPlgiQZQx0JW+e7Ee0/XDu7UUWMDlwCwoZWgGm6GwVNgQOLMvFo3m43lJKiGJ1PCAogLS6JgYsy DdiJkEnftzslMlEVJKGEGywBPOCrPWkMUzAJhJ5jXjw4dbL6iq+qUFqi0aTMAJAsfZnRjjxVdfo/8e FRGkAbfdpoSyt05NhLV2hOftf63YcrbPrzmY44dqGUDaJ0TTXcp/kDXScVlTjx7HqbcwLczDzT68e2 TkhNshXpAz33zp2gHyHNU0MYKJ6HSU X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB The clone_args structure is extensible, with the syscall passing in the length of the structure. Inside the kernel we use copy_struct_from_user() to read the struct but this has the unfortunate side effect of silently accepting some overrun in the structure size providing the extra data is all zeros. This means that we can't discover the clone3() features that the running kernel supports by simply probing with various struct sizes. We need to check this for the benefit of test systems which run newer kselftests on old kernels. Add a flag which can be set on a test to indicate that clone3() may return -E2BIG due to the use of newer struct versions. Currently no tests need this but it will become an issue for testing clone3() support for shadow stacks, the support for shadow stacks is already present on x86. Signed-off-by: Mark Brown --- tools/testing/selftests/clone3/clone3.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c index 3b3a08e6a34d..26221661e9ae 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -39,6 +39,7 @@ struct test { size_t size; size_function size_function; int expected; + bool e2big_valid; enum test_mode test_mode; filter_function filter; }; @@ -153,6 +154,11 @@ static void test_clone3(const struct test *test) ksft_print_msg("[%d] clone3() with flags says: %d expected %d\n", getpid(), ret, test->expected); if (ret != test->expected) { + if (test->e2big_valid && ret == -E2BIG) { + ksft_print_msg("Test reported -E2BIG\n"); + ksft_test_result_skip("%s\n", test->name); + return; + } ksft_print_msg( "[%d] Result (%d) is different than expected (%d)\n", getpid(), ret, test->expected); From patchwork Sun Jun 23 11:23:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13708578 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 99FDA13775B; Sun, 23 Jun 2024 11:26:57 +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=1719142017; cv=none; b=u9uht+mpb4e0OZbrhAjh3Tm0xSNquxeaUcmhow19NyB8UESJuF8F1oHiDSAnjo74509sX5X4jTrVcXjRNAlhY0lWJIs6QxcrYAcuHXL3mF3rJ+ZZFne5T4NI9qcomAw6uJvH9j2jtTLC+rgwOKplAygf4c7Rw/ub2+l5m0b7PjA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719142017; c=relaxed/simple; bh=HJyHebPulu/V3TNgcFXSyNdIb6oXCZUmN5TtiBmzewk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=A0go6WqCN88GeyELp1PNm485zi2Hli2ZUqccBHAPdUF6ueeL7jXsIOM85DlOm0B2Wkfue8lnNaQARdfXtB5aKmwnmfo4IbxMdvRdh1E2bOnihnBh6Evb//hY/g55TFch1XX3mX/UDG6tPm9ytriTlSAbf7/9CKM5fW6MAzmDOzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kudHEoaT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kudHEoaT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B0A5AC2BD10; Sun, 23 Jun 2024 11:26:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719142017; bh=HJyHebPulu/V3TNgcFXSyNdIb6oXCZUmN5TtiBmzewk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kudHEoaTui41qM0o382XZN75YcysYjQ9ZmqT1fFzWGrqBsRJ1ykHt6J7JDHtlWUoO e5VrZ3x9TyGw8LKaZqD7FoW+10DfdJc4Z+WxeyEIbR4UTQ9S0m3FcfShjY+/4DO7RS mMDl/ikC3ts0dF/8C233Gh2R8BdwCOCOAh82HXxqCGl4LL5RBIuaiA2nCY3WPx2sw7 +xpsECh6kB/EMSUq8OWyIgKs6hvnsECJ3o/89/77RMtzByMaV8kEIZTDSUbpOkJPWv Ct+oINMYTJ9SANNEIWyURUkYUVTTdHuFyLZJlawSjwV1y40k3UAVHXsU3Wh7yNbuxd OLqbOP8ZXLo2w== From: Mark Brown Date: Sun, 23 Jun 2024 12:23:51 +0100 Subject: [PATCH RFT v6 9/9] selftests/clone3: Test shadow stack support Precedence: bulk X-Mailing-List: linux-kselftest@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240623-clone3-shadow-stack-v6-9-9ee7783b1fb9@kernel.org> References: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> In-Reply-To: <20240623-clone3-shadow-stack-v6-0-9ee7783b1fb9@kernel.org> To: "Rick P. Edgecombe" , Deepak Gupta , Szabolcs Nagy , "H.J. Lu" , Florian Weimer , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Valentin Schneider , Christian Brauner , Shuah Khan Cc: linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , jannh@google.com, bsegall@google.com, linux-kselftest@vger.kernel.org, linux-api@vger.kernel.org, Mark Brown , Kees Cook X-Mailer: b4 0.14-dev-d4707 X-Developer-Signature: v=1; a=openpgp-sha256; l=9308; i=broonie@kernel.org; h=from:subject:message-id; bh=HJyHebPulu/V3TNgcFXSyNdIb6oXCZUmN5TtiBmzewk=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBmeAZEeAvKTbdDrDWoRUR7tJAhUG/UTAqRo8YCApbD 2ftNR1iJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZngGRAAKCRAk1otyXVSH0Gz7B/ 9MFFHaKRFSiqwqrZQ24MzWgP13MH5OX9xBMkZsWVsdLejdUBDtbbDM0HXtbkGcEGcxELbO4G8WTP+b Xb6uYp7q7TXNlb2JAACDKlCx6f1EVZ+w1AcD+rNDw9ZSxKq1iptmywBLMcG4/uZZkGQQFMjiBb2lUv MPfLQq/KcDB6KGkzXeJrrucKFzOqyS2of4UEFDdowS/1mY1MkHDQlFLPwPxLTKHCPe3zTvik3TJdA5 gH68vhzs0rduRiGDxW5RhI/llbMzsHhcHtlnSZSxzHo4+GDJ0Q4x9r3gatGk3UobWyrTM/j0tkKyiR m+gLQbYMaFLeAs4rxSxNm1GHSCdstY X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB Add basic test coverage for specifying the shadow stack for a newly created thread via clone3(), including coverage of the newly extended argument structure. We check that a user specified shadow stack can be provided, and that invalid combinations of parameters are rejected. In order to facilitate testing on systems without userspace shadow stack support we manually enable shadow stacks on startup, this is architecture specific due to the use of an arch_prctl() on x86. Due to interactions with potential userspace locking of features we actually detect support for shadow stacks on the running system by attempting to allocate a shadow stack page during initialisation using map_shadow_stack(), warning if this succeeds when the enable failed. In order to allow testing of user configured shadow stacks on architectures with that feature we need to ensure that we do not return from the function where the clone3() syscall is called in the child process, doing so would trigger a shadow stack underflow. To do this we use inline assembly rather than the standard syscall wrapper to call clone3(). In order to avoid surprises we also use a syscall rather than the libc exit() function., this should be overly cautious. Signed-off-by: Mark Brown --- tools/testing/selftests/clone3/clone3.c | 135 +++++++++++++++++++++- tools/testing/selftests/clone3/clone3_selftests.h | 38 ++++++ 2 files changed, 172 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c index 26221661e9ae..696fbb6f9496 100644 --- a/tools/testing/selftests/clone3/clone3.c +++ b/tools/testing/selftests/clone3/clone3.c @@ -3,6 +3,7 @@ /* Based on Christian Brauner's clone3() example */ #define _GNU_SOURCE +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,8 +21,12 @@ #include #include "../kselftest.h" +#include "../ksft_shstk.h" #include "clone3_selftests.h" +static bool shadow_stack_supported; +static size_t max_supported_args_size; + enum test_mode { CLONE3_ARGS_NO_TEST, CLONE3_ARGS_ALL_0, @@ -28,6 +34,10 @@ enum test_mode { CLONE3_ARGS_INVAL_EXIT_SIGNAL_NEG, CLONE3_ARGS_INVAL_EXIT_SIGNAL_CSIG, CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG, + CLONE3_ARGS_SHADOW_STACK, + CLONE3_ARGS_SHADOW_STACK_NO_SIZE, + CLONE3_ARGS_SHADOW_STACK_NO_POINTER, + CLONE3_ARGS_SHADOW_STACK_NO_TOKEN, }; typedef bool (*filter_function)(void); @@ -44,6 +54,44 @@ struct test { filter_function filter; }; + +/* + * We check for shadow stack support by attempting to use + * map_shadow_stack() since features may have been locked by the + * dynamic linker resulting in spurious errors when we attempt to + * enable on startup. We warn if the enable failed. + */ +static void test_shadow_stack_supported(void) +{ + long ret; + + ret = syscall(__NR_map_shadow_stack, 0, getpagesize(), 0); + if (ret == -1) { + ksft_print_msg("map_shadow_stack() not supported\n"); + } else if ((void *)ret == MAP_FAILED) { + ksft_print_msg("Failed to map shadow stack\n"); + } else { + ksft_print_msg("Shadow stack supportd\n"); + shadow_stack_supported = true; + + if (!shadow_stack_enabled) + ksft_print_msg("Mapped but did not enable shadow stack\n"); + } +} + +static unsigned long long get_shadow_stack_page(unsigned long flags) +{ + unsigned long long page; + + page = syscall(__NR_map_shadow_stack, 0, getpagesize(), flags); + if ((void *)page == MAP_FAILED) { + ksft_print_msg("map_shadow_stack() failed: %d\n", errno); + return 0; + } + + return page; +} + static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) { struct __clone_args args = { @@ -89,6 +137,21 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) case CLONE3_ARGS_INVAL_EXIT_SIGNAL_NSIG: args.exit_signal = 0x00000000000000f0ULL; break; + case CLONE3_ARGS_SHADOW_STACK: + /* We need to specify a normal stack too to avoid corruption */ + args.shadow_stack = get_shadow_stack_page(SHADOW_STACK_SET_TOKEN); + args.shadow_stack_size = getpagesize(); + break; + case CLONE3_ARGS_SHADOW_STACK_NO_POINTER: + args.shadow_stack_size = getpagesize(); + break; + case CLONE3_ARGS_SHADOW_STACK_NO_SIZE: + args.shadow_stack = get_shadow_stack_page(SHADOW_STACK_SET_TOKEN); + break; + case CLONE3_ARGS_SHADOW_STACK_NO_TOKEN: + args.shadow_stack = get_shadow_stack_page(0); + args.shadow_stack_size = getpagesize(); + break; } memcpy(&args_ext.args, &args, sizeof(struct __clone_args)); @@ -102,7 +165,12 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) if (pid == 0) { ksft_print_msg("I am the child, my PID is %d\n", getpid()); - _exit(EXIT_SUCCESS); + /* + * Use a raw syscall to ensure we don't get issues + * with manually specified shadow stack and exit handlers. + */ + syscall(__NR_exit, EXIT_SUCCESS); + ksft_print_msg("CHILD FAILED TO EXIT PID is %d\n", getpid()); } ksft_print_msg("I am the parent (%d). My child's pid is %d\n", @@ -112,6 +180,7 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) ksft_print_msg("waitpid() returned %s\n", strerror(errno)); return -errno; } + ksft_print_msg("WAITED\n"); if (WIFSIGNALED(status)) { ksft_print_msg("Child exited with signal %d\n", @@ -191,6 +260,26 @@ static bool no_timenamespace(void) return true; } +static bool have_shadow_stack(void) +{ + if (shadow_stack_supported) { + ksft_print_msg("Shadow stack supported\n"); + return true; + } + + return false; +} + +static bool no_shadow_stack(void) +{ + if (!shadow_stack_supported) { + ksft_print_msg("Shadow stack not supported\n"); + return true; + } + + return false; +} + static size_t page_size_plus_8(void) { return getpagesize() + 8; @@ -334,6 +423,47 @@ static const struct test tests[] = { .expected = -EINVAL, .test_mode = CLONE3_ARGS_NO_TEST, }, + { + .name = "Shadow stack on system with shadow stack", + .size = 0, + .expected = 0, + .e2big_valid = true, + .test_mode = CLONE3_ARGS_SHADOW_STACK, + .filter = no_shadow_stack, + }, + { + .name = "Shadow stack with no pointer", + .size = 0, + .expected = -EINVAL, + .e2big_valid = true, + .test_mode = CLONE3_ARGS_SHADOW_STACK_NO_POINTER, + }, + { + .name = "Shadow stack with no size", + .size = 0, + .expected = -EINVAL, + .e2big_valid = true, + .test_mode = CLONE3_ARGS_SHADOW_STACK_NO_SIZE, + .filter = no_shadow_stack, + }, + { + .name = "Shadow stack with no token", + .flags = CLONE_VM, + .size = 0, + .expected = SIGSEGV, + .e2big_valid = true, + .test_mode = CLONE3_ARGS_SHADOW_STACK_NO_TOKEN, + .filter = no_shadow_stack, + }, + { + .name = "Shadow stack on system without shadow stack", + .flags = CLONE_VM, + .size = 0, + .expected = -EINVAL, + .e2big_valid = true, + .test_mode = CLONE3_ARGS_SHADOW_STACK, + .filter = have_shadow_stack, + }, }; int main(int argc, char *argv[]) @@ -341,9 +471,12 @@ int main(int argc, char *argv[]) size_t size; int i; + enable_shadow_stack(); + ksft_print_header(); ksft_set_plan(ARRAY_SIZE(tests)); test_clone3_supported(); + test_shadow_stack_supported(); for (i = 0; i < ARRAY_SIZE(tests); i++) test_clone3(&tests[i]); diff --git a/tools/testing/selftests/clone3/clone3_selftests.h b/tools/testing/selftests/clone3/clone3_selftests.h index 39b5dcba663c..38d82934668a 100644 --- a/tools/testing/selftests/clone3/clone3_selftests.h +++ b/tools/testing/selftests/clone3/clone3_selftests.h @@ -31,12 +31,50 @@ struct __clone_args { __aligned_u64 set_tid; __aligned_u64 set_tid_size; __aligned_u64 cgroup; +#ifndef CLONE_ARGS_SIZE_VER2 +#define CLONE_ARGS_SIZE_VER2 88 /* sizeof third published struct */ +#endif + __aligned_u64 shadow_stack; + __aligned_u64 shadow_stack_size; +#ifndef CLONE_ARGS_SIZE_VER3 +#define CLONE_ARGS_SIZE_VER3 104 /* sizeof fourth published struct */ +#endif }; +/* + * For architectures with shadow stack support we need to be + * absolutely sure that the clone3() syscall will be inline and not a + * function call so we open code. + */ +#ifdef __x86_64__ +static pid_t __always_inline sys_clone3(struct __clone_args *args, size_t size) +{ + long ret; + register long _num __asm__ ("rax") = __NR_clone3; + register long _args __asm__ ("rdi") = (long)(args); + register long _size __asm__ ("rsi") = (long)(size); + + __asm__ volatile ( + "syscall\n" + : "=a"(ret) + : "r"(_args), "r"(_size), + "0"(_num) + : "rcx", "r11", "memory", "cc" + ); + + if (ret < 0) { + errno = -ret; + return -1; + } + + return ret; +} +#else static pid_t sys_clone3(struct __clone_args *args, size_t size) { return syscall(__NR_clone3, args, size); } +#endif static inline void test_clone3_supported(void) {