Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a0b41d1 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Thomas Gleixner
Browse files

x86/mm: Introduce arch_rnd() to compute 32/64 mmap random base



The compat (32bit) mmap() sycall issued by a 64-bit task results in a
mapping above 4GB. That's outside the compat mode address space and
prevents CRIU to restore 32bit processes from a 64bit application.

As a first step to address this, split out the address base randomizing
calculation from arch_mmap_rnd() into a helper function, which can be used
independent of mmap_ia32() based decisions.

[ tglx: Massaged changelog ]

Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarDmitry 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-2-dsafonov@virtuozzo.com


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 4495c08e
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -55,6 +55,14 @@ static unsigned long stack_maxrandom_size(void)
#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
#define MAX_GAP (TASK_SIZE/6*5)

#ifdef CONFIG_COMPAT
# define mmap32_rnd_bits  mmap_rnd_compat_bits
# define mmap64_rnd_bits  mmap_rnd_bits
#else
# define mmap32_rnd_bits  mmap_rnd_bits
# define mmap64_rnd_bits  mmap_rnd_bits
#endif

static int mmap_is_legacy(void)
{
	if (current->personality & ADDR_COMPAT_LAYOUT)
@@ -66,20 +74,14 @@ static int mmap_is_legacy(void)
	return sysctl_legacy_va_layout;
}

unsigned long arch_mmap_rnd(void)
static unsigned long arch_rnd(unsigned int rndbits)
{
	unsigned long rnd;

	if (mmap_is_ia32())
#ifdef CONFIG_COMPAT
		rnd = get_random_long() & ((1UL << mmap_rnd_compat_bits) - 1);
#else
		rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
#endif
	else
		rnd = get_random_long() & ((1UL << mmap_rnd_bits) - 1);
	return (get_random_long() & ((1UL << rndbits) - 1)) << PAGE_SHIFT;
}

	return rnd << PAGE_SHIFT;
unsigned long arch_mmap_rnd(void)
{
	return arch_rnd(mmap_is_ia32() ? mmap32_rnd_bits : mmap64_rnd_bits);
}

static unsigned long mmap_base(unsigned long rnd)