linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP
@ 2018-09-15  5:51 Huacai Chen
  2018-09-17 19:15 ` Paul Burton
  2018-09-25 23:23 ` [PATCH] MIPS: VDSO: Always map near top of user memory Paul Burton
  0 siblings, 2 replies; 6+ messages in thread
From: Huacai Chen @ 2018-09-15  5:51 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: Paul Burton, James Hogan, linux-mips, Fuxin Zhang, Zhangjin Wu,
	Huacai Chen, Huacai Chen

Unlimited stack size (ulimit -s unlimited) causes kernel to use legacy
layout for applications. Thus, if VDSO isn't mapped above STACK_TOP, it
will be mapped at a very low address. This will probably cause an early
brk() failure, because the application's initial mm->brk is usually
below VDSO (especially when COMPAT_BRK is enabled) and there is no more
room to expand its heap.

This patch reserve 4 MB space above STACK_TOP, and use the low 2 MB for
VDSO randomization (as a result, VDSO pages can use as much as 2 MB).

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/processor.h |  5 +++--
 arch/mips/kernel/vdso.c           | 16 +++++++++++++++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index b2fa629..8964eca 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -13,6 +13,7 @@
 
 #include <linux/atomic.h>
 #include <linux/cpumask.h>
+#include <linux/sizes.h>
 #include <linux/threads.h>
 
 #include <asm/cachectl.h>
@@ -82,9 +83,9 @@ extern unsigned int vced_count, vcei_count;
 
 /*
  * One page above the stack is used for branch delay slot "emulation".
- * See dsemul.c for details.
+ * See dsemul.c for details, other pages are for VDSO.
  */
-#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - PAGE_SIZE)
+#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - SZ_4M)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 8f845f6..9a17467 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/timekeeper_internal.h>
@@ -97,6 +98,19 @@ void update_vsyscall_tz(void)
 	}
 }
 
+static unsigned long vdso_base(void)
+{
+	unsigned long offset = 0UL;
+
+	if (current->flags & PF_RANDOMIZE) {
+		offset = get_random_int();
+		offset <<= PAGE_SHIFT;
+		offset &= 0x1ffffful; /* 2 MB */
+	}
+
+	return STACK_TOP + PAGE_SIZE + offset;
+}
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mips_vdso_image *image = current->thread.abi->vdso;
@@ -137,7 +151,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (cpu_has_dc_aliases)
 		size += shm_align_mask + 1;
 
