Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp664152ybh; Tue, 10 Mar 2020 06:07:11 -0700 (PDT) X-Google-Smtp-Source: ADFU+vu3n2ztrAApp4fJmO9j56mo9WBZDI/ZuDvpFw2DlwbriJuvfljk8jxvM8UeYl88KQjRth3J X-Received: by 2002:a05:6808:8e5:: with SMTP id d5mr1068836oic.88.1583845631009; Tue, 10 Mar 2020 06:07:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1583845631; cv=none; d=google.com; s=arc-20160816; b=ZXn0PD/wuPeM8kstD2vR74S4+a3H50eSqTHXF2kHLTz4z23r8sHS6thZTggWAwX7VA yCkb+4ScF7XVj6GjjjJLp6yPQ1WCa5rwzUsqsEbq02LAbqiyuUBG2gbG3T9f7yqpDM18 dyM50U0kBcOF5ywe4JfcllpI2lCj3x7L083rstHGnqpAHWIeingnuNTR/QTce31MhsJi gWPkKnvgap0YJ2kH7i3Pmglgn4QNMvncNL8HZLNWW+EuZB7qTieMKqRIfCea3dGvCjuI 6ZmfhiH9YIYSi8uLvZt11mTOfrlMTByS9V43hLvVKe1/mR/50jejIGudD1x/p6SwV67r 4jLg== 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=df3gI47uqpQtjKWEhW7PkCLaLPNH8G7uJiq8ViOY02c=; b=ubeW0LT+pxPoFz6feD47BEUsk3F/EKPKuqBztIbMejkBl9BCCb8yJeNbS4IYZfQY8p PeoyP2+1cSsSI4cgyBqyhf+eaw9vi7IeF1WBaxZN6Tp7/w+VwshHQE4cdMR7YhAoY2hl Tzv5gAgUKdTr/B7r1ApoVZWyJBBg22iZ0PHwB6Ss+j3o4G9q+7Kixxktw6NwsLWg1KO7 Mg9sN8KyAuHPXrDpRAP9/QZc4FMz4H9p4Mh0rIOXftVjwU+HBts7zaYJyx4IqO6UhFvP 3L/DWl3cJQb5ydJArplJMDIVfPeOOYN3Nd2i1vg+7zQaHh8elGYAdWL147x2TIxOjCDG 8+gA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=GsymGbLM; 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 h125si5260283oia.253.2020.03.10.06.06.48; Tue, 10 Mar 2020 06:07:10 -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=GsymGbLM; 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 S1728237AbgCJNEO (ORCPT + 99 others); Tue, 10 Mar 2020 09:04:14 -0400 Received: from mail.kernel.org ([198.145.29.99]:49182 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729456AbgCJNEL (ORCPT ); Tue, 10 Mar 2020 09:04:11 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (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 C9C672468C; Tue, 10 Mar 2020 13:04:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1583845451; bh=khnnaXEotQCDVtCSFvYA545nYovW0yzZNDRL37GEq3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GsymGbLMZrPf3FmTFK8zaM4gjDfghU++dg8zgq6VcjACXHlXDHTmZaMVSzM2VLls6 oobDDX3xWG3NLT5nVjQoOEZ3KqYBHij3pZkrd5B0UR2z2AW73pUwU4QoNdPbiAgvIw R8HFYLPiwOgjG9fXglA8R5lT+hd8d4JUkr2iepOE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hans de Goede , Ard Biesheuvel , Ingo Molnar , linux-efi@vger.kernel.org, Thomas Gleixner Subject: [PATCH 5.5 186/189] efi/x86: Align GUIDs to their size in the mixed mode runtime wrapper Date: Tue, 10 Mar 2020 13:40:23 +0100 Message-Id: <20200310123658.257035725@linuxfoundation.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200310123639.608886314@linuxfoundation.org> References: <20200310123639.608886314@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: Ard Biesheuvel commit 63056e8b5ebf41d52170e9f5ba1fc83d1855278c upstream. Hans reports that his mixed mode systems running v5.6-rc1 kernels hit the WARN_ON() in virt_to_phys_or_null_size(), caused by the fact that efi_guid_t objects on the vmap'ed stack happen to be misaligned with respect to their sizes. As a quick (i.e., backportable) fix, copy GUID pointer arguments to the local stack into a buffer that is naturally aligned to its size, so that it is guaranteed to cover only one physical page. Note that on x86, we cannot rely on the stack pointer being aligned the way the compiler expects, so we need to allocate an 8-byte aligned buffer of sufficient size, and copy the GUID into that buffer at an offset that is aligned to 16 bytes. Fixes: f6697df36bdf0bf7 ("x86/efi: Prevent mixed mode boot corruption with CONFIG_VMAP_STACK=y") Reported-by: Hans de Goede Signed-off-by: Ard Biesheuvel Signed-off-by: Ingo Molnar Tested-by: Hans de Goede Cc: linux-efi@vger.kernel.org Cc: Ingo Molnar Cc: Thomas Gleixner Link: https://lore.kernel.org/r/20200221084849.26878-2-ardb@kernel.org Signed-off-by: Greg Kroah-Hartman --- arch/x86/platform/efi/efi_64.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -791,6 +791,8 @@ static efi_status_t efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, u32 *attr, unsigned long *data_size, void *data) { + u8 buf[24] __aligned(8); + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); efi_status_t status; u32 phys_name, phys_vendor, phys_attr; u32 phys_data_size, phys_data; @@ -798,8 +800,10 @@ efi_thunk_get_variable(efi_char16_t *nam spin_lock_irqsave(&efi_runtime_lock, flags); + *vnd = *vendor; + phys_data_size = virt_to_phys_or_null(data_size); - phys_vendor = virt_to_phys_or_null(vendor); + phys_vendor = virt_to_phys_or_null(vnd); phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); phys_attr = virt_to_phys_or_null(attr); phys_data = virt_to_phys_or_null_size(data, *data_size); @@ -816,14 +820,18 @@ static efi_status_t efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor, u32 attr, unsigned long data_size, void *data) { + u8 buf[24] __aligned(8); + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); u32 phys_name, phys_vendor, phys_data; efi_status_t status; unsigned long flags; spin_lock_irqsave(&efi_runtime_lock, flags); + *vnd = *vendor; + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); - phys_vendor = virt_to_phys_or_null(vendor); + phys_vendor = virt_to_phys_or_null(vnd); phys_data = virt_to_phys_or_null_size(data, data_size); /* If data_size is > sizeof(u32) we've got problems */ @@ -840,6 +848,8 @@ efi_thunk_set_variable_nonblocking(efi_c u32 attr, unsigned long data_size, void *data) { + u8 buf[24] __aligned(8); + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); u32 phys_name, phys_vendor, phys_data; efi_status_t status; unsigned long flags; @@ -847,8 +857,10 @@ efi_thunk_set_variable_nonblocking(efi_c if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) return EFI_NOT_READY; + *vnd = *vendor; + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); - phys_vendor = virt_to_phys_or_null(vendor); + phys_vendor = virt_to_phys_or_null(vnd); phys_data = virt_to_phys_or_null_size(data, data_size); /* If data_size is > sizeof(u32) we've got problems */ @@ -865,14 +877,18 @@ efi_thunk_get_next_variable(unsigned lon efi_char16_t *name, efi_guid_t *vendor) { + u8 buf[24] __aligned(8); + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); efi_status_t status; u32 phys_name_size, phys_name, phys_vendor; unsigned long flags; spin_lock_irqsave(&efi_runtime_lock, flags); + *vnd = *vendor; + phys_name_size = virt_to_phys_or_null(name_size); - phys_vendor = virt_to_phys_or_null(vendor); + phys_vendor = virt_to_phys_or_null(vnd); phys_name = virt_to_phys_or_null_size(name, *name_size); status = efi_thunk(get_next_variable, phys_name_size, @@ -880,6 +896,7 @@ efi_thunk_get_next_variable(unsigned lon spin_unlock_irqrestore(&efi_runtime_lock, flags); + *vendor = *vnd; return status; }