From b18b10d81ae65dbcfbcf0bcc2ccedc8e21a5910e Mon Sep 17 00:00:00 2001 From: guenther Date: Mon, 16 Jan 2023 07:09:11 +0000 Subject: [PATCH] Currently we disable kbind(2) for static program from libc.a's 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 | 8 ++------ sys/kern/exec_elf.c | 6 +++++- sys/sys/proc.h | 4 +++- sys/uvm/uvm_mmap.c | 9 +++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/libc/dlfcn/init.c b/lib/libc/dlfcn/init.c index 98766b80039..48c062cef55 100644 --- a/lib/libc/dlfcn/init.c +++ b/lib/libc/dlfcn/init.c @@ -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 * @@ -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 */ diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c index 779b729b240..6b4f45ce407 100644 --- a/sys/kern/exec_elf.c +++ b/sys/kern/exec_elf.c @@ -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); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 15844fa4d34..d014a558415 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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 diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index ef1ebce59ec..1ebed4cb1b6 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -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; -- 2.20.1