-	base = get_unmapped_area(NULL, 0, size, 0, 0);
+	base = get_unmapped_area(NULL, vdso_base(), size, 0, 0);
 	if (IS_ERR_VALUE(base)) {
 		ret = base;
 		goto out;
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP
  2018-09-15  5:51 [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP Huacai Chen
@ 2018-09-17 19:15 ` Paul Burton
  2018-09-18  8:21   ` Huacai Chen
  2018-09-25 23:23 ` [PATCH] MIPS: VDSO: Always map near top of user memory Paul Burton
  1 sibling, 1 reply; 6+ messages in thread
From: Paul Burton @ 2018-09-17 19:15 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, James Hogan, linux-mips, Fuxin Zhang, Zhangjin Wu,
	Huacai Chen

Hi Huacai,

On Sat, Sep 15, 2018 at 01:51:30PM +0800, Huacai Chen wrote:
> Unlimited stack size (ulimit -s unlimited) causes kernel to use legacy
> layout for applications. Thus, if VDSO isn't mapped above STACK_TOP, it
> will be mapped at a very low address. This will probably cause an early
> brk() failure, because the application's initial mm->brk is usually
> below VDSO (especially when COMPAT_BRK is enabled) and there is no more
> room to expand its heap.
> 
> This patch reserve 4 MB space above STACK_TOP, and use the low 2 MB for
> VDSO randomization (as a result, VDSO pages can use as much as 2 MB).
> 
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> ---
>  arch/mips/include/asm/processor.h |  5 +++--
>  arch/mips/kernel/vdso.c           | 16 +++++++++++++++-
>  2 files changed, 18 insertions(+), 3 deletions(-)

Could you give an example of a program that fails due to this?

I'm able to reproduce that with ulimit -s unlimited the VDSO gets placed
just above the heap, but the ELF interpreter & shared libraries get
mapped nearby too so even with the VDSO moved a brk syscall would still
presumably fail at around the same point. For example:

  # ulimit -s unlimited; cat /proc/self/maps
  00400000-004ec000 r-xp 00000000 08:00 71436      /usr/bin/coreutils
  004fc000-004fd000 rwxp 000ec000 08:00 71436      /usr/bin/coreutils
  004fd000-0050f000 rwxp 00000000 00:00 0
  00cc3000-00ce4000 rwxp 00000000 00:00 0          [heap]
  2ab75000-2ab96000 r-xp 00000000 08:00 44641      /lib/ld-linux-mipsn8.so.1
  2ab96000-2ab98000 r--p 00000000 00:00 0          [vvar]
  2ab98000-2ab99000 r-xp 00000000 00:00 0          [vdso]
  2ab99000-2ab9d000 rwxp 00000000 00:00 0
  2aba5000-2aba6000 r-xp 00020000 08:00 44641      /lib/ld-linux-mipsn8.so.1
  2aba6000-2aba7000 rwxp 00021000 08:00 44641      /lib/ld-linux-mipsn8.so.1
  2aba7000-2ad18000 r-xp 00000000 08:00 477163     /usr/lib/libcrypto.so.1.0.0
  2ad18000-2ad27000 ---p 00171000 08:00 477163     /usr/lib/libcrypto.so.1.0.0
  ...

Are you running something statically linked to avoid that?

Apart from that I'm not keen on unconditionally taking away 4MB of
address space. For o32 programs we already only have 2GB of user address
space & it's not unheard of for programs to bump up against that limit,
so reducing it further would need to be a last resort. If we did need to
move VDSO to the top of the user address space we can do that with a
hint to get_unmapped_area() without changing STACK_TOP.

Thanks,
    Paul

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP
  2018-09-17 19:15 ` Paul Burton
@ 2018-09-18  8:21   ` Huacai Chen
  0 siblings, 0 replies; 6+ messages in thread
From: Huacai Chen @ 2018-09-18  8:21 UTC (permalink / raw)
  To: Paul Burton
  Cc: Ralf Baechle, James Hogan, Linux MIPS Mailing List, Fuxin Zhang,
	Zhangjin Wu

On Tue, Sep 18, 2018 at 3:15 AM, Paul Burton <paul.burton@mips.com> wrote:
> Hi Huacai,
>
> On Sat, Sep 15, 2018 at 01:51:30PM +0800, Huacai Chen wrote:
>> Unlimited stack size (ulimit -s unlimited) causes kernel to use legacy
>> layout for applications. Thus, if VDSO isn't mapped above STACK_TOP, it
>> will be mapped at a very low address. This will probably cause an early
>> brk() failure, because the application's initial mm->brk is usually
>> below VDSO (especially when COMPAT_BRK is enabled) and there is no more
>> room to expand its heap.
>>
>> This patch reserve 4 MB space above STACK_TOP, and use the low 2 MB for
>> VDSO randomization (as a result, VDSO pages can use as much as 2 MB).
>>
>> Signed-off-by: Huacai Chen <chenhc@lemote.com>
>> ---
>>  arch/mips/include/asm/processor.h |  5 +++--
>>  arch/mips/kernel/vdso.c           | 16 +++++++++++++++-
>>  2 files changed, 18 insertions(+), 3 deletions(-)
>
> Could you give an example of a program that fails due to this?
>
> I'm able to reproduce that with ulimit -s unlimited the VDSO gets placed
> just above the heap, but the ELF interpreter & shared libraries get
> mapped nearby too so even with the VDSO moved a brk syscall would still
> presumably fail at around the same point. For example:
>
>   # ulimit -s unlimited; cat /proc/self/maps
>   00400000-004ec000 r-xp 00000000 08:00 71436      /usr/bin/coreutils
>   004fc000-004fd000 rwxp 000ec000 08:00 71436      /usr/bin/coreutils
>   004fd000-0050f000 rwxp 00000000 00:00 0
>   00cc3000-00ce4000 rwxp 00000000 00:00 0          [heap]
>   2ab75000-2ab96000 r-xp 00000000 08:00 44641      /lib/ld-linux-mipsn8.so.1
>   2ab96000-2ab98000 r--p 00000000 00:00 0          [vvar]
>   2ab98000-2ab99000 r-xp 00000000 00:00 0          [vdso]
>   2ab99000-2ab9d000 rwxp 00000000 00:00 0
>   2aba5000-2aba6000 r-xp 00020000 08:00 44641      /lib/ld-linux-mipsn8.so.1
>   2aba6000-2aba7000 rwxp 00021000 08:00 44641      /lib/ld-linux-mipsn8.so.1
>   2aba7000-2ad18000 r-xp 00000000 08:00 477163     /usr/lib/libcrypto.so.1.0.0
>   2ad18000-2ad27000 ---p 00171000 08:00 477163     /usr/lib/libcrypto.so.1.0.0
>   ...
>
> Are you running something statically linked to avoid that?
Yes, I use a statically linked binary, so heap expanding is only
affected by VDSO, but not by ld.so. However, in the legacy layout
case, both VDSO and ld.so are mapped begin with TASK_UNMAPPED_BASE
(0x2AAAB000), so a dynamically linked binary's heap will not probablly
hit VDSO/ld.so (because dynamically linked binaries are small).

>
> Apart from that I'm not keen on unconditionally taking away 4MB of
> address space. For o32 programs we already only have 2GB of user address
> space & it's not unheard of for programs to bump up against that limit,
> so reducing it further would need to be a last resort. If we did need to
> move VDSO to the top of the user address space we can do that with a
> hint to get_unmapped_area() without changing STACK_TOP.
The task stack is allocated very early, if without changing STACK_TOP,
get_unmapped_area() cannot assure that VDSO is above stack.

Huacai

>
> Thanks,
>     Paul

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] MIPS: VDSO: Always map near top of user memory
  2018-09-15  5:51 [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP Huacai Chen
  2018-09-17 19:15 ` Paul Burton
@ 2018-09-25 23:23 ` Paul Burton
       [not found]   ` <tencent_7D95F91F120F9BCE2DCAC958@qq.com>
  1 sibling, 1 reply; 6+ messages in thread
From: Paul Burton @ 2018-09-25 23:23 UTC (permalink / raw)
  To: Huacai Chen, Huacai Chen, linux-mips; +Cc: stable, Paul Burton

When using the legacy mmap layout, for example triggered using ulimit -s
unlimited, get_unmapped_area() fills memory from bottom to top starting
from a fairly low address near TASK_UNMAPPED_BASE.

This placement is suboptimal if the user application wishes to allocate
large amounts of heap memory using the brk syscall. With the VDSO being
located low in the user's virtual address space, the amount of space
available for access using brk is limited much more than it was prior to
the introduction of the VDSO.

For example:

  # ulimit -s unlimited; cat /proc/self/maps
  00400000-004ec000 r-xp 00000000 08:00 71436      /usr/bin/coreutils
  004fc000-004fd000 rwxp 000ec000 08:00 71436      /usr/bin/coreutils
  004fd000-0050f000 rwxp 00000000 00:00 0
  00cc3000-00ce4000 rwxp 00000000 00:00 0          [heap]
  2ab96000-2ab98000 r--p 00000000 00:00 0          [vvar]
  2ab98000-2ab99000 r-xp 00000000 00:00 0          [vdso]
  2ab99000-2ab9d000 rwxp 00000000 00:00 0
  ...

Resolve this by adjusting STACK_TOP to reserve space for the VDSO &
providing an address hint to get_unmapped_area() causing it to use this
space even when using the legacy mmap layout.

We reserve enough space for the VDSO, plus 1MB or 8MB for 32 bit & 64
bit systems respectively within which we randomize the VDSO base
address. Previously this randomization was taken care of by the mmap
base address randomization performed by arch_mmap_rnd(). The 1MB & 8MB
sizes are somewhat arbitrary but chosen such that we have some
randomization without taking up too much of the user's virtual address
space, which is often in short supply for 32 bit systems.

With this the VDSO is always mapped at a high address, leaving lots of
space for statically linked programs to make use of brk:

  # ulimit -s unlimited; cat /proc/self/maps
  00400000-004ec000 r-xp 00000000 08:00 71436      /usr/bin/coreutils
  004fc000-004fd000 rwxp 000ec000 08:00 71436      /usr/bin/coreutils
  004fd000-0050f000 rwxp 00000000 00:00 0
  00c28000-00c49000 rwxp 00000000 00:00 0          [heap]
  ...
  7f67c000-7f69d000 rwxp 00000000 00:00 0          [stack]
  7f7fc000-7f7fd000 rwxp 00000000 00:00 0
  7fcf1000-7fcf3000 r--p 00000000 00:00 0          [vvar]
  7fcf3000-7fcf4000 r-xp 00000000 00:00 0          [vdso]

Signed-off-by: Paul Burton <paul.burton@mips.com>
Reported-by: Huacai Chen <chenhc@lemote.com>
Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO")
Cc: Huacai Chen <chenhc@lemote.com>
Cc: linux-mips@linux-mips.org
Cc: stable@vger.kernel.org # v4.4+
---
Huacai, could you test if this fixes your problem?

It takes up less of the user's virtual address space (only 1MB for
MIPS32), takes none at all when randomization is disabled, and doesn't
make assumptions about the size of the VDSO.
---
 arch/mips/include/asm/processor.h | 10 +++++-----
 arch/mips/kernel/process.c        | 25 +++++++++++++++++++++++++
 arch/mips/kernel/vdso.c           | 18 +++++++++++++++++-
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index b2fa62922d88..15917ee42f9f 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -13,6 +13,7 @@
 
 #include <linux/atomic.h>
 #include <linux/cpumask.h>
+#include <linux/sizes.h>
 #include <linux/threads.h>
 
 #include <asm/cachectl.h>
@@ -80,11 +81,10 @@ extern unsigned int vced_count, vcei_count;
 
 #endif
 
-/*
- * One page above the stack is used for branch delay slot "emulation".
- * See dsemul.c for details.
- */
-#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - PAGE_SIZE)
+#define VDSO_RANDOMIZE_SIZE	(test_thread_flag(TIF_32BIT_ADDR) ? SZ_1M : SZ_8M)
+
+extern unsigned long mips_stack_top(void);
+#define STACK_TOP		mips_stack_top()
 
 /*
  * This decides where the kernel will search for a free chunk of vm
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 8fc69891e117..1b699a367c45 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -32,6 +32,7 @@
 #include <linux/nmi.h>
 #include <linux/cpu.h>
 
+#include <asm/abi.h>
 #include <asm/asm.h>
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -39,6 +40,7 @@
 #include <asm/dsp.h>
 #include <asm/fpu.h>
 #include <asm/irq.h>
+#include <asm/mips-gic.h>
 #include <asm/msa.h>
 #include <asm/pgtable.h>
 #include <asm/mipsregs.h>
@@ -645,6 +647,29 @@ unsigned long get_wchan(struct task_struct *task)
 	return pc;
 }
 
+unsigned long mips_stack_top(void)
+{
+	unsigned long top = TASK_SIZE & PAGE_MASK;
+
+	/* One page for branch delay slot "emulation" */
+	top -= PAGE_SIZE;
+
+	/* Space for the VDSO, data page & GIC user page */
+	top -= PAGE_ALIGN(current->thread.abi->vdso->size);
+	top -= PAGE_SIZE;
+	top -= mips_gic_present() ? PAGE_SIZE : 0;
+
+	/* Space for cache colour alignment */
+	if (cpu_has_dc_aliases)
+		top -= shm_align_mask + 1;
+
+	/* Space to randomize the VDSO base */
+	if (current->flags & PF_RANDOMIZE)
+		top -= VDSO_RANDOMIZE_SIZE;
+
+	return top;
+}
+
 /*
  * Don't forget that the stack pointer must be aligned on a 8 bytes
  * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 8f845f6e5f42..48a9c6b90e07 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -15,6 +15,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/timekeeper_internal.h>
@@ -97,6 +98,21 @@ void update_vsyscall_tz(void)
 	}
 }
 
+static unsigned long vdso_base(void)
+{
+	unsigned long base;
+
+	/* Skip the delay slot emulation page */
+	base = STACK_TOP + PAGE_SIZE;
+
+	if (current->flags & PF_RANDOMIZE) {
+		base += get_random_int() & (VDSO_RANDOMIZE_SIZE - 1);
+		base = PAGE_ALIGN(base);
+	}
+
+	return base;
+}
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mips_vdso_image *image = current->thread.abi->vdso;
@@ -137,7 +153,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (cpu_has_dc_aliases)
 		size += shm_align_mask + 1;
 
