From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>,
"Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>,
Thomas Gleixner <tglx@linutronix.de>,
Borislav Petkov <bp@alien8.de>, "H. Peter Anvin" <hpa@zytor.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Andy Lutomirski <luto@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH AUTOSEL 4.14 11/13] x86/boot/64: Fix crash if kernel image crosses page table boundary
Date: Tue, 2 Jul 2019 22:18:12 -0400 [thread overview]
Message-ID: <20190703021814.18385-11-sashal@kernel.org> (raw)
In-Reply-To: <20190703021814.18385-1-sashal@kernel.org>
From: "Kirill A. Shutemov" <kirill@shutemov.name>
[ 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 <kirill.shutemov@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20190620112345.28833-1-kirill.shutemov@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
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 45b5c6c4a55e..7c67d8939f3e 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -117,26 +117,27 @@ 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;
pmd_entry += sme_get_me_mask();
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
next prev parent reply other threads:[~2019-07-03 2:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-03 2:18 [PATCH AUTOSEL 4.14 01/13] clk: ti: clkctrl: Fix returning uninitialized data Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 02/13] efi/bgrt: Drop BGRT status field reserved bits check Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 03/13] perf/core: Fix perf_sample_regs_user() mm check Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 04/13] ARM: omap2: remove incorrect __init annotation Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 05/13] be2net: fix link failure after ethtool offline test Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 06/13] ppp: mppe: Add softdep to arc4 Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 07/13] net: stmmac: fixed new system time seconds value calculation Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 08/13] sis900: fix TX completion Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 09/13] ARM: dts: imx6ul: fix PWM[1-4] interrupts Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 10/13] dm verity: use message limit for data block corruption message Sasha Levin
2019-07-03 2:18 ` Sasha Levin [this message]
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 12/13] cpu/hotplug: Fix out-of-bounds read when setting fail state Sasha Levin
2019-07-03 2:18 ` [PATCH AUTOSEL 4.14 13/13] linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190703021814.18385-11-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=kirill@shutemov.name \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=peterz@infradead.org \
--cc=stable@vger.kernel.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).