Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp1705640ybi; Wed, 17 Jul 2019 20:28:16 -0700 (PDT) X-Google-Smtp-Source: APXvYqx3S4fK/Ca6+xYBFx6hnUH3GeqwnnU3husVraekzMezlRvGFDSQ4uBKrez2cYd2cvG2JXWB X-Received: by 2002:a17:902:b905:: with SMTP id bf5mr44358641plb.342.1563420496251; Wed, 17 Jul 2019 20:28:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563420496; cv=none; d=google.com; s=arc-20160816; b=Bx9KJH3iHB4d/in05HA0kcUSt8dX2FLEvYTv+fAnuezuWBBgULJwuXRD3sp3ve6t2A /cLTfvntiDzt1GvoHJHTN7YUadJ3xDhCLwl6ImxvIS9EfCyJt+lMimY4Xu8o/JnAlAtg qrvGZ5QHQr11MaQedYrj2HvmgNnkt8wx0m3T2A17uP555Z5fR15Vb8Keu8HXCHXkq0JD T/UuXNwIyT0bn6TEKDR5tTo1kw5Yd1Uqne6+W8/2B8Qw2KWzZRHfHgyTGT/IMuSsShyb Ozz6PYNTcwDWdW87a+NPGAMiZKVQ2Ba34/smtnF9zj4g2yLfzIBeBGUSStMcFKv72Q9U SYwQ== 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=72+d9ropSnf+P/bVg2abFLLAh352LDSb8msogmSlHIc=; b=erUrgxB/Cnv3EAjHpmlU91qpPoPJFDLorm7a/rBu38zIHzBl8OQhWe/EXCpARP5+MJ Ow451jNbVn++1A0NA7rM9ntgGuAJz5VzbjZpdep7QQ3c8YJa8jIJvueNT/rFJJ23rCL5 PsBBiepoJAwN5Zm4nfo5LV7/mHHAw1wGae1daZnnIcLFhgBt8aDyyzWI8mtl96/QJ6Vn lsEjCZVB56O1IctAH3AxsBT/xYmZ8/IIKZ4U9m4/nxCZtqXGJdg/CityXlkbnDJKDQh/ A/sF3toSCoEulkXAbaPkCnGnv6Je+zUufFUWLdbX+zyj3OjKNPpg8w+rCNBg3awooVSO UyiA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ISTMWEmD; 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 131si89221pfu.165.2019.07.17.20.28.00; Wed, 17 Jul 2019 20:28:16 -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=ISTMWEmD; 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 S2389861AbfGRDFG (ORCPT + 99 others); Wed, 17 Jul 2019 23:05:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:36024 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727822AbfGRDFD (ORCPT ); Wed, 17 Jul 2019 23:05:03 -0400 Received: from localhost (115.42.148.210.bf.2iij.net [210.148.42.115]) (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 E238C2053B; Thu, 18 Jul 2019 03:05:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1563419102; bh=28zCHK5yuvWJPg6l0q6O7kS11mbjehpetbxQ/HaLk+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ISTMWEmDHQW/PvGhJNhQLjSRYt8NX716NFnJJjDB4lsSyQwIuIkdNIeE7oeAKIYua B0jeayxtSwE3zJR+7YDb0lQHES2U1XHrDBS9snzDU5AF5M1JljjspLDfD9KwkH3eRj vMEVAHeo4Z7pDpaIKaLQzKyxdp18bpGJf2Ko5FQU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Kirill A. Shutemov" , Thomas Gleixner , Borislav Petkov , "H. Peter Anvin" , Dave Hansen , Andy Lutomirski , Peter Zijlstra , Sasha Levin Subject: [PATCH 5.1 30/54] x86/boot/64: Fix crash if kernel image crosses page table boundary Date: Thu, 18 Jul 2019 12:01:25 +0900 Message-Id: <20190718030055.675779386@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190718030053.287374640@linuxfoundation.org> References: <20190718030053.287374640@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 [ Upstream commit 81c7ed296dcd02bc0b4488246d040e03e633737a ] A kernel which boots in 5-level paging mode crashes in a small percentage of cases if KASLR is enabled. This issue was tracked down to the case when the kernel image unpacks in a way that it crosses an 1G boundary. The crash is caused by an overrun of the PMD page table in __startup_64() and corruption of P4D page table allocated next to it. This particular issue is not visible with 4-level paging as P4D page tables are not used. But the P4D and the PUD calculation have similar problems. The PMD index calculation is wrong due to operator precedence, which fails to confine the PMDs in the PMD array on wrap around. The P4D calculation for 5-level paging and the PUD calculation calculate the first index correctly, but then blindly increment it which causes the same issue when a kernel image is located across a 512G and for 5-level paging across a 46T boundary. This wrap around mishandling was introduced when these parts moved from assembly to C. Restore it to the correct behaviour. Fixes: c88d71508e36 ("x86/boot/64: Rewrite startup_64() in C") Signed-off-by: Kirill A. Shutemov Signed-off-by: Thomas Gleixner Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Dave Hansen Cc: Andy Lutomirski Cc: Peter Zijlstra Link: https://lkml.kernel.org/r/20190620112345.28833-1-kirill.shutemov@linux.intel.com Signed-off-by: Sasha Levin --- arch/x86/kernel/head64.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 16b1cbd3a61e..7df5bce4e1be 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -190,18 +190,18 @@ unsigned long __head __startup_64(unsigned long physaddr, pgd[i + 0] = (pgdval_t)p4d + pgtable_flags; pgd[i + 1] = (pgdval_t)p4d + pgtable_flags; - i = (physaddr >> P4D_SHIFT) % PTRS_PER_P4D; - p4d[i + 0] = (pgdval_t)pud + pgtable_flags; - p4d[i + 1] = (pgdval_t)pud + pgtable_flags; + i = physaddr >> P4D_SHIFT; + p4d[(i + 0) % PTRS_PER_P4D] = (pgdval_t)pud + pgtable_flags; + p4d[(i + 1) % PTRS_PER_P4D] = (pgdval_t)pud + pgtable_flags; } else { i = (physaddr >> PGDIR_SHIFT) % PTRS_PER_PGD; pgd[i + 0] = (pgdval_t)pud + pgtable_flags; pgd[i + 1] = (pgdval_t)pud + pgtable_flags; } - i = (physaddr >> PUD_SHIFT) % PTRS_PER_PUD; - pud[i + 0] = (pudval_t)pmd + pgtable_flags; - pud[i + 1] = (pudval_t)pmd + pgtable_flags; + i = physaddr >> PUD_SHIFT; + pud[(i + 0) % PTRS_PER_PUD] = (pudval_t)pmd + pgtable_flags; + pud[(i + 1) % PTRS_PER_PUD] = (pudval_t)pmd + pgtable_flags; pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; /* Filter out unsupported __PAGE_KERNEL_* bits: */ @@ -211,8 +211,9 @@ unsigned long __head __startup_64(unsigned long physaddr, pmd_entry += physaddr; for (i = 0; i < DIV_ROUND_UP(_end - _text, PMD_SIZE); i++) { - int idx = i + (physaddr >> PMD_SHIFT) % PTRS_PER_PMD; - pmd[idx] = pmd_entry + i * PMD_SIZE; + int idx = i + (physaddr >> PMD_SHIFT); + + pmd[idx % PTRS_PER_PMD] = pmd_entry + i * PMD_SIZE; } /* -- 2.20.1