From patchwork Wed Nov 8 18:11:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: tip-bot2 for Thomas Gleixner X-Patchwork-Id: 163127 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:aa0b:0:b0:403:3b70:6f57 with SMTP id k11csp1096446vqo; Wed, 8 Nov 2023 10:12:18 -0800 (PST) X-Google-Smtp-Source: AGHT+IEPnBBjVjlu236hVh48lcw5jRMFjE15JWqZxkm+DBdA0ok+jb+ItJZBEDEb34GM1tUemp7k X-Received: by 2002:a05:6a00:2e9b:b0:68a:45a1:c0ee with SMTP id fd27-20020a056a002e9b00b0068a45a1c0eemr2998111pfb.15.1699467138422; Wed, 08 Nov 2023 10:12:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699467138; cv=none; d=google.com; s=arc-20160816; b=K7rk1XRg0kHlXu/3teYF0l6kECVIE38RKMCePPktfCDwO/Qrlj4oBThGz9XbLj8Cup xaBNP9OZMOq23hbHzT9REOTXJjGmFWGe0Wmm6j9yHxkp6KHYKYt6UiG7jU94VTMyrVnK lZinPxBm0kVf8HH8cMyP6MtkGKwupCjcz0fH0HzMaDxhHerHPrDhCBPMsF4Z0pXEJWtW YgLQ87B65TZRiqxl3Qzf0nua4ioV57KBEJvPX4bSOtet4lEnwUufV00ImlEK3OWwCzsX jQLLncDjqGhfH+KfiyQHco4vH6fXN6qtnEW6tG/tRdhgK62IN2qSuFHj2JhIPdIyeBl5 rDzA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:cc:subject:to:reply-to:sender:from :dkim-signature:dkim-signature:date; bh=qTZCwBL3ePgB/9fon2+LOAb4X4uCob5TehfJ6KGUEaw=; fh=ihXV2nD3c44uXP9YF549iIppsBJ6cX5dpP/W79mbziw=; b=RNnGS09swMhGaLztDrYn2AH6xLIfmQ0oKOtQV2AwCPyh9v2579cwArs1iwuxHeS7yA 7XGIM7VCqB6G7mMkMqkcn9ZpcVPY4iOLu6DJ9UCUY611qY2fvKDDZQsyCMhbb1KiaT/l 1I975IdwABUchc9Dv0LsMw3F9XSrZjDtGoEBl6Ta/dg+ft9Xgox81jaibWxdhaQohwHI zXvIz5Ro1Y6g49tQBRwFDXjVhXrM++tO/7mFfxviC9hukHoe9bhDbsHnuvwZ34wiAuDY 7gvLp6dyzItcLFmT1WlLIr/8nszQhKdiVBCteLP0IYrTjzXNLubwvPfb4ijar4/9QjNv UsYg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=flO7Gdrk; dkim=neutral (no key) header.i=@linutronix.de header.b=EnmaNQwf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from lipwig.vger.email (lipwig.vger.email. [2620:137:e000::3:3]) by mx.google.com with ESMTPS id x25-20020aa784d9000000b006c2d5caf9b2si12732944pfn.282.2023.11.08.10.12.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Nov 2023 10:12:18 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) client-ip=2620:137:e000::3:3; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=flO7Gdrk; dkim=neutral (no key) header.i=@linutronix.de header.b=EnmaNQwf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id CE34081489D7; Wed, 8 Nov 2023 10:12:15 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231935AbjKHSLt (ORCPT + 32 others); Wed, 8 Nov 2023 13:11:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229460AbjKHSLr (ORCPT ); Wed, 8 Nov 2023 13:11:47 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2A9B4171B; Wed, 8 Nov 2023 10:11:45 -0800 (PST) Date: Wed, 08 Nov 2023 18:11:41 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1699467102; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qTZCwBL3ePgB/9fon2+LOAb4X4uCob5TehfJ6KGUEaw=; b=flO7GdrkVu7ni32ohs7YdWtZfoYXzx6BtOwtiHLxIQDgDrQKijvUg6jboC6F2zAd1Itwgl s5u6alisiibmdb+MHBlp5bSSYDglZnjFc+GYVFGkW+7318SdkV2X4WbTi4ttS4sLbCH772 vUzCc08rIpsjKqkuWY7flvE7zkjUjhrQjsz4V2k5TbDm/cQzjXeLW/0By6Jru9rPed5hYu Cm0z1q5qJwopB2CNxIOfP7qNmbAvmp5vSMPgVMa3Op5s2TKFWkJGx5GSZAYGHrAqsbMNuo YLiejfPrSsOY3VtSC5RmvoaQJdKwuKFn+srcqzAuBSAhQWEkvfWWL4T/6Zgecw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1699467102; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qTZCwBL3ePgB/9fon2+LOAb4X4uCob5TehfJ6KGUEaw=; b=EnmaNQwfQKp7CIYAMpq2JPbYtsAz5r9RrQ3QnZuyKNxCD5GkDzYy402K9RwBpnR2q23Dgp IxSenka/aPkap2BA== From: "tip-bot2 for Rick Edgecombe" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/urgent] x86/shstk: Delay signal entry SSP write until after user accesses Cc: Pengfei Xu , Rick Edgecombe , Dave Hansen , stable@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <169946710196.3135.13826556225049872785.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Wed, 08 Nov 2023 10:12:15 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782020454009855043 X-GMAIL-MSGID: 1782020454009855043 The following commit has been merged into the x86/urgent branch of tip: Commit-ID: 31255e072b2e91f97645d792d25b2db744186dd1 Gitweb: https://git.kernel.org/tip/31255e072b2e91f97645d792d25b2db744186dd1 Author: Rick Edgecombe AuthorDate: Tue, 07 Nov 2023 10:22:51 -08:00 Committer: Dave Hansen CommitterDate: Wed, 08 Nov 2023 08:55:37 -08:00 x86/shstk: Delay signal entry SSP write until after user accesses When a signal is being delivered, the kernel needs to make accesses to userspace. These accesses could encounter an access error, in which case the signal delivery itself will trigger a segfault. Usually this would result in the kernel killing the process. But in the case of a SEGV signal handler being configured, the failure of the first signal delivery will result in *another* signal getting delivered. The second signal may succeed if another thread has resolved the issue that triggered the segfault (i.e. a well timed mprotect()/mmap()), or the second signal is being delivered to another stack (i.e. an alt stack). On x86, in the non-shadow stack case, all the accesses to userspace are done before changes to the registers (in pt_regs). The operation is aborted when an access error occurs, so although there may be writes done for the first signal, control flow changes for the signal (regs->ip, regs->sp, etc) are not committed until all the accesses have already completed successfully. This means that the second signal will be delivered as if it happened at the time of the first signal. It will effectively replace the first aborted signal, overwriting the half-written frame of the aborted signal. So on sigreturn from the second signal, control flow will resume happily from the point of control flow where the original signal was delivered. The problem is, when shadow stack is active, the shadow stack SSP register/MSR is updated *before* some of the userspace accesses. This means if the earlier accesses succeed and the later ones fail, the second signal will not be delivered at the same spot on the shadow stack as the first one. So on sigreturn from the second signal, the SSP will be pointing to the wrong location on the shadow stack (off by a frame). Pengfei privately reported that while using a shadow stack enabled glibc, the “signal06” test in the LTP test-suite hung. It turns out it is testing the above described double signal scenario. When this test was compiled with shadow stack, the first signal pushed a shadow stack sigframe, then the second pushed another. When the second signal was handled, the SSP was at the first shadow stack signal frame instead of the original location. The test then got stuck as the #CP from the twice incremented SSP was incorrect and generated segfaults in a loop. Fix this by adjusting the SSP register only after any userspace accesses, such that there can be no failures after the SSP is adjusted. Do this by moving the shadow stack sigframe push logic to happen after all other userspace accesses. Note, sigreturn (as opposed to the signal delivery dealt with in this patch) has ordering behavior that could lead to similar failures. The ordering issues there extend beyond shadow stack to include the alt stack restoration. Fixing that would require cross-arch changes, and the ordering today does not cause any known test or apps breakages. So leave it as is, for now. [ dhansen: minor changelog/subject tweak ] Fixes: 05e36022c054 ("x86/shstk: Handle signals for shadow stack") Reported-by: Pengfei Xu Signed-off-by: Rick Edgecombe Signed-off-by: Dave Hansen Tested-by: Pengfei Xu Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20231107182251.91276-1-rick.p.edgecombe%40intel.com Link: https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/syscalls/signal/signal06.c --- arch/x86/kernel/signal_64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index cacf2ed..23d8aaf 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c @@ -175,9 +175,6 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp); uc_flags = frame_uc_flags(regs); - if (setup_signal_shadow_stack(ksig)) - return -EFAULT; - if (!user_access_begin(frame, sizeof(*frame))) return -EFAULT; @@ -198,6 +195,9 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) return -EFAULT; } + if (setup_signal_shadow_stack(ksig)) + return -EFAULT; + /* Set up registers for signal handler */ regs->di = ksig->sig; /* In case the signal handler was declared without prototypes */