From: deraadt Date: Tue, 2 Apr 2024 08:39:16 +0000 (+0000) Subject: Delete the msyscall mechanism entirely, since mimmutable+pinsyscalls has X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=30d2057940fb9e9627ddc71bfc4fe05f8825fcec;p=openbsd Delete the msyscall mechanism entirely, since mimmutable+pinsyscalls has 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. --- diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c index 33e5cadb76a..0cb3b15968f 100644 --- a/sys/kern/exec_elf.c +++ b/sys/kern/exec_elf.c @@ -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. diff --git a/sys/kern/exec_subr.c b/sys/kern/exec_subr.c index a02566bf797..4ebca1b981d 100644 --- a/sys/kern/exec_subr.c +++ b/sys/kern/exec_subr.c @@ -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 diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index b4816b2e9a0..d571b0855cf 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -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++) { diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index a00e2372145..7d87a4cbcb9 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -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); } diff --git a/sys/sys/exec.h b/sys/sys/exec.h index d6b5c645713..801181f2c98 100644 --- a/sys/sys/exec.h +++ b/sys/sys/exec.h @@ -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 */ }; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c98ea17b594..4333914bf6e 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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 */ diff --git a/sys/uvm/uvm.h b/sys/uvm/uvm.h index 3078d2cfed9..79dd17e35d4 100644 --- a/sys/uvm/uvm.h +++ b/sys/uvm/uvm.h @@ -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) */ diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 7fd732396c5..0b9a135d3ad 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -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 */ diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c index 0e84e2a1e3f..a0c17ee18f4 100644 --- a/sys/uvm/uvm_map.c +++ b/sys/uvm/uvm_map.c @@ -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); diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h index b1f53696f7a..2fd80e85888 100644 --- a/sys/uvm/uvm_map.h +++ b/sys/uvm/uvm_map.h @@ -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); diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index c0205f26781..4148367ebad 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -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; } /*