-	base = get_unmapped_area(NULL, 0, size, 0, 0);
+	base = get_unmapped_area(NULL, vdso_base(), size, 0, 0);
 	if (IS_ERR_VALUE(base)) {
 		ret = base;
 		goto out;
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] MIPS: VDSO: Always map near top of user memory
       [not found]   ` <tencent_7D95F91F120F9BCE2DCAC958@qq.com>
@ 2018-09-27 18:16     ` Paul Burton
  0 siblings, 0 replies; 6+ messages in thread
From: Paul Burton @ 2018-09-27 18:16 UTC (permalink / raw)
  To: 陈华才; +Cc: Huacai Chen, linux-mips, stable, Paul Burton

Hi Huacai,

On Thu, Sep 27, 2018 at 02:26:42PM +0800, 陈华才 wrote:
> I think this patch can solve my problem, but I have something to say:
>
> 1, VDSO randomization is introduced in commit
> ccd3988086364837d0c0fb4563d7 in 3.19. So this patch should backported
> as early as 3.19.

Ugh, OK so the not-really-a-VDSO page that we called VDSO before we
really had a VDSO was randomly located too. A backport to that would
need to be significantly different.

However the only currently supported LTS kernel older than 4.4 (which
introduced the real VDSO) is 3.16. 3.16 didn't support the randomization
anyway, I don't think it's worth the effort to backport any further than
4.4.

