mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
x86/mm: Make mmap(MAP_32BIT) work correctly
[ Upstream commit 3e6ef9c809 ]
mmap(MAP_32BIT) is broken due to the dependency on the TIF_ADDR32 thread
flag.
For 64bit applications MAP_32BIT will force legacy bottom-up allocations and
the 1GB address space restriction even if the application issued a compat
syscall, which should not be subject of these restrictions.
For 32bit applications, which issue 64bit syscalls the newly introduced
mmap base separation into 64-bit and compat bases changed the behaviour
because now a 64-bit mapping is returned, but due to the TIF_ADDR32
dependency MAP_32BIT is ignored. Before the separation a 32-bit mapping was
returned, so the MAP_32BIT handling was irrelevant.
Replace the check for TIF_ADDR32 with a check for the compat syscall. That
solves both the 64-bit issuing a compat syscall and the 32-bit issuing a
64-bit syscall problems.
[ tglx: Massaged changelog ]
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Cc: 0x7f454c46@gmail.com
Cc: linux-mm@kvack.org
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Link: http://lkml.kernel.org/r/20170306141721.9188-5-dsafonov@virtuozzo.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
b243aa88a7
commit
45142b2857
@@ -16,6 +16,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/elf.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/ia32.h>
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
@@ -100,7 +101,7 @@ out:
|
||||
static void find_start_end(unsigned long flags, unsigned long *begin,
|
||||
unsigned long *end)
|
||||
{
|
||||
if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT)) {
|
||||
if (!in_compat_syscall() && (flags & MAP_32BIT)) {
|
||||
/* This is usually used needed to map code in small
|
||||
model, so it needs to be in the first 31bit. Limit
|
||||
it to that. This means we need to move the
|
||||
@@ -175,7 +176,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
||||
return addr;
|
||||
|
||||
/* for MAP_32BIT mappings we force the legacy mmap base */
|
||||
if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT))
|
||||
if (!in_compat_syscall() && (flags & MAP_32BIT))
|
||||
goto bottomup;
|
||||
|
||||
/* requesting a specific address */
|
||||
|
||||
Reference in New Issue
Block a user