From f745c206bcc02cfea056b2c3827a906a098ab257 Mon Sep 17 00:00:00 2001 From: cheloha Date: Sun, 5 Dec 2021 22:00:42 +0000 Subject: [PATCH] kbind(2): disable system call if not initialized before first __tfork(2) To unlock kbind(2) we need to protect ps_kbind_addr and ps_kbind_cookie. The simplest way to do this is to disallow kbind(2) initialization after the first __tfork(2) call. If the first thread does not initialize the kbind(2) variables before __tfork(2) then we disable kbind(2) during that first __tfork(2) call. This is guenther@'s patch, I'm just committing it. Discussed with guenther@, deraadt@, kettenis@, and mpi@. ok kettenis@, positive response from mpi@, "I am busy" guenther@ --- sys/kern/kern_fork.c | 9 ++++++++- sys/sys/proc.h | 8 +++++--- sys/uvm/uvm_mmap.c | 4 +--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 1e51f71301a..89bd3a7e5a1 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.236 2021/06/19 02:05:33 cheloha Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.237 2021/12/05 22:00:42 cheloha Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -137,6 +137,13 @@ sys___tfork(struct proc *p, void *v, register_t *retval) return EINVAL; #endif /* TCB_INVALID */ + /* + * kbind(2) can only be used if it is initialized before the + * process goes multithreaded. + */ + if (p->p_p->ps_kbind_addr == 0) + p->p_p->ps_kbind_addr = BOGO_PC; + return thread_fork(p, param.tf_stack, param.tf_tcb, param.tf_tid, retval); } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c418ba9414e..4aa36a48696 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.316 2021/11/26 04:42:13 visa Exp $ */ +/* $OpenBSD: proc.h,v 1.317 2021/12/05 22:00:42 cheloha Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -265,8 +265,10 @@ struct process { uint64_t ps_pledge; uint64_t ps_execpledge; - int64_t ps_kbind_cookie; - u_long ps_kbind_addr; + int64_t ps_kbind_cookie; /* [K] */ + u_long ps_kbind_addr; /* [K] */ +/* an address that can't be in userspace or kernelspace */ +#define BOGO_PC (u_long)-1 /* End area that is copied on creation. */ #define ps_endcopy ps_refcnt diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 4b969cb0fc6..e499a573a9a 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_mmap.c,v 1.164 2021/03/26 13:40:05 mpi Exp $ */ +/* $OpenBSD: uvm_mmap.c,v 1.165 2021/12/05 22:00:42 cheloha Exp $ */ /* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */ /* @@ -1073,8 +1073,6 @@ uvm_mmapfile(vm_map_t map, vaddr_t *addr, vsize_t size, vm_prot_t prot, return error; } -/* an address that can't be in userspace or kernelspace */ -#define BOGO_PC (u_long)-1 int sys_kbind(struct proc *p, void *v, register_t *retval) { -- 2.20.1