Currently we disable kbind(2) for static program from libc.a's
authorguenther <guenther@openbsd.org>
Mon, 16 Jan 2023 07:09:11 +0000 (07:09 +0000)
committerguenther <guenther@openbsd.org>
Mon, 16 Jan 2023 07:09:11 +0000 (07:09 +0000)
preinit hook.  Delete that and instead have the kernel disable kbind
at exec-time if the program doesn't have an ELF interpreter.  For
now, permit userland calls to disable it when already disabled so
existing static programs continue to work.

prompted by deraadt@ questioning about the call in libc.a

ok deraadt@ miod@

lib/libc/dlfcn/init.c
sys/kern/exec_elf.c
sys/sys/proc.h
sys/uvm/uvm_mmap.c

index 98766b8..48c062c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init.c,v 1.11 2022/12/27 17:10:06 jmc Exp $ */
+/*     $OpenBSD: init.c,v 1.12 2023/01/16 07:09:12 guenther Exp $ */
 /*
  * Copyright (c) 2014,2015 Philip Guenther <guenther@openbsd.org>
  *
@@ -205,17 +205,13 @@ _csu_finish(char **argv, char **envp, void (*cleanup)(void))
 
 #ifndef PIC
 /*
- * static libc in a static link?  Then disable kbind and set up
- * __progname and environ
+ * static libc in a static link?  Then set up __progname and environ
  */
 static inline void
 early_static_init(char **argv, char **envp)
 {
        static char progname_storage[NAME_MAX+1];
 
-       /* disable kbind */
-       syscall(SYS_kbind, (void *)NULL, (size_t)0, (long long)0);
-
        environ = envp;
 
        /* set up __progname */
index 779b729..6b4f45c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exec_elf.c,v 1.179 2023/01/13 23:02:43 kettenis Exp $ */
+/*     $OpenBSD: exec_elf.c,v 1.180 2023/01/16 07:09:11 guenther Exp $ */
 
 /*
  * Copyright (c) 1996 Per Fogelstrom
@@ -807,6 +807,10 @@ exec_elf_fixup(struct proc *p, struct exec_package *epp)
 
        interp = epp->ep_interp;
 
+       /* disable kbind in programs that don't use ld.so */
+       if (interp == NULL)
+               p->p_p->ps_kbind_addr = BOGO_PC;
+
        if (interp &&
            (error = elf_load_file(p, interp, epp, ap)) != 0) {
                uprintf("execve: cannot load %s\n", interp);
index 15844fa..d014a55 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.338 2023/01/07 05:24:58 guenther Exp $     */
+/*     $OpenBSD: proc.h,v 1.339 2023/01/16 07:09:11 guenther Exp $     */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -237,6 +237,8 @@ struct process {
 
        int64_t ps_kbind_cookie;        /* [m] */
        u_long  ps_kbind_addr;          /* [m] */
+/* 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 ef1ebce..1ebed4c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_mmap.c,v 1.176 2023/01/04 06:33:33 jsg Exp $      */
+/*     $OpenBSD: uvm_mmap.c,v 1.177 2023/01/16 07:09:11 guenther Exp $ */
 /*     $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $        */
 
 /*
@@ -1130,8 +1130,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)
 {
@@ -1171,9 +1169,12 @@ sys_kbind(struct proc *p, void *v, register_t *retval)
        pc = PROC_PC(p);
        mtx_enter(&pr->ps_mtx);
        if (paramp == NULL) {
+               /* ld.so disables kbind() when lazy binding is disabled */
                if (pr->ps_kbind_addr == 0)
                        pr->ps_kbind_addr = BOGO_PC;
-               else
+               /* pre-7.3 static binaries disable kbind */
+               /* XXX delete check in 2026 */
+               else if (pr->ps_kbind_addr != BOGO_PC)
                        sigill = 1;
        } else if (pr->ps_kbind_addr == 0) {
                pr->ps_kbind_addr = pc;