diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2024-01-16 19:05:02 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2024-01-16 19:05:02 +0000 |
commit | 299830858df6b28127f1fa05a7edec8a98165ca5 (patch) | |
tree | 015985d7f1b1f2b490784c65d555344a00717c52 /sys/kern/kern_exec.c | |
parent | e31f6e362537ab2a45e56c0ad841b328af94e810 (diff) |
The kernel will now read pinsyscall tables out of PT_OPENBSD_SYSCALLS in
the main program or ld.so, and accept a submission of that information
for libc.so from ld.so via pinsyscalls(2). At system call invocation,
the syscall number is matched to the specific address it must come from.
ok kettenis, gnezdo, testing of variations by many people
Diffstat (limited to 'sys/kern/kern_exec.c')
-rw-r--r-- | sys/kern/kern_exec.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 9d8ec981347..47048040c22 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.252 2023/10/30 07:13:10 claudio Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.253 2024/01/16 19:05:01 deraadt Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -314,6 +314,8 @@ sys_execve(struct proc *p, void *v, register_t *retval) VMCMDSET_INIT(&pack.ep_vmcmds); pack.ep_vap = &attr; pack.ep_flags = 0; + pack.ep_pins = NULL; + pack.ep_npins = 0; /* see if we can run it. */ if ((error = check_exec(p, &pack)) != 0) { @@ -514,6 +516,30 @@ sys_execve(struct proc *p, void *v, register_t *retval) if (copyout(&arginfo, (char *)pr->ps_strings, sizeof(arginfo))) goto exec_abort; + free(pr->ps_pin.pn_pins, M_PINSYSCALL, + pr->ps_pin.pn_npins * sizeof(u_int)); + if (pack.ep_npins) { + pr->ps_pin.pn_start = pack.ep_pinstart; + pr->ps_pin.pn_end = pack.ep_pinend; + pr->ps_pin.pn_pins = pack.ep_pins; + pack.ep_pins = NULL; + pr->ps_pin.pn_npins = pack.ep_npins; + pr->ps_flags |= PS_PIN; + } else { + pr->ps_pin.pn_start = pr->ps_pin.pn_end = 0; + pr->ps_pin.pn_pins = NULL; + pr->ps_pin.pn_npins = 0; + pr->ps_flags &= ~PS_PIN; + } + if (pr->ps_libcpin.pn_pins) { + free(pr->ps_libcpin.pn_pins, M_PINSYSCALL, + pr->ps_libcpin.pn_npins * sizeof(u_int)); + pr->ps_libcpin.pn_start = pr->ps_libcpin.pn_end = 0; + pr->ps_libcpin.pn_pins = NULL; + pr->ps_libcpin.pn_npins = 0; + pr->ps_flags &= ~PS_LIBCPIN; + } + stopprofclock(pr); /* stop profiling */ fdcloseexec(p); /* handle close on exec */ execsigs(p); /* reset caught signals */ @@ -752,6 +778,7 @@ bad: if (pack.ep_interp != NULL) pool_put(&namei_pool, pack.ep_interp); free(pack.ep_args, M_TEMP, sizeof *pack.ep_args); + free(pack.ep_pins, M_PINSYSCALL, pack.ep_npins * sizeof(u_int)); /* close and put the exec'd file */ vn_close(pack.ep_vp, FREAD, cred, p); pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf); |