exec_new_vmspace: print useful error message on ctty if stack cannot be mapped.

After old vmspace is destroyed during execve(2), but before the new space
is fully constructed, an error during image activation cannot be returned
because there is no executing program to receive it.

In the relatively common case of failure to map stack, print some hints
on the control terminal.  Note that user has enough knobs to cause stack
mapping error, and this is the most common reason for execve(2) aborting
the process.

Requested by:	jhb
Reviewed by:	emaste, jhb
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D28050
This commit is contained in:
Konstantin Belousov 2021-01-11 20:51:07 +02:00
parent 2e1c94aa1f
commit 4ea65707d3

View File

@ -1043,6 +1043,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
struct rlimit rlim_stack;
vm_offset_t sv_minuser, stack_addr;
vm_map_t map;
vm_prot_t stack_prot;
u_long ssiz;
imgp->vmspace_destroyed = 1;
@ -1126,11 +1127,16 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
if (ssiz < imgp->eff_stack_sz)
imgp->eff_stack_sz = ssiz;
stack_addr = sv->sv_usrstack - ssiz;
error = vm_map_stack(map, stack_addr, (vm_size_t)ssiz,
obj != NULL && imgp->stack_prot != 0 ? imgp->stack_prot :
sv->sv_stackprot, VM_PROT_ALL, MAP_STACK_GROWS_DOWN);
if (error != KERN_SUCCESS)
stack_prot = obj != NULL && imgp->stack_prot != 0 ?
imgp->stack_prot : sv->sv_stackprot;
error = vm_map_stack(map, stack_addr, (vm_size_t)ssiz, stack_prot,
VM_PROT_ALL, MAP_STACK_GROWS_DOWN);
if (error != KERN_SUCCESS) {
uprintf("exec_new_vmspace: mapping stack size %#jx prot %#x "
"failed mach error %d errno %d\n", (uintmax_t)ssiz,
stack_prot, error, vm_mmap_to_errno(error));
return (vm_mmap_to_errno(error));
}
/*
* vm_ssize and vm_maxsaddr are somewhat antiquated concepts, but they