* Attempts to grow a vm stack entry. Returns KERN_SUCCESS if we * successfully grow the stack. */
| 4621 | * successfully grow the stack. |
| 4622 | */ |
| 4623 | static int |
| 4624 | vm_map_growstack(vm_map_t map, vm_offset_t addr, vm_map_entry_t gap_entry) |
| 4625 | { |
| 4626 | vm_map_entry_t stack_entry; |
| 4627 | struct proc *p; |
| 4628 | struct vmspace *vm; |
| 4629 | struct ucred *cred; |
| 4630 | vm_offset_t gap_end, gap_start, grow_start; |
| 4631 | vm_size_t grow_amount, guard, max_grow; |
| 4632 | rlim_t lmemlim, stacklim, vmemlim; |
| 4633 | int rv, rv1; |
| 4634 | bool gap_deleted, grow_down, is_procstack; |
| 4635 | #ifdef notyet |
| 4636 | uint64_t limit; |
| 4637 | #endif |
| 4638 | #ifdef RACCT |
| 4639 | int error; |
| 4640 | #endif |
| 4641 | |
| 4642 | p = curproc; |
| 4643 | vm = p->p_vmspace; |
| 4644 | |
| 4645 | /* |
| 4646 | * Disallow stack growth when the access is performed by a |
| 4647 | * debugger or AIO daemon. The reason is that the wrong |
| 4648 | * resource limits are applied. |
| 4649 | */ |
| 4650 | if (p != initproc && (map != &p->p_vmspace->vm_map || |
| 4651 | p->p_textvp == NULL)) |
| 4652 | return (KERN_FAILURE); |
| 4653 | |
| 4654 | MPASS(!map->system_map); |
| 4655 | |
| 4656 | lmemlim = lim_cur(curthread, RLIMIT_MEMLOCK); |
| 4657 | stacklim = lim_cur(curthread, RLIMIT_STACK); |
| 4658 | vmemlim = lim_cur(curthread, RLIMIT_VMEM); |
| 4659 | retry: |
| 4660 | /* If addr is not in a hole for a stack grow area, no need to grow. */ |
| 4661 | if (gap_entry == NULL && !vm_map_lookup_entry(map, addr, &gap_entry)) |
| 4662 | return (KERN_FAILURE); |
| 4663 | if ((gap_entry->eflags & MAP_ENTRY_GUARD) == 0) |
| 4664 | return (KERN_SUCCESS); |
| 4665 | if ((gap_entry->eflags & MAP_ENTRY_STACK_GAP_DN) != 0) { |
| 4666 | stack_entry = vm_map_entry_succ(gap_entry); |
| 4667 | if ((stack_entry->eflags & MAP_ENTRY_GROWS_DOWN) == 0 || |
| 4668 | stack_entry->start != gap_entry->end) |
| 4669 | return (KERN_FAILURE); |
| 4670 | grow_amount = round_page(stack_entry->start - addr); |
| 4671 | grow_down = true; |
| 4672 | } else if ((gap_entry->eflags & MAP_ENTRY_STACK_GAP_UP) != 0) { |
| 4673 | stack_entry = vm_map_entry_pred(gap_entry); |
| 4674 | if ((stack_entry->eflags & MAP_ENTRY_GROWS_UP) == 0 || |
| 4675 | stack_entry->end != gap_entry->start) |
| 4676 | return (KERN_FAILURE); |
| 4677 | grow_amount = round_page(addr + 1 - stack_entry->end); |
| 4678 | grow_down = false; |
| 4679 | } else { |
| 4680 | return (KERN_FAILURE); |
no test coverage detected