Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp790411ybe; Fri, 13 Sep 2019 06:26:23 -0700 (PDT) X-Google-Smtp-Source: APXvYqxMKf938g3Fe6FVoeXTtHEr/KFRJ0K7OTrbGjR6It8IIP2zRJ/SyecW8DkHYd3BXFFKf1QN X-Received: by 2002:a17:906:43cf:: with SMTP id j15mr40067294ejn.7.1568381183095; Fri, 13 Sep 2019 06:26:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568381183; cv=none; d=google.com; s=arc-20160816; b=DuudiaX3nwG9ixtxL13+geUaFt2+sqr98j58thLaZKcknS/jpp9mRKWN1R07gCEcYZ gQalhWSe8NwAz5QMb8kQg2nNA/55742JBx+e4DW+cXRAzavRcqkUQc6/6w3XaPRknjNb tsIZIhjvJzWhvuDHzS1kL4dDCQXrjeacBT7n9KzcxwvV0nLZNdZ/bCZSVruEKMrbz1o2 vGWkzQpSdW2Py+Jn8MyplPkVQYRiRbVYZ1b/cbofX2l8XWEdhL6eiPxbglHXIMkf49BZ +a/OU8KeQLic5K+FS9ADfZY6us4ZnlidDCiNp79QaDaQ8h4m8rgItUZZwnNSevpZpodE 5B5g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=porPm53thT3oPpbn08YtE7sFK9Ft+0mvdDYN7X6+9R4=; b=QeO9GulQFtgH8IdhTlzepGytZc0QAOskeQAUy9RGrzMWip/Y4+uRSE/lRoVKv0iCT3 /3MGL1bKwfHZDmdGG+tcPzinKlokn2CKfOASu47IvtPpeafHqLoflSuc9ZGSRwkasSUT fIcB0bx5oP8H4gUEMDU/+neEqTCHJY7fWQL4/EayRa7v3NGpYNZn1zubJ7FkDuPyP6m8 JKXWbUHD1tB3vi60b5sotLRAOAO5SDIom5XeEtSGDDA1/okrN61H8aoLHEAWI6Ut5PBk eiNCD/X0UTjiRR26rQkCeAiDw4lW0JjLW7Byh8Do++DWQFwm5PcgNh5canQs2bSTRiFh HGAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=J0TEHSpt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d21si14459144edx.405.2019.09.13.06.25.58; Fri, 13 Sep 2019 06:26:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=J0TEHSpt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390869AbfIMNVk (ORCPT + 99 others); Fri, 13 Sep 2019 09:21:40 -0400 Received: from mail.kernel.org ([198.145.29.99]:51402 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390847AbfIMNVi (ORCPT ); Fri, 13 Sep 2019 09:21:38 -0400 Received: from localhost (unknown [104.132.45.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 12C44206BB; Fri, 13 Sep 2019 13:21:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568380897; bh=Bm1BnlIDZUnwryajTE320S6bTasMDDIgTNO3VcEA5Og=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J0TEHSpt7IPdnwZzv/kFZz9TlYy6bxsnqdG1hjpMwMca4JxOnQGErBYQCQqfuxXcH CDLCNeIznuq4JS0Rh7D+2ifcFR2m00x07ZCi0wT1ShbFcDuoCd8u38mYq93ieMI9/h z3Glo/jQIkstwvA2OHHjvM6Mf8p72sPYmjPqGVdI= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Gustavo Romero , Michael Neuling , Michael Ellerman Subject: [PATCH 5.2 14/37] powerpc/tm: Fix FP/VMX unavailable exceptions inside a transaction Date: Fri, 13 Sep 2019 14:07:19 +0100 Message-Id: <20190913130516.440597006@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190913130510.727515099@linuxfoundation.org> References: <20190913130510.727515099@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Gustavo Romero commit 8205d5d98ef7f155de211f5e2eb6ca03d95a5a60 upstream. When we take an FP unavailable exception in a transaction we have to account for the hardware FP TM checkpointed registers being incorrect. In this case for this process we know the current and checkpointed FP registers must be the same (since FP wasn't used inside the transaction) hence in the thread_struct we copy the current FP registers to the checkpointed ones. This copy is done in tm_reclaim_thread(). We use thread->ckpt_regs.msr to determine if FP was on when in userspace. thread->ckpt_regs.msr represents the state of the MSR when exiting userspace. This is setup by check_if_tm_restore_required(). Unfortunatley there is an optimisation in giveup_all() which returns early if tsk->thread.regs->msr (via local variable `usermsr`) has FP=VEC=VSX=SPE=0. This optimisation means that check_if_tm_restore_required() is not called and hence thread->ckpt_regs.msr is not updated and will contain an old value. This can happen if due to load_fp=255 we start a userspace process with MSR FP=1 and then we are context switched out. In this case thread->ckpt_regs.msr will contain FP=1. If that same process is then context switched in and load_fp overflows, MSR will have FP=0. If that process now enters a transaction and does an FP instruction, the FP unavailable will not update thread->ckpt_regs.msr (the bug) and MSR FP=1 will be retained in thread->ckpt_regs.msr. tm_reclaim_thread() will then not perform the required memcpy and the checkpointed FP regs in the thread struct will contain the wrong values. The code path for this happening is: Userspace: Kernel Start userspace with MSR FP/VEC/VSX/SPE=0 TM=1 < ----- ... tbegin bne fp instruction FP unavailable ---- > fp_unavailable_tm() tm_reclaim_current() tm_reclaim_thread() giveup_all() return early since FP/VMX/VSX=0 /* ckpt MSR not updated (Incorrect) */ tm_reclaim() /* thread_struct ckpt FP regs contain junk (OK) */ /* Sees ckpt MSR FP=1 (Incorrect) */ no memcpy() performed /* thread_struct ckpt FP regs not fixed (Incorrect) */ tm_recheckpoint() /* Put junk in hardware checkpoint FP regs */ .... < ----- Return to userspace with MSR TM=1 FP=1 with junk in the FP TM checkpoint TM rollback reads FP junk This is a data integrity problem for the current process as the FP registers are corrupted. It's also a security problem as the FP registers from one process may be leaked to another. This patch moves up check_if_tm_restore_required() in giveup_all() to ensure thread->ckpt_regs.msr is updated correctly. A simple testcase to replicate this will be posted to tools/testing/selftests/powerpc/tm/tm-poison.c Similarly for VMX. This fixes CVE-2019-15030. Fixes: f48e91e87e67 ("powerpc/tm: Fix FP and VMX register corruption") Cc: stable@vger.kernel.org # 4.12+ Signed-off-by: Gustavo Romero Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190904045529.23002-1-gromero@linux.vnet.ibm.com Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/process.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -497,13 +497,14 @@ void giveup_all(struct task_struct *tsk) if (!tsk->thread.regs) return; + check_if_tm_restore_required(tsk); + usermsr = tsk->thread.regs->msr; if ((usermsr & msr_all_available) == 0) return; msr_check_and_set(msr_all_available); - check_if_tm_restore_required(tsk); WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC)));