Skip to content

Commit 5f74f82

Browse files
hdellerakpm00
authored andcommitted
parisc: fix mmap_base calculation when stack grows upwards
Matoro reported various userspace crashes on the parisc platform with kernel 6.6 and bisected it to commit 3033cd4 ("parisc: Use generic mmap top-down layout and brk randomization"). That commit switched parisc to use the common infrastructure to calculate mmap_base, but missed that the mmap_base() function takes care for architectures where the stack grows downwards only. Fix the mmap_base() calculation to include the stack-grows-upwards case and thus fix the userspace crashes on parisc. Link: https://lkml.kernel.org/r/ZVH2qeS1bG7/1J/l@p100 Fixes: 3033cd4 ("parisc: Use generic mmap top-down layout and brk randomization") Signed-off-by: Helge Deller <deller@gmx.de> Reported-by: matoro <matoro_mailinglist_kernel@matoro.tk> Tested-by: matoro <matoro_mailinglist_kernel@matoro.tk> Cc: <stable@vger.kernel.org> [6.6+] Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 13b2a4b commit 5f74f82

5 files changed

Lines changed: 17 additions & 13 deletions

File tree

arch/parisc/Kconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ config ARCH_MMAP_RND_COMPAT_BITS_MIN
140140
default 8
141141

142142
config ARCH_MMAP_RND_BITS_MAX
143-
default 24 if 64BIT
144-
default 17
143+
default 18 if 64BIT
144+
default 13
145145

146146
config ARCH_MMAP_RND_COMPAT_BITS_MAX
147-
default 17
147+
default 13
148148

149149
# unless you want to implement ACPI on PA-RISC ... ;-)
150150
config PM

arch/parisc/include/asm/elf.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -349,15 +349,7 @@ struct pt_regs; /* forward declaration... */
349349

350350
#define ELF_HWCAP 0
351351

352-
/* Masks for stack and mmap randomization */
353-
#define BRK_RND_MASK (is_32bit_task() ? 0x07ffUL : 0x3ffffUL)
354-
#define MMAP_RND_MASK (is_32bit_task() ? 0x1fffUL : 0x3ffffUL)
355-
#define STACK_RND_MASK MMAP_RND_MASK
356-
357-
struct mm_struct;
358-
extern unsigned long arch_randomize_brk(struct mm_struct *);
359-
#define arch_randomize_brk arch_randomize_brk
360-
352+
#define STACK_RND_MASK 0x7ff /* 8MB of VA */
361353

362354
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
363355
struct linux_binprm;

arch/parisc/include/asm/processor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747

4848
#ifndef __ASSEMBLY__
4949

50+
struct rlimit;
51+
unsigned long mmap_upper_limit(struct rlimit *rlim_stack);
5052
unsigned long calc_max_stack_size(unsigned long stack_max);
5153

5254
/*

arch/parisc/kernel/sys_parisc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ unsigned long calc_max_stack_size(unsigned long stack_max)
7777
* indicating that "current" should be used instead of a passed-in
7878
* value from the exec bprm as done with arch_pick_mmap_layout().
7979
*/
80-
static unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
80+
unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
8181
{
8282
unsigned long stack_base;
8383

mm/util.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack)
414414

415415
static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
416416
{
417+
#ifdef CONFIG_STACK_GROWSUP
418+
/*
419+
* For an upwards growing stack the calculation is much simpler.
420+
* Memory for the maximum stack size is reserved at the top of the
421+
* task. mmap_base starts directly below the stack and grows
422+
* downwards.
423+
*/
424+
return PAGE_ALIGN_DOWN(mmap_upper_limit(rlim_stack) - rnd);
425+
#else
417426
unsigned long gap = rlim_stack->rlim_cur;
418427
unsigned long pad = stack_guard_gap;
419428

@@ -431,6 +440,7 @@ static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)
431440
gap = MAX_GAP;
432441

433442
return PAGE_ALIGN(STACK_TOP - gap - rnd);
443+
#endif
434444
}
435445

436446
void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)

0 commit comments

Comments
 (0)