1 /* 2 * Finalizes the stack vm_area_struct. The flags and permissions are updated, 3 * the stack is optionally relocated, and some extra space is added. 4 */ 5 6 /** The macro below is for platform riscv. 7 executable_stack is the X flag of bprm. 8 stack_top is a value get by STACK_TOP minusing a 9 random ul if random vm is on. 10 STACK_TOP is 0x400 0000 0000. 11 **/ 12 /** bprm_mm_init set up the mm_struct of bprm 13 vma->vm_end = 0x400 0000 0000 14 vm_start = vm_end - 0x1000 15 bprm->p = vm_end - sizeof(void *) 16 **/ 17 int setup_arg_pages(struct linux_binprm *bprm, 18 unsigned long stack_top, 19 int executable_stack) 20 { 21 unsigned long ret; 22 unsigned long stack_shift; 23 struct mm_struct *mm = current->mm; 24 struct vm_area_struct *vma = bprm->vma; 25 struct vm_area_struct *prev = NULL; 26 unsigned long vm_flags; 27 unsigned long stack_base; 28 unsigned long stack_size; 29 unsigned long stack_expand; 30 unsigned long rlim_stack; 31 32 #ifdef CONFIG_STACK_GROWSUP 33 /* Limit stack size */ 34 stack_base = rlimit_max(RLIMIT_STACK); 35 //* STACK_SIZE_MAX is 0x80 0000 for 8KB 36 if (stack_base > STACK_SIZE_MAX) 37 stack_base = STACK_SIZE_MAX; 38 39 /* Add space for stack randomization. */ 40 //* For riscv, STACK_RND_MASK is 0x7ff. 41 //* This operation makes stack_base be 0xff f000. 42 stack_base += (STACK_RND_MASK << PAGE_SHIFT); 43 44 /* Make sure we didn't let the argument array grow too large. */ 45 if (vma->vm_end - vma->vm_start > stack_base) 46 return -ENOMEM; 47 48 stack_base = PAGE_ALIGN(stack_top - stack_base); 49 //* stack_shift = 0x3ff ff000 0000 50 stack_shift = vma->vm_start - stack_base; 51 //* arg_start = 0x100 0000 - sizeof(void*) 52 mm->arg_start = bprm->p - stack_shift; 53 //* p = 0x100 0000 54 bprm->p = vma->vm_end - stack_shift; 55 #else 56 stack_top = arch_align_stack(stack_top); 57 stack_top = PAGE_ALIGN(stack_top); 58 59 if (unlikely(stack_top < mmap_min_addr) || 60 unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr)) 61 return -ENOMEM; 62 //* stack_shift = 0 63 stack_shift = vma->vm_end - stack_top; 64 //* p = vm_end - sizeof(void*) 65 bprm->p -= stack_shift; 66 //* arg_start = vm_end - sizeof(void*) 67 mm->arg_start = bprm->p; 68 #endif 69 70 if (bprm->loader) 71 bprm->loader -= stack_shift; 72 bprm->exec -= stack_shift; 73 74 down_write(&mm->mmap_sem); 75 vm_flags = VM_STACK_FLAGS; 76 77 /* 78 * Adjust stack execute permissions; explicitly enable for 79 * EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone 80 * (arch default) otherwise. 81 */ 82 if (unlikely(executable_stack == EXSTACK_ENABLE_X)) 83 vm_flags |= VM_EXEC; 84 else if (executable_stack == EXSTACK_DISABLE_X) 85 vm_flags &= ~VM_EXEC; 86 vm_flags |= mm->def_flags; 87 vm_flags |= VM_STACK_INCOMPLETE_SETUP; 88 89 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end, 90 vm_flags); 91 if (ret) 92 goto out_unlock; 93 BUG_ON(prev != vma); 94 95 /* Move stack pages down in memory. */ 96 if (stack_shift) { 97 ret = shift_arg_pages(vma, stack_shift); 98 if (ret) 99 goto out_unlock; 100 } 101 102 /* mprotect_fixup is overkill to remove the temporary stack flags */ 103 vma->vm_flags &= ~VM_STACK_INCOMPLETE_SETUP; 104 105 stack_expand = 131072UL; /* randomly 32*4k (or 2*64k) pages */ 106 //* one page: 0x1000 107 stack_size = vma->vm_end - vma->vm_start; 108 /* 109 * Align this down to a page boundary as expand_stack 110 * will align it up. 111 */ 112 rlim_stack = rlimit(RLIMIT_STACK) & PAGE_MASK; 113 #ifdef CONFIG_STACK_GROWSUP 114 if (stack_size + stack_expand > rlim_stack) 115 stack_base = vma->vm_start + rlim_stack; 116 else 117 stack_base = vma->vm_end + stack_expand; 118 #else 119 if (stack_size + stack_expand > rlim_stack) 120 stack_base = vma->vm_end - rlim_stack; 121 else 122 stack_base = vma->vm_start - stack_expand; 123 #endif 124 current->mm->start_stack = bprm->p; 125 ret = expand_stack(vma, stack_base); 126 if (ret) 127 ret = -EFAULT; 128 129 out_unlock: 130 up_write(&mm->mmap_sem); 131 return ret; 132 } 133 EXPORT_SYMBOL(setup_arg_pages);