Skip to content

Commit

Permalink
x86/mpx: Fix 32-bit address space calculation
Browse files Browse the repository at this point in the history
I received a bug report that running 32-bit MPX binaries on
64-bit kernels was broken.  I traced it down to this little code
snippet.  We were switching our "number of bounds directory
entries" calculation correctly.  But, we didn't switch the other
side of the calculation: the virtual space size.

This meant that we were calculating an absurd size for
bd_entry_virt_space() on 32-bit because we used the 64-bit
virt_space.

This was _also_ broken for 32-bit kernels running on 64-bit
hardware since boot_cpu_data.x86_virt_bits=48 even when running
in 32-bit mode.

Correct that and properly handle all 3 possible cases:

 1. 32-bit binary on 64-bit kernel
 2. 64-bit binary on 64-bit kernel
 3. 32-bit binary on 32-bit kernel

This manifested in having bounds tables not properly unmapped.
It "leaked" memory but had no functional impact otherwise.

Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: <stable@vger.kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave@sr71.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20151111181934.FA7FAC34@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Dave Hansen authored and Ingo Molnar committed Nov 12, 2015
1 parent 46561c3 commit f3119b8
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions arch/x86/mm/mpx.c
Original file line number Diff line number Diff line change
@@ -723,11 +723,23 @@ static unsigned long mpx_get_bt_entry_offset_bytes(struct mm_struct *mm,
*/
static inline unsigned long bd_entry_virt_space(struct mm_struct *mm)
{
unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
if (is_64bit_mm(mm))
return virt_space / MPX_BD_NR_ENTRIES_64;
else
return virt_space / MPX_BD_NR_ENTRIES_32;
unsigned long long virt_space;
unsigned long long GB = (1ULL << 30);

/*
* This covers 32-bit emulation as well as 32-bit kernels
* running on 64-bit harware.
*/
if (!is_64bit_mm(mm))
return (4ULL * GB) / MPX_BD_NR_ENTRIES_32;

/*
* 'x86_virt_bits' returns what the hardware is capable
* of, and returns the full >32-bit adddress space when
* running 32-bit kernels on 64-bit hardware.
*/
virt_space = (1ULL << boot_cpu_data.x86_virt_bits);
return virt_space / MPX_BD_NR_ENTRIES_64;
}

/*

0 comments on commit f3119b8

Please sign in to comment.