Skip to content

Commit 296927d

Browse files
torvaldsgregkh
authored andcommitted
execve: always mark stack as growing down during early stack setup
commit f66066b upstream. While our user stacks can grow either down (all common architectures) or up (parisc and the ia64 register stack), the initial stack setup when we copy the argument and environment strings to the new stack at execve() time is always done by extending the stack downwards. But it turns out that in commit 8d7071a ("mm: always expand the stack with the mmap write lock held"), as part of making the stack growing code more robust, 'expand_downwards()' was now made to actually check the vma flags: if (!(vma->vm_flags & VM_GROWSDOWN)) return -EFAULT; and that meant that this execve-time stack expansion started failing on parisc, because on that architecture, the stack flags do not contain the VM_GROWSDOWN bit. At the same time the new check in expand_downwards() is clearly correct, and simplified the callers, so let's not remove it. The solution is instead to just codify the fact that yes, during execve(), the stack grows down. This not only matches reality, it ends up being particularly simple: we already have special execve-time flags for the stack (VM_STACK_INCOMPLETE_SETUP) and use those flags to avoid page migration during this setup time (see vma_is_temporary_stack() and invalid_migration_vma()). So just add VM_GROWSDOWN to that set of temporary flags, and now our stack flags automatically match reality, and the parisc stack expansion works again. Note that the VM_STACK_INCOMPLETE_SETUP bits will be cleared when the stack is finalized, so we only add the extra VM_GROWSDOWN bit on CONFIG_STACK_GROWSUP architectures (ie parisc) rather than adding it in general. Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/all/[email protected]/ Fixes: 8d7071a ("mm: always expand the stack with the mmap write lock held") Reported-by: John David Anglin <[email protected]> Reported-and-tested-by: Helge Deller <[email protected]> Reported-and-tested-by: Guenter Roeck <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d856e6f commit 296927d

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

include/linux/mm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ extern unsigned int kobjsize(const void *objp);
378378
#endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
379379

380380
/* Bits set in the VMA until the stack is in its final location */
381-
#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ)
381+
#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY)
382382

383383
#define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0)
384384

@@ -400,8 +400,10 @@ extern unsigned int kobjsize(const void *objp);
400400

401401
#ifdef CONFIG_STACK_GROWSUP
402402
#define VM_STACK VM_GROWSUP
403+
#define VM_STACK_EARLY VM_GROWSDOWN
403404
#else
404405
#define VM_STACK VM_GROWSDOWN
406+
#define VM_STACK_EARLY 0
405407
#endif
406408

407409
#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)

0 commit comments

Comments
 (0)