summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2023-02-16 04:42:09 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2023-02-16 04:42:09 +0000
commitb7c6aad45ee0aa3b9854ba91916340bcfc5ea142 (patch)
tree1890b2c7febcfc9fae5a5c3945ab1e058ab3fc89 /sys/uvm
parent627535f1d71887996ee3bdd5ef1e3b6076a8bcdd (diff)
Add pinsyscall(2). With this you can tell the kernel the location
(start,len) of the syscall stub in libc.so for a specified syscall (using SYS_* notation). Only SYS_execve is supported at this time. ok gnezdo mortimer kettenis
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_extern.h4
-rw-r--r--sys/uvm/uvm_mmap.c35
2 files changed, 37 insertions, 2 deletions
diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h
index 6f4ddc5327a..994957f7c9e 100644
--- a/sys/uvm/uvm_extern.h
+++ b/sys/uvm/uvm_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_extern.h,v 1.166 2022/11/17 18:53:05 deraadt Exp $ */
+/* $OpenBSD: uvm_extern.h,v 1.167 2023/02/16 04:42:07 deraadt Exp $ */
/* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */
/*
@@ -214,6 +214,8 @@ struct vmspace {
caddr_t vm_daddr; /* [I] user virtual address of data */
caddr_t vm_maxsaddr; /* [I] user VA at max stack growth */
caddr_t vm_minsaddr; /* [I] user VA at top of stack */
+ vaddr_t vm_execve; /* [v] execve systemcall stub region */
+ vaddr_t vm_execve_end; /* [v] execve systemcall stub region */
};
/*
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c
index e3dcd41089e..db0adcfdcc4 100644
--- a/sys/uvm/uvm_mmap.c
+++ b/sys/uvm/uvm_mmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_mmap.c,v 1.178 2023/02/11 23:22:19 deraadt Exp $ */
+/* $OpenBSD: uvm_mmap.c,v 1.179 2023/02/16 04:42:08 deraadt Exp $ */
/* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -68,6 +68,7 @@
#include <machine/exec.h> /* for __LDPGSZ */
+#include <sys/syscall.h>
#include <sys/syscallargs.h>
#include <uvm/uvm.h>
@@ -616,6 +617,38 @@ sys_msyscall(struct proc *p, void *v, register_t *retval)
}
/*
+ * sys_pinsyscall
+ */
+int
+sys_pinsyscall(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_pinsyscall_args /* {
+ syscallarg(int) syscall;
+ syscallarg(void *) addr;
+ syscallarg(size_t) len;
+ } */ *uap = v;
+ struct vmspace *vm = p->p_vmspace;
+ vm_map_t map = &p->p_vmspace->vm_map;
+ vaddr_t start, end;
+
+ if (SCARG(uap, syscall) != SYS_execve)
+ return (EINVAL);
+ start = (vaddr_t)SCARG(uap, addr);
+ end = start + (vsize_t)SCARG(uap, len);
+ if (start >= end || start < map->min_offset || end > map->max_offset)
+ return (EFAULT);
+ vm_map_lock(map);
+ if (vm->vm_execve) {
+ vm_map_unlock(map);
+ return (EPERM);
+ }
+ vm->vm_execve = start;
+ vm->vm_execve_end = end;
+ vm_map_unlock(map);
+ return (0);
+}
+
+/*
* sys_mimmutable: the mimmutable system call
*/
int