mirror of https://gitee.com/openkylin/linux.git
x86/mm: Make mmap(MAP_32BIT) work correctly
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>
This commit is contained in:
parent
1b028f784e
commit
3e6ef9c809
|
@ -115,7 +115,7 @@ static unsigned long get_mmap_base(int is_legacy)
|
|||
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
|
||||
|
@ -191,7 +191,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 */
|
||||
|
|
Loading…
Reference in New Issue