Delete the msyscall mechanism entirely, since mimmutable+pinsyscalls has
authorderaadt <deraadt@openbsd.org>
Tue, 2 Apr 2024 08:39:16 +0000 (08:39 +0000)
committerderaadt <deraadt@openbsd.org>
Tue, 2 Apr 2024 08:39:16 +0000 (08:39 +0000)
replaced it with a more strict mechanism, which happens to be lockless O(1)
rather than micro-lock O(1)+O(log N).  Also nop-out the sys_msyscall(2) guts,
but leave the syscall around for a bit longer so that people can build through
it, since ld.so(1) still wants to call it.

sys/kern/exec_elf.c
sys/kern/exec_subr.c
sys/kern/init_main.c
sys/kern/kern_exec.c
sys/sys/exec.h
sys/sys/proc.h
sys/uvm/uvm.h
sys/uvm/uvm_extern.h
sys/uvm/uvm_map.c
sys/uvm/uvm_map.h
sys/uvm/uvm_mmap.c

index 33e5cad..0cb3b15 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exec_elf.c,v 1.185 2024/01/17 22:22:25 kurt Exp $     */
+/*     $OpenBSD: exec_elf.c,v 1.186 2024/04/02 08:39:16 deraadt Exp $  */
 
 /*
  * Copyright (c) 1996 Per Fogelstrom
@@ -494,10 +494,15 @@ elf_load_file(struct proc *p, char *path, struct exec_package *epp,
                                addr = ph[i].p_vaddr - base_ph->p_vaddr;
                        }
                        elf_load_psection(&epp->ep_vmcmds, nd.ni_vp,
-                           &ph[i], &addr, &size, &prot, flags | VMCMD_SYSCALL);
+                           &ph[i], &addr, &size, &prot, flags);
                        /* If entry is within this section it must be text */
                        if (eh.e_entry >= ph[i].p_vaddr &&
                            eh.e_entry < (ph[i].p_vaddr + size)) {
+                               /* LOAD containing e_entry may not be writable */
+                               if (prot & PROT_WRITE) {
+                                       error = ENOEXEC;
+                                       goto bad1;
+                               }
                                epp->ep_entry = addr + eh.e_entry -
                                    ELF_TRUNC(ph[i].p_vaddr,ph[i].p_align);
                                if (flags == VMCMD_RELATIVE)
@@ -715,7 +720,7 @@ exec_elf_makecmds(struct proc *p, struct exec_package *epp)
         */
        for (i = 0, pp = ph; i < eh->e_phnum; i++, pp++) {
                Elf_Addr addr, size = 0;
-               int prot = 0, syscall = 0;
+               int prot = 0;
                int flags = 0;
 
                switch (pp->p_type) {
@@ -731,16 +736,9 @@ exec_elf_makecmds(struct proc *p, struct exec_package *epp)
                        } else
                                addr = ELF_NO_ADDR;
 
-                       /*
-                        * Permit system calls in main-text static binaries.
-                        * static binaries may not call msyscall() or
-                        * pinsyscalls()
-                        */
-                       if (interp == NULL) {
-                               syscall = VMCMD_SYSCALL;
-                               p->p_vmspace->vm_map.flags |= VM_MAP_SYSCALL_ONCE;
+                       /* Static binaries may not call pinsyscalls() */
+                       if (interp == NULL)
                                p->p_vmspace->vm_map.flags |= VM_MAP_PINSYSCALL_ONCE;
-                       }
 
                        /*
                         * Calculates size of text and data segments
@@ -750,7 +748,7 @@ exec_elf_makecmds(struct proc *p, struct exec_package *epp)
                         * for DATA_PLT, is fine for TEXT_PLT.
                         */
                        elf_load_psection(&epp->ep_vmcmds, epp->ep_vp,
-                           pp, &addr, &size, &prot, flags | textrel | syscall);
+                           pp, &addr, &size, &prot, flags | textrel);
 
                        /*
                         * Update exe_base in case alignment was off.
index a02566b..4ebca1b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exec_subr.c,v 1.66 2023/03/19 20:32:13 kettenis Exp $ */
+/*     $OpenBSD: exec_subr.c,v 1.67 2024/04/02 08:39:16 deraadt Exp $  */
 /*     $NetBSD: exec_subr.c,v 1.9 1994/12/04 03:10:42 mycroft Exp $    */
 
 /*
@@ -194,9 +194,6 @@ vmcmd_map_pagedvn(struct proc *p, struct exec_vmcmd *cmd)
        /*
         * do the map
         */
-       if ((cmd->ev_flags & VMCMD_SYSCALL) && (cmd->ev_prot & PROT_EXEC))
-               flags |= UVM_FLAG_SYSCALL;
-
        error = uvm_map(&p->p_vmspace->vm_map, &cmd->ev_addr, cmd->ev_len,
            uobj, cmd->ev_offset, 0,
            UVM_MAPFLAG(cmd->ev_prot, PROT_MASK, MAP_INHERIT_COPY,
@@ -217,8 +214,7 @@ vmcmd_map_pagedvn(struct proc *p, struct exec_vmcmd *cmd)
                            round_page(cmd->ev_addr + cmd->ev_len), 1);
 #ifdef PMAP_CHECK_COPYIN
                if (PMAP_CHECK_COPYIN &&
-                   ((flags & UVM_FLAG_SYSCALL) ||
-                   ((cmd->ev_flags & VMCMD_IMMUTABLE) && (cmd->ev_prot & PROT_EXEC))))
+                   ((cmd->ev_flags & VMCMD_IMMUTABLE) && (cmd->ev_prot & PROT_EXEC)))
                        uvm_map_check_copyin_add(&p->p_vmspace->vm_map,
                            cmd->ev_addr, round_page(cmd->ev_addr + cmd->ev_len));
 #endif
index b4816b2..d571b08 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init_main.c,v 1.325 2024/02/14 06:17:51 miod Exp $    */
+/*     $OpenBSD: init_main.c,v 1.326 2024/04/02 08:39:16 deraadt Exp $ */
 /*     $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $   */
 
 /*
@@ -626,7 +626,7 @@ start_init(void *arg)
            NULL, UVM_UNKNOWN_OFFSET, 0,
            UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_MASK, MAP_INHERIT_COPY,
            MADV_NORMAL,
-           UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW|UVM_FLAG_STACK|UVM_FLAG_SYSCALL)))
+           UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW|UVM_FLAG_STACK)))
                panic("init: couldn't allocate argument space");
 
        for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) {
index a00e237..7d87a4c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exec.c,v 1.254 2024/01/17 18:56:13 deraadt Exp $ */
+/*     $OpenBSD: kern_exec.c,v 1.255 2024/04/02 08:39:16 deraadt Exp $ */
 /*     $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $  */
 
 /*-
@@ -905,7 +905,7 @@ exec_sigcode_map(struct process *pr)
        if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_sigcode, round_page(sz),
            sigobject, 0, 0, UVM_MAPFLAG(PROT_EXEC,
            PROT_READ | PROT_WRITE | PROT_EXEC, MAP_INHERIT_COPY,
-           MADV_RANDOM, UVM_FLAG_COPYONW | UVM_FLAG_SYSCALL))) {
+           MADV_RANDOM, UVM_FLAG_COPYONW))) {
                uao_detach(sigobject);
                return (ENOMEM);
        }
index d6b5c64..801181f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exec.h,v 1.53 2024/01/16 19:05:00 deraadt Exp $       */
+/*     $OpenBSD: exec.h,v 1.54 2024/04/02 08:39:16 deraadt Exp $       */
 /*     $NetBSD: exec.h,v 1.59 1996/02/09 18:25:09 christos Exp $       */
 
 /*-
@@ -92,7 +92,6 @@ struct exec_vmcmd {
 #define VMCMD_RELATIVE  0x0001  /* ev_addr is relative to base entry */
 #define VMCMD_BASE      0x0002  /* marks a base entry */
 #define VMCMD_STACK     0x0004  /* create with UVM_FLAG_STACK */
-#define VMCMD_SYSCALL   0x0008  /* create with UVM_FLAG_SYSCALL */
 #define VMCMD_IMMUTABLE        0x0010  /* create with UVM_ET_IMMUTABLE */
 #define VMCMD_TEXTREL  0x0020  /* terrible binary contains terrible textrel */
 };