> 2, vdso_base() may need to be modified for 4.4, because 4.4 has no
> delay slot emulation.

Yes I know. The GIC code changed in 4.14 too so backports will need to
take that into account too.

> 3, Maybe it is better to set VDSO_RANDOMIZE_SIZE to 16MB for 64bit
> kernel, because commit ccd3988086364837d0c0fb4563d7 use 16MB.

It actually uses 256MB for MIPS64. Since address space isn't scarce
for MIPS64 I'll go with that.

Thanks,
    Paul

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP
@ 2017-11-16  8:33 Huacai Chen
  0 siblings, 0 replies; 6+ messages in thread
From: Huacai Chen @ 2017-11-16  8:33 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

Unlimited stack size (ulimit -s unlimited) causes kernel to use legacy
layout for applications. Thus, if VDSO isn't mapped above STACK_TOP, it
will be mapped at a very low address. This will probably cause an early
brk() failure, because the application's initial mm->brk is usually
below VDSO (especially when COMPAT_BRK is enabled) and there is no more
room to expand its heap.

This patch reserve 4 MB space above STACK_TOP, and use the low 2 MB for
VDSO randomization (as a result, VDSO pages can use as much as 2 MB).

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/processor.h |  5 +++--
 arch/mips/kernel/vdso.c           | 16 +++++++++++++++-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index af34afb..7fff032 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -13,6 +13,7 @@
 
 #include <linux/atomic.h>
 #include <linux/cpumask.h>
