aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2026-06-15 13:32:47 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2026-06-21 11:46:53 +0000
commit6a572920f251ac8ac6a80a55d4d039736ea7dd65 (patch)
tree72b6f50a197ae34299b9a38d687d6e39b89dc71d
parent836749817036b90b60af0584fa21f2d9dbd60ff7 (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.c21
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