From patchwork Fri Aug 2 06:13:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aruna Ramakrishna X-Patchwork-Id: 13751139 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 595DBC52D71 for ; Fri, 2 Aug 2024 06:13:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id DCDEB6B0085; Fri, 2 Aug 2024 02:13:37 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D7D1E6B0088; Fri, 2 Aug 2024 02:13:37 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C44AA6B0089; Fri, 2 Aug 2024 02:13:37 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id A83406B0085 for ; Fri, 2 Aug 2024 02:13:37 -0400 (EDT) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 402521A0D1F for ; Fri, 2 Aug 2024 06:13:37 +0000 (UTC) X-FDA: 82406288874.08.4878D9A Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by imf29.hostedemail.com (Postfix) with ESMTP id 2C628120005 for ; Fri, 2 Aug 2024 06:13:34 +0000 (UTC) Authentication-Results: imf29.hostedemail.com; dkim=pass header.d=oracle.com header.s=corp-2023-11-20 header.b=AAJaKO0L; spf=pass (imf29.hostedemail.com: domain of aruna.ramakrishna@oracle.com designates 205.220.165.32 as permitted sender) smtp.mailfrom=aruna.ramakrishna@oracle.com; dmarc=pass (policy=reject) header.from=oracle.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722579186; a=rsa-sha256; cv=none; b=aRPBAFESpUhtHb0pnVcDZt/XRzbplAsrfCdtnnVTK3eCaxGdApdnQpraa2dUicDdzplIYs AB1VAHPUHFksz6BCxEVbbUI1ZtjsYEr7N9vT8UQie2qTKBs5LlDVIucLefmjCpPltfSd54 Vxp3XQ1bQABF0zww6zbE09crKQPbuO0= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=pass header.d=oracle.com header.s=corp-2023-11-20 header.b=AAJaKO0L; spf=pass (imf29.hostedemail.com: domain of aruna.ramakrishna@oracle.com designates 205.220.165.32 as permitted sender) smtp.mailfrom=aruna.ramakrishna@oracle.com; dmarc=pass (policy=reject) header.from=oracle.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1722579186; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=MKU+WG2gzC94jUgb0tLE7u9uI0Bei7s8TSL3t2RlLeo=; b=E2m8V4BOhZJKnAZ9itkBwUmOUmFJZsL0AEETZ605mQoziynIuBk3zKBHdExR8jK1XkemJ5 ku4SmH3Wq65BbjaK5zSP1edK/rk61Tw7yEuNJweSD7QYvKctnBpqyT53Ob7fzEVQuDsC/9 m/8Kc7lOah7ZVl3/0K6H9j251jtXUGU= Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4723ft2W022569; Fri, 2 Aug 2024 06:13:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=corp-2023-11-20; bh=M KU+WG2gzC94jUgb0tLE7u9uI0Bei7s8TSL3t2RlLeo=; b=AAJaKO0Lt2E/BfIvZ GBc6utt0Ckp1t98ialbh0Zn8hKiUYaILlBQQ28J2suY6kKTKuws+eJ0u1Vxp2e17 JNEy+fLnJUsIvdhwpRa3DLQzKaYV8Rl57h2jEQwpgTEHrOOR67IF8tyVoqQJJC+1 btBQ5133OROjE2ltYvgl5KBbKRWxS8GvS6tirvO4CzRSuIEX4RbfJGtRtaF+vNTf FOYtCbCZoAGjXJeLN6lFysR7yGLZQKUTJk2dxE07e4+gu3hfwXaeoRHVSAcRtpMM aXWvb/5eeS5rFL/VzqNTsKqm4/3EpMw13iglGqmY8SQ1cnzIB4pguVB986O+IyGH bnAfg== Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.appoci.oracle.com [138.1.37.129]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 40rjg5gfyy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 02 Aug 2024 06:13:27 +0000 (GMT) Received: from pps.filterd (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (8.17.1.19/8.17.1.19) with ESMTP id 4725TVE3035644; Fri, 2 Aug 2024 06:13:26 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 40nvp16eb1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 02 Aug 2024 06:13:26 +0000 Received: from phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 4726BM9a012716; Fri, 2 Aug 2024 06:13:26 GMT Received: from aruramak-dev.osdevelopmeniad.oraclevcn.com (aruramak-dev.allregionaliads.osdevelopmeniad.oraclevcn.com [100.100.253.155]) by phxpaimrmta03.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 40nvp16e89-2; Fri, 02 Aug 2024 06:13:26 +0000 From: Aruna Ramakrishna To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, dave.hansen@linux.intel.com, tglx@linutronix.de, mingo@kernel.org, linux-mm@kvack.org, keith.lucas@oracle.com, jeffxu@chromium.org, rick.p.edgecombe@intel.com, jorgelo@chromium.org, keescook@chromium.org, sroettger@google.com, jannh@google.com, aruna.ramakrishna@oracle.com Subject: [PATCH v8 1/5] x86/pkeys: Add PKRU as a parameter in signal handling functions Date: Fri, 2 Aug 2024 06:13:14 +0000 Message-Id: <20240802061318.2140081-2-aruna.ramakrishna@oracle.com> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240802061318.2140081-1-aruna.ramakrishna@oracle.com> References: <20240802061318.2140081-1-aruna.ramakrishna@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-08-02_03,2024-08-01_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 adultscore=0 mlxlogscore=999 mlxscore=0 suspectscore=0 malwarescore=0 bulkscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2407110000 definitions=main-2408020042 X-Proofpoint-ORIG-GUID: jRagxgvjfVt8Bq3SVJ4BKZjm5pIfO22r X-Proofpoint-GUID: jRagxgvjfVt8Bq3SVJ4BKZjm5pIfO22r X-Stat-Signature: bxsop6b34f1g8efeed6eg66hdkyuhbe3 X-Rspamd-Queue-Id: 2C628120005 X-Rspam-User: X-Rspamd-Server: rspam10 X-HE-Tag: 1722579214-676004 X-HE-Meta: U2FsdGVkX1+tyO3ZmbaR38+2xJXV31IwA7l0s02gzEwCuHMuKFrQySrCTWrCeTMC0QPJLxVyNV0ANmXQ/oeK7IWozdVyN4Xf0akhNLXkjGVTddyh9p3eFj0uYqTB3SBpYRDy4QbEvajqZaS9Pryx+9MCbF9J8xkdxWlq09rvVuBd4+nB3Ay3doMPYue2Gqi3VipvAgPDQursG8u3gX4IyCh5Ra4n5aLAb8ogGmhUlSQuAj636zVorReE0WLIx/lzpeYdsquajD+f+P5bsciiAW0tOiTNqnO0Rq0PQbbhsE4isLA8EZjDj9+0Vw0bMy22uBgrioEOWGXRAy0+zMoIbkkYxZ6XCpKq3HoZhkw65fdPUbeW/Gi3ht2XYPPf6QCHJvlQHjd+tIUjgDqlyjarq0vJyNvqM5XEjyiiY2mzpTbquQ0ob2SnWsNaeoEBs/r7/x/nG1fYs/glluiOrKf7Wb/JXwh3+OtMvkKxzBph0bi/0fKYPAZ4ruKRwcKiwPMAz5aojRox/JZ8D9+Uk/IatDuWqj0Se3li6ENaOyFLoltvbKjjtd78YPaXqudnn9+a08f1Tx1Z0usqGHez5LGLeSrXDJYuEIo3VZKZ/9UbNisvqaqeEWs0IY32MAzl/Od5FfHTA2CvpjcnOrHfc8vYJSw2WdiOuyxEAKePPv12/DCaOMl/6oxIZoR5KirbSCzpGf7DG9K73IgfxH3QUzP0s8NCumX3NFvvGo5ebDrceLU38WH9YCDzXD/sooHZtsBzljS7Ido20e8gXN6QEnablF8kE0jLteakYKenMLvOVXwOjHejR88fdHRiXh+4kL6YsbmMRE9LeQx9/bwcq3Ep3bU5xvNNwSrapzycR27kTfIIh85IyLyUSvk89kCWdz7IORqJkXTzcWIcpxYER1JaD2DyWG3zJbwbN8RuTntibixN1OxSqpIieRShu1AOweYUhPFvUDZYsQWKYPbo2aD 9jx/hVzc 0hqoIJSOE0NE2XhwfpnKv5cFqLDV+gBZVcZ7iVzzc88fdIYIPZGuVyYuXP1TjJiKwBYtP8ZZH4qRNArSPXLBoTMHsXGeeAKl9yS8J8Zd9yt0AH/yz1f+p/cYKbihBNrrDsPB4RLME5gCnsYA8cDt+9QrtM85fEDL/TNc4Re2WD+SFJuT8qtSqlrTzlErYA2JZS8Nt/8VyBPQ2SKrhQiUXln+2Kw== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Problem description: Let's assume there's a multithreaded application that runs untrusted user code. Each thread has its stack/code protected by a non-zero pkey, and the PKRU register is set up such that only that particular non-zero pkey is enabled. Each thread also sets up an alternate signal stack to handle signals, which is protected by pkey zero. The pkeys man page documents that the PKRU will be reset to init_pkru when the signal handler is invoked, which means that pkey zero access will be enabled. But this reset happens after the kernel attempts to push fpu state to the alternate stack, which is not (yet) accessible by the kernel, which leads to a new SIGSEGV being sent to the application, terminating it. Enabling both the non-zero pkey (for the thread) and pkey zero in userspace will not work for this use case. We cannot have the alt stack writeable by all - the rationale here is that the code running in that thread (using a non-zero pkey) is untrusted and should not have access to the alternate signal stack (that uses pkey zero), to prevent the return address of a function from being changed. The expectation is that kernel should be able to set up the alternate signal stack and deliver the signal to the application even if pkey zero is explicitly disabled by the application. The signal handler accessibility should not be dictated by whatever PKRU value the thread sets up. Solution: The PKRU register is managed by XSAVE, which means the sigframe contents must match the register contents - which is not the case here. We want the sigframe to contain the user-defined PKRU value (so that it is restored correctly from sigcontext) but the actual register must be reset to init_pkru so that the alt stack is accessible and the signal can be delivered to the application. It seems that the proper fix here would be to remove PKRU from the XSAVE framework and manage it separately, which is quite complicated. As a workaround, do this: orig_pkru = rdpkru(); wrpkru(orig_pkru & init_pkru_value); xsave_to_user_sigframe(); put_user(pkru_sigframe_addr, orig_pkru) This change is split over multiple patches. In preparation for writing PKRU to sigframe in a later patch, pass in PKRU as an additional parameter down the chain from get_sigframe(): get_sigframe() copy_fpstate_to_sigframe() copy_fpregs_to_sigframe() There are no functional changes in this patch. Signed-off-by: Aruna Ramakrishna --- arch/x86/include/asm/fpu/signal.h | 2 +- arch/x86/kernel/fpu/signal.c | 6 +++--- arch/x86/kernel/signal.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/signal.h index 611fa41711af..eccc75bc9c4f 100644 --- a/arch/x86/include/asm/fpu/signal.h +++ b/arch/x86/include/asm/fpu/signal.h @@ -29,7 +29,7 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame, unsigned long fpu__get_fpstate_size(void); -extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size); +extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size, u32 pkru); extern void fpu__clear_user_states(struct fpu *fpu); extern bool fpu__restore_sig(void __user *buf, int ia32_frame); diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 247f2225aa9f..2b3b9e140dd4 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -156,7 +156,7 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame, return !err; } -static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) +static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf, u32 pkru) { if (use_xsave()) return xsave_to_user_sigframe(buf); @@ -185,7 +185,7 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) * For [f]xsave state, update the SW reserved fields in the [f]xsave frame * indicating the absence/presence of the extended state to the user. */ -bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) +bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size, u32 pkru) { struct task_struct *tsk = current; struct fpstate *fpstate = tsk->thread.fpu.fpstate; @@ -228,7 +228,7 @@ bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) fpregs_restore_userregs(); pagefault_disable(); - ret = copy_fpregs_to_sigframe(buf_fx); + ret = copy_fpregs_to_sigframe(buf_fx, pkru); pagefault_enable(); fpregs_unlock(); diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 31b6f5dddfc2..1f1e8e0ac5a3 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -84,6 +84,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, unsigned long math_size = 0; unsigned long sp = regs->sp; unsigned long buf_fx = 0; + u32 pkru = read_pkru(); /* redzone */ if (!ia32_frame) @@ -139,7 +140,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size, } /* save i387 and extended state */ - if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size)) + if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size, pkru)) return (void __user *)-1L; return (void __user *)sp;