+#include <linux/sizes.h>
 #include <linux/threads.h>
 
 #include <asm/cachectl.h>
@@ -82,9 +83,9 @@ extern unsigned int vced_count, vcei_count;
 
 /*
  * One page above the stack is used for branch delay slot "emulation".
- * See dsemul.c for details.
+ * See dsemul.c for details, other pages are for VDSO.
  */
-#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - PAGE_SIZE)
+#define STACK_TOP	((TASK_SIZE & PAGE_MASK) - SZ_4M)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 019035d..6ec4537 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/timekeeper_internal.h>
@@ -95,6 +96,19 @@ void update_vsyscall_tz(void)
 	}
 }
 
+static unsigned long vdso_base(void)
+{
+	unsigned long offset = 0UL;
+
+	if (current->flags & PF_RANDOMIZE) {
+		offset = get_random_int();
+		offset <<= PAGE_SHIFT;
+		offset &= 0x1ffffful; /* 2 MB */
+	}
+
+	return STACK_TOP + PAGE_SIZE + offset;
+}
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mips_vdso_image *image = current->thread.abi->vdso;
@@ -128,7 +142,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	vvar_size = gic_size + PAGE_SIZE;
 	size = vvar_size + image->size;
 
-	base = get_unmapped_area(NULL, 0, size, 0, 0);
+	base = get_unmapped_area(NULL, vdso_base(), size, 0, 0);
 	if (IS_ERR_VALUE(base)) {
 		ret = base;
 		goto out;
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-09-27 18:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-15  5:51 [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP Huacai Chen
2018-09-17 19:15 ` Paul Burton
2018-09-18  8:21   ` Huacai Chen
2018-09-25 23:23 ` [PATCH] MIPS: VDSO: Always map near top of user memory Paul Burton
     [not found]   ` <tencent_7D95F91F120F9BCE2DCAC958@qq.com>
2018-09-27 18:16     ` Paul Burton
  -- strict thread matches above, loose matches on Subject: below --
2017-11-16  8:33 [PATCH Resend] MIPS: Ensure VDSO pages mapped above STACK_TOP Huacai Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).