index c98ea17..4333914 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.357 2024/03/30 13:33:21 mpi Exp $  */
+/*     $OpenBSD: proc.h,v 1.358 2024/04/02 08:39:16 deraadt Exp $      */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -337,7 +337,6 @@ struct proc {
        struct  filedesc *p_fd;         /* copy of p_p->ps_fd */
        struct  vmspace *p_vmspace;     /* [I] copy of p_p->ps_vmspace */
        struct  p_inentry p_spinentry;  /* [o] cache for SP check */
-       struct  p_inentry p_pcinentry;  /* [o] cache for PC check */
 
        int     p_flag;                 /* P_* flags. */
        u_char  p_spare;                /* unused */
index 3078d2c..79dd17e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm.h,v 1.72 2024/03/30 12:47:47 mpi Exp $    */
+/*     $OpenBSD: uvm.h,v 1.73 2024/04/02 08:39:17 deraadt Exp $        */
 /*     $NetBSD: uvm.h,v 1.24 2000/11/27 08:40:02 chs Exp $     */
 
 /*
@@ -92,7 +92,6 @@ struct uvm {
 #define UVM_ET_STACK           0x0040  /* this is a stack */
 #define UVM_ET_WC              0x0080  /* write combining */
 #define UVM_ET_CONCEAL         0x0100  /* omit from dumps */
-#define UVM_ET_SYSCALL         0x0200  /* syscall text segment */
 #define UVM_ET_IMMUTABLE       0x0400  /* entry may not be changed */
 #define UVM_ET_FREEMAPPED      0x8000  /* map entry is on free list (DEBUG) */
 
index 7fd7323..0b9a135 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_extern.h,v 1.173 2024/01/19 21:20:35 deraadt Exp $        */
+/*     $OpenBSD: uvm_extern.h,v 1.174 2024/04/02 08:39:17 deraadt Exp $        */
 /*     $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $      */
 
 /*
@@ -111,7 +111,6 @@ typedef int         vm_prot_t;
 #define UVM_FLAG_STACK   0x2000000 /* page may contain a stack */
 #define UVM_FLAG_WC      0x4000000 /* write combining */
 #define UVM_FLAG_CONCEAL 0x8000000 /* omit from dumps */
-#define UVM_FLAG_SYSCALL 0x10000000 /* system calls allowed */
 #define UVM_FLAG_SIGALTSTACK 0x20000000 /* sigaltstack validation required */
 
 /* macros to extract info */
index 0e84e2a..a0c17ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_map.c,v 1.327 2024/02/21 03:28:29 deraadt Exp $   */
+/*     $OpenBSD: uvm_map.c,v 1.328 2024/04/02 08:39:17 deraadt Exp $   */
 /*     $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
 
 /*
@@ -871,12 +871,6 @@ uvm_mapanon(struct vm_map *map, vaddr_t *addr, vsize_t sz,
        entry->inheritance = inherit;
        entry->wired_count = 0;
        entry->advice = advice;
-       if (prot & PROT_WRITE)
-               map->wserial++;
-       if (flags & UVM_FLAG_SYSCALL) {
-               entry->etype |= UVM_ET_SYSCALL;
-               map->wserial++;
-       }
        if (flags & UVM_FLAG_STACK) {
                entry->etype |= UVM_ET_STACK;
                if (flags & (UVM_FLAG_FIXED | UVM_FLAG_UNMAP))
@@ -1146,12 +1140,6 @@ uvm_map(struct vm_map *map, vaddr_t *addr, vsize_t sz,
        entry->inheritance = inherit;
        entry->wired_count = 0;
        entry->advice = advice;
-       if (prot & PROT_WRITE)
-               map->wserial++;
-       if (flags & UVM_FLAG_SYSCALL) {
-               entry->etype |= UVM_ET_SYSCALL;
-               map->wserial++;
-       }
        if (flags & UVM_FLAG_STACK) {
                entry->etype |= UVM_ET_STACK;
                if (flags & UVM_FLAG_UNMAP)
@@ -1613,23 +1601,6 @@ uvm_map_inentry_sp(vm_map_entry_t entry)
        return (1);
 }
 
-/*
- * The system call must not come from a writeable entry, W^X is violated.
- * (Would be nice if we can spot aliasing, which is also kind of bad)
- *
- * The system call must come from an syscall-labeled entry (which are
- * the text regions of the main program, sigtramp, ld.so, or libc).
- */
-int
-uvm_map_inentry_pc(vm_map_entry_t entry)
-{
-       if (entry->protection & PROT_WRITE)
-               return (0);     /* not permitted */
-       if ((entry->etype & UVM_ET_SYSCALL) == 0)
-               return (0);     /* not permitted */
-       return (1);
-}
-
 int
 uvm_map_inentry_recheck(u_long serial, vaddr_t addr, struct p_inentry *ie)
 {
@@ -1747,8 +1718,6 @@ uvm_map_is_stack_remappable(struct vm_map *map, vaddr_t addr, vaddr_t sz,
                        return FALSE;
                }
                if (sigaltstack_check) {
-                       if ((iter->etype & UVM_ET_SYSCALL))
-                               return FALSE;
                        if (iter->protection != (PROT_READ | PROT_WRITE))
                                return FALSE;
                }
@@ -2937,13 +2906,12 @@ uvm_map_printit(struct vm_map *map, boolean_t full,
                    (long long)entry->offset, entry->aref.ar_amap,
                    entry->aref.ar_pageoff);
                (*pr)("\tsubmap=%c, cow=%c, nc=%c, stack=%c, "
-                   "syscall=%c, prot(max)=%d/%d, inh=%d, "
+                   "prot(max)=%d/%d, inh=%d, "
                    "wc=%d, adv=%d\n",
                    (entry->etype & UVM_ET_SUBMAP) ? 'T' : 'F',
                    (entry->etype & UVM_ET_COPYONWRITE) ? 'T' : 'F',
                    (entry->etype & UVM_ET_NEEDSCOPY) ? 'T' : 'F',
                    (entry->etype & UVM_ET_STACK) ? 'T' : 'F',
-                   (entry->etype & UVM_ET_SYSCALL) ? 'T' : 'F',
                    entry->protection, entry->max_protection,
                    entry->inheritance, entry->wired_count, entry->advice);
 
@@ -3222,10 +3190,6 @@ uvm_map_protect(struct vm_map *map, vaddr_t start, vaddr_t end,
                        mask = UVM_ET_ISCOPYONWRITE(iter) ?
                            ~PROT_WRITE : PROT_MASK;
 
-                       /* XXX should only wserial++ if no split occurs */
-                       if (iter->protection & PROT_WRITE)
-                               map->wserial++;
-
                        if (map->flags & VM_MAP_ISVMSPACE) {
                                if (old_prot == PROT_NONE) {
                                        ((struct vmspace *)map)->vm_dused +=
@@ -3401,7 +3365,7 @@ uvmspace_exec(struct proc *p, vaddr_t start, vaddr_t end)
                 */
                vm_map_lock(map);
                vm_map_modflags(map, 0, VM_MAP_WIREFUTURE |
-                   VM_MAP_SYSCALL_ONCE | VM_MAP_PINSYSCALL_ONCE);
+                   VM_MAP_PINSYSCALL_ONCE);
 
                /*
                 * now unmap the old program
@@ -3938,8 +3902,7 @@ uvmspace_fork(struct process *pr)
                            new_map, new_entry->start, new_entry->end);
                }
        }
-       new_map->flags |= old_map->flags &
-           (VM_MAP_SYSCALL_ONCE | VM_MAP_PINSYSCALL_ONCE);
+       new_map->flags |= old_map->flags & VM_MAP_PINSYSCALL_ONCE;
 #ifdef PMAP_CHECK_COPYIN
        if (PMAP_CHECK_COPYIN) {
                memcpy(&new_map->check_copyin, &old_map->check_copyin,
@@ -4244,48 +4207,6 @@ uvm_map_check_copyin_add(struct vm_map *map, vaddr_t start, vaddr_t end)
 }
 #endif /* PMAP_CHECK_COPYIN */
 
-/* 
- * uvm_map_syscall: permit system calls for range of addrs in map.
- *
- * => map must be unlocked
- */
-int
-uvm_map_syscall(struct vm_map *map, vaddr_t start, vaddr_t end)
-{
-       struct vm_map_entry *entry;
-
-       if (start > end)
-               return EINVAL;
-       start = MAX(start, map->min_offset);
-       end = MIN(end, map->max_offset);
-       if (start >= end)
-               return 0;
-       if (map->flags & VM_MAP_SYSCALL_ONCE)   /* only allowed once */
-               return (EPERM);
-
-       vm_map_lock(map);
-
-       entry = uvm_map_entrybyaddr(&map->addr, start);
-       if (entry->end > start)
-               UVM_MAP_CLIP_START(map, entry, start);
-       else
-               entry = RBT_NEXT(uvm_map_addr, entry);
-
-       while (entry != NULL && entry->start < end) {
-               UVM_MAP_CLIP_END(map, entry, end);
-               entry->etype |= UVM_ET_SYSCALL;
-               entry = RBT_NEXT(uvm_map_addr, entry);
-       }
-
-#ifdef PMAP_CHECK_COPYIN
-       check_copyin_add(map, start, end);      /* Add libc's text segment */
-#endif
-       map->wserial++;
-       map->flags |= VM_MAP_SYSCALL_ONCE;
-       vm_map_unlock(map);
-       return (0);
-}
-
 /* 
  * uvm_map_immutable: block mapping/mprotect for range of addrs in map.
  *
@@ -4328,8 +4249,6 @@ uvm_map_immutable(struct vm_map *map, vaddr_t start, vaddr_t end, int imut)
                        entry->etype &= ~UVM_ET_IMMUTABLE;
                entry = RBT_NEXT(uvm_map_addr, entry);
        }
-
-       map->wserial++;
        error = 0;
 out:
        vm_map_unlock(map);
index b1f5369..2fd80e8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_map.h,v 1.88 2024/01/16 19:05:01 deraadt Exp $    */
+/*     $OpenBSD: uvm_map.h,v 1.89 2024/04/02 08:39:17 deraadt Exp $    */
 /*     $NetBSD: uvm_map.h,v 1.24 2001/02/18 21:19:08 chs Exp $ */
 
 /*
@@ -261,7 +261,6 @@ RBT_PROTOTYPE(uvm_map_addr, vm_map_entry, daddrs.addr_entry,
 struct vm_map {
        struct pmap             *pmap;          /* [I] Physical map */
        u_long                  sserial;        /* [v] # stack changes */
-       u_long                  wserial;        /* [v] # PROT_WRITE increases */
 
        struct uvm_map_addr     addr;           /* [v] Entry tree, by addr */
 
@@ -328,7 +327,6 @@ struct vm_map {
 #define        VM_MAP_WANTLOCK         0x10            /* rw: want to write-lock */
 #define        VM_MAP_GUARDPAGES       0x20            /* rw: add guard pgs to map */
 #define        VM_MAP_ISVMSPACE        0x40            /* ro: map is a vmspace */
-#define        VM_MAP_SYSCALL_ONCE     0x80            /* rw: libc syscall registered */
 #define        VM_MAP_PINSYSCALL_ONCE  0x100           /* rw: pinsyscall done */
 
 /* Number of kernel maps and entries to statically allocate */
@@ -358,7 +356,6 @@ struct vm_map *     uvm_map_create(pmap_t, vaddr_t, vaddr_t, int);
 vaddr_t                uvm_map_pie(vaddr_t);
 vaddr_t                uvm_map_hint(struct vmspace *, vm_prot_t, vaddr_t, vaddr_t);
 int            uvm_map_check_copyin_add(struct vm_map *, vaddr_t, vaddr_t);
-int            uvm_map_syscall(struct vm_map *, vaddr_t, vaddr_t);
 int            uvm_map_immutable(struct vm_map *, vaddr_t, vaddr_t, int);
 int            uvm_map_inherit(struct vm_map *, vaddr_t, vaddr_t, vm_inherit_t);
 int            uvm_map_advice(struct vm_map *, vaddr_t, vaddr_t, int);
@@ -385,7 +382,6 @@ int         uvm_map_mquery(struct vm_map*, vaddr_t*, vsize_t, voff_t, int);
 struct p_inentry;
 
 int            uvm_map_inentry_sp(vm_map_entry_t);
-int            uvm_map_inentry_pc(vm_map_entry_t);
 boolean_t      uvm_map_inentry(struct proc *, struct p_inentry *, vaddr_t addr,
                    const char *fmt, int (*fn)(vm_map_entry_t), u_long serial);
 
index c0205f2..4148367 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_mmap.c,v 1.186 2024/03/28 02:19:57 deraadt Exp $  */
+/*     $OpenBSD: uvm_mmap.c,v 1.187 2024/04/02 08:39:17 deraadt Exp $  */
 /*     $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $        */
 
 /*
@@ -592,24 +592,7 @@ sys_mprotect(struct proc *p, void *v, register_t *retval)
 int
 sys_msyscall(struct proc *p, void *v, register_t *retval)
 {
-       struct sys_msyscall_args /* {
-               syscallarg(void *) addr;
-               syscallarg(size_t) len;
-       } */ *uap = v;
-       vaddr_t addr;
-       vsize_t size, pageoff;
-
-       addr = (vaddr_t)SCARG(uap, addr);
-       size = (vsize_t)SCARG(uap, len);
-
-       /*
-        * align the address to a page boundary, and adjust the size accordingly
-        */
-       ALIGN_ADDR(addr, size, pageoff);
-       if (addr > SIZE_MAX - size)
-               return EINVAL;          /* disallow wrap-around. */
-
-       return uvm_map_syscall(&p->p_vmspace->vm_map, addr, addr+size);
+       return 0;
 }
 
 /*