diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2026-06-15 13:32:47 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-06-21 11:46:53 +0000 |
| commit | 6a572920f251ac8ac6a80a55d4d039736ea7dd65 (patch) | |
| tree | 72b6f50a197ae34299b9a38d687d6e39b89dc71d | |
| parent | 836749817036b90b60af0584fa21f2d9dbd60ff7 (diff) | |
kern_procctl(PROC_WX_MAPPINGS_PERMIT): ensure stability of the target vmspace
Reviewed by: markj
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D57497
| -rw-r--r-- | sys/kern/kern_procctl.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c index c8d14aa2f2f6..581b24f21d3c 100644 --- a/sys/kern/kern_procctl.c +++ b/sys/kern/kern_procctl.c @@ -40,6 +40,7 @@ #include <sys/priv.h> #include <sys/proc.h> #include <sys/procctl.h> +#include <sys/ptrace.h> #include <sys/sx.h> #include <sys/syscallsubr.h> #include <sys/sysproto.h> @@ -877,22 +878,27 @@ wxmap_ctl(struct thread *td, struct proc *p, void *data) { struct vmspace *vm; vm_map_t map; - int state; + int error, state; PROC_LOCK_ASSERT(p, MA_OWNED); state = *(int *)data; + error = 0; switch (state) { case PROC_WX_MAPPINGS_PERMIT: - p->p_flag2 |= P2_WXORX_DISABLE; PROC_UNLOCK(p); - vm = vmspace_acquire_ref(p); - if (vm != NULL) { + error = proc_vmspace_ref(td, p, PRVM_BLOCK_EXEC | + PRVM_CHECK_DEBUG, &vm); + if (error == 0) { map = &vm->vm_map; vm_map_lock(map); map->flags &= ~MAP_WXORX; vm_map_unlock(map); - vmspace_free(vm); + PROC_LOCK(p); + p->p_flag2 |= P2_WXORX_DISABLE; + PROC_UNLOCK(p); + proc_vmspace_unref(td, p, PRVM_BLOCK_EXEC | + PRVM_CHECK_DEBUG, vm); } PROC_LOCK(p); break; @@ -900,10 +906,11 @@ wxmap_ctl(struct thread *td, struct proc *p, void *data) p->p_flag2 |= P2_WXORX_ENABLE_EXEC; break; default: - return (EINVAL); + error = EINVAL; + break; } - return (0); + return (error); } static int |
