kbind(2): disable system call if not initialized before first __tfork(2)
authorcheloha <cheloha@openbsd.org>
Sun, 5 Dec 2021 22:00:42 +0000 (22:00 +0000)
committercheloha <cheloha@openbsd.org>
Sun, 5 Dec 2021 22:00:42 +0000 (22:00 +0000)
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
sys/sys/proc.h
sys/uvm/uvm_mmap.c

index 1e51f71..89bd3a7 100644 (file)
@@ -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);
 }
index c418ba9..4aa36a4 100644 (file)
@@ -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
index 4b969cb..e499a57 100644 (file)
@@ -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)
 {