diff options
author | Greg Hackmann <ghackmann@google.com> | 2014-08-28 14:00:10 -0700 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2016-02-16 13:54:03 -0800 |
commit | c6a9c8e51b188d049496643db2cfbb67df65190c (patch) | |
tree | 823ad677a82987ab1166aa36811436a6c180a841 /arch/arm64 | |
parent | 487e34bfedac629ad8af0471ab72ab553871e810 (diff) |
arm64: check for upper PAGE_SHIFT bits in pfn_valid()
pfn_valid() returns a false positive when the lower (64 - PAGE_SHIFT)
bits match a valid pfn but some of the upper bits are set. This caused
a kernel panic in kpageflags_read() when a userspace utility parsed
/proc/*/pagemap, neglected to discard the upper flag bits, and tried to
lseek()+read() from the corresponding offset in /proc/kpageflags.
A valid pfn will never have the upper PAGE_SHIFT bits set, so simply
check for this before passing the pfn to memblock_is_memory().
Change-Id: Ief5d8cd4dd93cbecd545a634a8d5885865cb5970
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Diffstat (limited to 'arch/arm64')
-rw-r--r-- | arch/arm64/mm/init.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 17bf39ac83ba..325f89ff897e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -118,9 +118,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) } #ifdef CONFIG_HAVE_ARCH_PFN_VALID +#define PFN_MASK ((1UL << (64 - PAGE_SHIFT)) - 1) + int pfn_valid(unsigned long pfn) { - return memblock_is_memory(pfn << PAGE_SHIFT); + return (pfn & PFN_MASK) == pfn && memblock_is_memory(pfn << PAGE_SHIFT); } EXPORT_SYMBOL(pfn_valid); #endif |