diff options
-rw-r--r-- | libexec/ld.so/Makefile | 4 | ||||
-rw-r--r-- | libexec/ld.so/aarch64/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/alpha/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/amd64/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/arm/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/hppa/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/i386/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 19 | ||||
-rw-r--r-- | libexec/ld.so/library_mquery.c | 17 | ||||
-rw-r--r-- | libexec/ld.so/m88k/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/mips64/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/sh/syscall.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/syscall.h | 3 | ||||
-rw-r--r-- | sys/kern/exec_elf.c | 17 | ||||
-rw-r--r-- | sys/kern/exec_subr.c | 7 | ||||
-rw-r--r-- | sys/kern/init_main.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 4 | ||||
-rw-r--r-- | sys/sys/exec.h | 3 | ||||
-rw-r--r-- | sys/sys/exec_elf.h | 34 | ||||
-rw-r--r-- | sys/sys/syscall_mi.h | 6 | ||||
-rw-r--r-- | sys/uvm/uvm.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_extern.h | 3 | ||||
-rw-r--r-- | sys/uvm/uvm_map.c | 58 | ||||
-rw-r--r-- | sys/uvm/uvm_map.h | 4 | ||||
-rw-r--r-- | sys/uvm/uvm_mmap.c | 4 | ||||
-rw-r--r-- | usr.sbin/procmap/procmap.c | 28 |
27 files changed, 186 insertions, 63 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile index 92151b25d88..f9dd281ff66 100644 --- a/libexec/ld.so/Makefile +++ b/libexec/ld.so/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.77 2019/10/20 03:44:49 guenther Exp $ +# $OpenBSD: Makefile,v 1.78 2019/11/29 06:34:44 deraadt Exp $ SUBDIR=ldconfig ldd MAN= ld.so.1 @@ -28,7 +28,7 @@ SRCS+= dl_uname.c dl_dirname.c strlcat.c strlen.c trace.c SRCS+= malloc.c reallocarray.c tib.c ffs.c syscall=__syscall close exit fstat getdents getentropy getthrid issetugid \ - mprotect munmap open pledge read __realpath sendsyslog \ + mprotect munmap msyscall open pledge read __realpath sendsyslog \ __set_tcb sysctl thrkill utrace write GEN_PREFIX=\t.file "${@:R}.c"\n\#include "SYS.h" diff --git a/libexec/ld.so/aarch64/syscall.h b/libexec/ld.so/aarch64/syscall.h index f45c018475a..b1a3a7b442f 100644 --- a/libexec/ld.so/aarch64/syscall.h +++ b/libexec/ld.so/aarch64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.7 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.8 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/alpha/syscall.h b/libexec/ld.so/alpha/syscall.h index 4adb1a619e3..f8f322c9c11 100644 --- a/libexec/ld.so/alpha/syscall.h +++ b/libexec/ld.so/alpha/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.41 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.42 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/amd64/syscall.h b/libexec/ld.so/amd64/syscall.h index 9c5c1b6487e..a680d1bddd9 100644 --- a/libexec/ld.so/amd64/syscall.h +++ b/libexec/ld.so/amd64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.28 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.29 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/arm/syscall.h b/libexec/ld.so/arm/syscall.h index 9c5c1b6487e..a680d1bddd9 100644 --- a/libexec/ld.so/arm/syscall.h +++ b/libexec/ld.so/arm/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.28 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.29 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/hppa/syscall.h b/libexec/ld.so/hppa/syscall.h index 9c5c1b6487e..a680d1bddd9 100644 --- a/libexec/ld.so/hppa/syscall.h +++ b/libexec/ld.so/hppa/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.28 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.29 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/i386/syscall.h b/libexec/ld.so/i386/syscall.h index d0bc750ae5d..b7f329a184a 100644 --- a/libexec/ld.so/i386/syscall.h +++ b/libexec/ld.so/i386/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.32 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.33 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c index e9def013abc..204e631b201 100644 --- a/libexec/ld.so/library.c +++ b/libexec/ld.so/library.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library.c,v 1.83 2019/10/04 17:42:16 guenther Exp $ */ +/* $OpenBSD: library.c,v 1.84 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -102,7 +102,8 @@ _dl_tryload_shlib(const char *libname, int type, int flags) Elf_Addr libaddr, loff, align = _dl_pagesz - 1; Elf_Addr relro_addr = 0, relro_size = 0; elf_object_t *object; - char hbuf[4096]; + char hbuf[4096], *exec_start = 0; + size_t exec_size = 0; Elf_Dyn *dynp = NULL; Elf_Ehdr *ehdr; Elf_Phdr *phdp; @@ -253,6 +254,11 @@ _dl_tryload_shlib(const char *libname, int type, int flags) _dl_load_list_free(load_list); return(0); } + if ((flags & PROT_EXEC) && exec_start == 0) { + exec_start = start; + exec_size = ROUND_PG(size); + } + if (phdp->p_flags & PF_W) { /* Zero out everything past the EOF */ if ((size & align) != 0) @@ -301,6 +307,8 @@ _dl_tryload_shlib(const char *libname, int type, int flags) (Elf_Phdr *)((char *)libaddr + ehdr->e_phoff), ehdr->e_phnum,type, libaddr, loff); if (object) { + char *soname = (char *)object->Dyn.info[DT_SONAME]; + object->load_size = maxva - minva; /*XXX*/ object->load_list = load_list; /* set inode, dev from stat info */ @@ -312,6 +320,13 @@ _dl_tryload_shlib(const char *libname, int type, int flags) _dl_set_sod(object->load_name, &object->sod); if (ptls != NULL && ptls->p_memsz) _dl_set_tls(object, ptls, libaddr, libname); + + /* Request permission for system calls in libc.so's text segment */ + if (soname != NULL && + _dl_strncmp(soname, "libc.so.", 8) == 0) { + if (_dl_msyscall(exec_start, exec_size) == -1) + _dl_printf("msyscall %lx %lx error\n"); + } } else { _dl_munmap((void *)libaddr, maxva - minva); _dl_load_list_free(load_list); diff --git a/libexec/ld.so/library_mquery.c b/libexec/ld.so/library_mquery.c index 6f061410f51..f7e2baaa747 100644 --- a/libexec/ld.so/library_mquery.c +++ b/libexec/ld.so/library_mquery.c @@ -1,4 +1,4 @@ -/* $OpenBSD: library_mquery.c,v 1.60 2019/10/04 17:42:16 guenther Exp $ */ +/* $OpenBSD: library_mquery.c,v 1.61 2019/11/29 06:34:44 deraadt Exp $ */ /* * Copyright (c) 2002 Dale Rahn @@ -112,7 +112,8 @@ _dl_tryload_shlib(const char *libname, int type, int flags) Elf_Phdr *ptls = NULL; Elf_Addr relro_addr = 0, relro_size = 0; struct stat sb; - char hbuf[4096]; + char hbuf[4096], *exec_start = 0; + size_t exec_size = 0; #define ROUND_PG(x) (((x) + align) & ~(align)) #define TRUNC_PG(x) ((x) & ~(align)) @@ -288,6 +289,11 @@ retry: load_end = (Elf_Addr)ld->start + ROUND_PG(ld->size); } + if ((flags & PROT_EXEC) && exec_start == 0) { + exec_start = ld->start; + exec_size = ROUND_PG(ld->size); + } + phdp = (Elf_Phdr *)(hbuf + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++, phdp++) { if (phdp->p_type == PT_OPENBSD_RANDOMIZE) @@ -318,6 +324,13 @@ retry: if (ptls != NULL && ptls->p_memsz) _dl_set_tls(object, ptls, (Elf_Addr)lowld->start, libname); + + /* Request permission for system calls in libc.so's text segment */ + if (soname != NULL && + _dl_strncmp(soname, "libc.so.", 8) == 0) { + if (_dl_msyscall(exec_start, exec_size) == -1) + _dl_printf("msyscall %lx %lx error\n"); + } } else { _dl_load_list_free(lowld); } diff --git a/libexec/ld.so/m88k/syscall.h b/libexec/ld.so/m88k/syscall.h index ded5f6bc6db..f0b4c20e7e6 100644 --- a/libexec/ld.so/m88k/syscall.h +++ b/libexec/ld.so/m88k/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.24 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.25 2019/11/29 06:34:45 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/mips64/syscall.h b/libexec/ld.so/mips64/syscall.h index fc8e4c2e9d3..0d2497e6f3d 100644 --- a/libexec/ld.so/mips64/syscall.h +++ b/libexec/ld.so/mips64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.30 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.31 2019/11/29 06:34:45 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/powerpc/syscall.h b/libexec/ld.so/powerpc/syscall.h index 3d9a8a2207d..ab8811f0615 100644 --- a/libexec/ld.so/powerpc/syscall.h +++ b/libexec/ld.so/powerpc/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.47 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.48 2019/11/29 06:34:45 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/sh/syscall.h b/libexec/ld.so/sh/syscall.h index 0f39ad62c6b..dbb8084e6b2 100644 --- a/libexec/ld.so/sh/syscall.h +++ b/libexec/ld.so/sh/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.27 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.28 2019/11/29 06:34:45 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/libexec/ld.so/sparc64/syscall.h b/libexec/ld.so/sparc64/syscall.h index 656747035d4..f597523e8ae 100644 --- a/libexec/ld.so/sparc64/syscall.h +++ b/libexec/ld.so/sparc64/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.40 2019/07/14 03:23:12 guenther Exp $ */ +/* $OpenBSD: syscall.h,v 1.41 2019/11/29 06:34:45 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -48,6 +48,7 @@ int _dl_getthrid(void); int _dl_mprotect(const void *, size_t, int); int _dl_munmap(const void *, size_t); int _dl_open(const char *, int); +int _dl_msyscall(void *addr, size_t len); ssize_t _dl_read(int, const char *, size_t); int _dl_pledge(const char *, const char **); long _dl___syscall(quad_t, ...); diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c index 24adf0dbed6..87f0a4583c8 100644 --- a/sys/kern/exec_elf.c +++ b/sys/kern/exec_elf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_elf.c,v 1.151 2019/05/13 19:21:31 bluhm Exp $ */ +/* $OpenBSD: exec_elf.c,v 1.152 2019/11/29 06:34:45 deraadt Exp $ */ /* * Copyright (c) 1996 Per Fogelstrom @@ -456,7 +456,7 @@ 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); + &ph[i], &addr, &size, &prot, flags | VMCMD_SYSCALL); /* 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)) { @@ -621,6 +621,19 @@ exec_elf_makecmds(struct proc *p, struct exec_package *epp) } } else addr = ELF_NO_ADDR; + /* + * static binary: main program does system calls + * dynamic binary: regular main program won't do system + * calls, unfortunately go binaries do... + */ + flags |= VMCMD_SYSCALL; + if (interp == NULL) { + /* + * static binary: no ld.so, no late request for + * syscalls inside libc,so block msyscall() + */ + p->p_vmspace->vm_map.flags |= VM_MAP_SYSCALL_ONCE; + } /* * Calculates size of text and data segments diff --git a/sys/kern/exec_subr.c b/sys/kern/exec_subr.c index f32be4bddf4..0a1bad77f12 100644 --- a/sys/kern/exec_subr.c +++ b/sys/kern/exec_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_subr.c,v 1.56 2019/06/21 09:39:48 visa Exp $ */ +/* $OpenBSD: exec_subr.c,v 1.57 2019/11/29 06:34:45 deraadt Exp $ */ /* $NetBSD: exec_subr.c,v 1.9 1994/12/04 03:10:42 mycroft Exp $ */ /* @@ -167,6 +167,7 @@ vmcmd_map_pagedvn(struct proc *p, struct exec_vmcmd *cmd) * call this routine. */ struct uvm_object *uobj; + unsigned int syscalls = 0; int error; /* @@ -193,11 +194,13 @@ vmcmd_map_pagedvn(struct proc *p, struct exec_vmcmd *cmd) /* * do the map */ + if ((cmd->ev_flags & VMCMD_SYSCALL) && (cmd->ev_prot & PROT_EXEC)) + syscalls |= 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, - MADV_NORMAL, UVM_FLAG_COPYONW|UVM_FLAG_FIXED)); + MADV_NORMAL, UVM_FLAG_COPYONW | UVM_FLAG_FIXED | syscalls)); /* * check for error diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 558d99b28f3..dc03e801b16 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.292 2019/11/04 17:51:22 anton Exp $ */ +/* $OpenBSD: init_main.c,v 1.293 2019/11/29 06:34:45 deraadt Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -651,7 +651,8 @@ start_init(void *arg) if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE, 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))) + MADV_NORMAL, + UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW|UVM_FLAG_STACK|UVM_FLAG_SYSCALL))) 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 b71c8a9843c..3af40a9a400 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.209 2019/11/05 08:18:47 mpi Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.210 2019/11/29 06:34:45 deraadt Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -856,7 +856,7 @@ exec_sigcode_map(struct process *pr, struct emul *e) if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_sigcode, round_page(sz), e->e_sigobject, 0, 0, UVM_MAPFLAG(PROT_READ | PROT_EXEC, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_INHERIT_COPY, - MADV_RANDOM, UVM_FLAG_COPYONW))) { + MADV_RANDOM, UVM_FLAG_COPYONW | UVM_FLAG_SYSCALL))) { uao_detach(e->e_sigobject); return (ENOMEM); } diff --git a/sys/sys/exec.h b/sys/sys/exec.h index 77e1066e136..ecaef3ef40b 100644 --- a/sys/sys/exec.h +++ b/sys/sys/exec.h @@ -1,4 +1,4 @@ -/* $OpenBSD: exec.h,v 1.39 2019/11/28 04:34:50 guenther Exp $ */ +/* $OpenBSD: exec.h,v 1.40 2019/11/29 06:34:46 deraadt Exp $ */ /* $NetBSD: exec.h,v 1.59 1996/02/09 18:25:09 christos Exp $ */ /*- @@ -98,6 +98,7 @@ 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 EXEC_DEFAULT_VMCMD_SETSIZE 8 /* # of cmds in set to start */ diff --git a/sys/sys/exec_elf.h b/sys/sys/exec_elf.h index 21d9ea72813..403221a3b3b 100644 --- a/sys/sys/exec_elf.h +++ b/sys/sys/exec_elf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_elf.h,v 1.84 2019/04/20 23:10:00 deraadt Exp $ */ +/* $OpenBSD: exec_elf.h,v 1.85 2019/11/29 06:34:46 deraadt Exp $ */ /* * Copyright (c) 1995, 1996 Erik Theisen. All rights reserved. * @@ -56,7 +56,7 @@ typedef __int64_t Elf64_Sxword; typedef __uint64_t Elf64_Xword; typedef __uint64_t Elf64_Lword; -typedef __uint32_t Elf64_Half; +typedef __uint16_t Elf64_Half; typedef __uint16_t Elf64_Quarter; /* @@ -141,11 +141,11 @@ typedef struct { unsigned char e_ident[EI_NIDENT]; /* Id bytes */ Elf64_Quarter e_type; /* file type */ Elf64_Quarter e_machine; /* machine type */ - Elf64_Half e_version; /* version number */ + Elf64_Word e_version; /* version number */ Elf64_Addr e_entry; /* entry point */ Elf64_Off e_phoff; /* Program hdr offset */ Elf64_Off e_shoff; /* Section hdr offset */ - Elf64_Half e_flags; /* Processor flags */ + Elf64_Word e_flags; /* Processor flags */ Elf64_Quarter e_ehsize; /* sizeof ehdr */ Elf64_Quarter e_phentsize; /* Program header entry size */ Elf64_Quarter e_phnum; /* Number of program headers */ @@ -225,14 +225,14 @@ typedef struct { } Elf32_Shdr; typedef struct { - Elf64_Half sh_name; /* section name */ - Elf64_Half sh_type; /* section type */ + Elf64_Word sh_name; /* section name */ + Elf64_Word sh_type; /* section type */ Elf64_Xword sh_flags; /* section flags */ Elf64_Addr sh_addr; /* virtual address */ Elf64_Off sh_offset; /* file offset */ Elf64_Xword sh_size; /* section size */ - Elf64_Half sh_link; /* link to another */ - Elf64_Half sh_info; /* misc info */ + Elf64_Word sh_link; /* link to another */ + Elf64_Word sh_info; /* misc info */ Elf64_Xword sh_addralign; /* memory alignment */ Elf64_Xword sh_entsize; /* table entry size */ } Elf64_Shdr; @@ -335,7 +335,7 @@ typedef struct elf32_sym { } Elf32_Sym; typedef struct { - Elf64_Half st_name; /* Symbol name index in str table */ + Elf64_Word st_name; /* Symbol name index in str table */ Elf_Byte st_info; /* type / binding attrs */ Elf_Byte st_other; /* unused */ Elf64_Quarter st_shndx; /* section index of symbol */ @@ -443,8 +443,8 @@ typedef struct { } Elf32_Phdr; typedef struct { - Elf64_Half p_type; /* entry type */ - Elf64_Half p_flags; /* flags */ + Elf64_Word p_type; /* entry type */ + Elf64_Word p_flags; /* flags */ Elf64_Off p_offset; /* offset */ Elf64_Addr p_vaddr; /* virtual address */ Elf64_Addr p_paddr; /* physical address */ @@ -578,9 +578,9 @@ typedef struct { } Elf32_Nhdr; typedef struct { - Elf64_Half n_namesz; - Elf64_Half n_descsz; - Elf64_Half n_type; + Elf64_Word n_namesz; + Elf64_Word n_descsz; + Elf64_Word n_type; } Elf64_Nhdr; /* @@ -593,9 +593,9 @@ typedef struct { } Elf32_Note; typedef struct { - Elf64_Half namesz; - Elf64_Half descsz; - Elf64_Half type; + Elf64_Word namesz; + Elf64_Word descsz; + Elf64_Word type; } Elf64_Note; /* Values for n_type. */ diff --git a/sys/sys/syscall_mi.h b/sys/sys/syscall_mi.h index 1e071933349..f7e87413faa 100644 --- a/sys/sys/syscall_mi.h +++ b/sys/sys/syscall_mi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall_mi.h,v 1.23 2019/11/04 18:06:03 visa Exp $ */ +/* $OpenBSD: syscall_mi.h,v 1.24 2019/11/29 06:34:46 deraadt Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -73,9 +73,9 @@ mi_syscall(struct proc *p, register_t code, const struct sysent *callp, uvm_map_inentry_sp, p->p_vmspace->vm_map.sserial)) return (EPERM); - /* PC must not be in writeable memory */ + /* PC must be in un-writeable permitted text (sigtramp, libc, ld.so) */ if (!uvm_map_inentry(p, &p->p_pcinentry, PROC_PC(p), - "[%s]%d/%d pc=%lx inside %lx-%lx: writeable syscall\n", + "[%s]%d/%d pc=%lx inside %lx-%lx: bogus syscall\n", uvm_map_inentry_pc, p->p_vmspace->vm_map.wserial)) return (EPERM); diff --git a/sys/uvm/uvm.h b/sys/uvm/uvm.h index a2147155523..731ce8dba42 100644 --- a/sys/uvm/uvm.h +++ b/sys/uvm/uvm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm.h,v 1.65 2019/07/18 23:47:33 cheloha Exp $ */ +/* $OpenBSD: uvm.h,v 1.66 2019/11/29 06:34:45 deraadt Exp $ */ /* $NetBSD: uvm.h,v 1.24 2000/11/27 08:40:02 chs Exp $ */ /* @@ -91,6 +91,7 @@ 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_FREEMAPPED 0x8000 /* map entry is on free list (DEBUG) */ #define UVM_ET_ISOBJ(E) (((E)->etype & UVM_ET_OBJ) != 0) diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 203955c6375..779f7654d9d 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_extern.h,v 1.150 2019/11/28 23:42:52 guenther Exp $ */ +/* $OpenBSD: uvm_extern.h,v 1.151 2019/11/29 06:34:45 deraadt Exp $ */ /* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */ /* @@ -114,6 +114,7 @@ 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 */ /* macros to extract info */ #define UVM_PROTECTION(X) ((X) & PROT_MASK) diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c index d35620c66cd..3791b155920 100644 --- a/sys/uvm/uvm_map.c +++ b/sys/uvm/uvm_map.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_map.c,v 1.252 2019/11/26 18:23:48 mlarkin Exp $ */ +/* $OpenBSD: uvm_map.c,v 1.253 2019/11/29 06:34:45 deraadt Exp $ */ /* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */ /* @@ -1080,6 +1080,10 @@ uvm_mapanon(struct vm_map *map, vaddr_t *addr, vsize_t sz, 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)) @@ -1345,6 +1349,10 @@ uvm_map(struct vm_map *map, vaddr_t *addr, vsize_t sz, 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) @@ -1808,12 +1816,15 @@ uvm_map_inentry_sp(vm_map_entry_t entry) /* * If a syscall comes from a writeable entry, W^X is violated. * (Would be nice if we can spot aliasing, which is also kind of bad) + * Ensure system call comes from libc or ld.so's text segment. */ 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); } @@ -3089,12 +3100,14 @@ uvm_map_printit(struct vm_map *map, boolean_t full, entry, entry->start, entry->end, entry->object.uvm_obj, (long long)entry->offset, entry->aref.ar_amap, entry->aref.ar_pageoff); - (*pr)("\tsubmap=%c, cow=%c, nc=%c, stack=%c, prot(max)=%d/%d, inh=%d, " + (*pr)("\tsubmap=%c, cow=%c, nc=%c, stack=%c, " + "syscall=%c, 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); @@ -3511,7 +3524,7 @@ uvmspace_exec(struct proc *p, vaddr_t start, vaddr_t end) * when a process execs another program image. */ vm_map_lock(map); - vm_map_modflags(map, 0, VM_MAP_WIREFUTURE); + vm_map_modflags(map, 0, VM_MAP_WIREFUTURE|VM_MAP_SYSCALL_ONCE); /* * now unmap the old program @@ -4288,6 +4301,45 @@ uvm_map_inherit(struct vm_map *map, vaddr_t start, vaddr_t end, return (0); } +/* + * 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); + } + + map->wserial++; + map->flags |= VM_MAP_SYSCALL_ONCE; + vm_map_unlock(map); + return (0); +} + /* * uvm_map_advice: set advice code for range of addrs in map. * diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h index bb511e2ed6e..7ee39f50e81 100644 --- a/sys/uvm/uvm_map.h +++ b/sys/uvm/uvm_map.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_map.h,v 1.64 2019/11/02 09:36:08 mpi Exp $ */ +/* $OpenBSD: uvm_map.h,v 1.65 2019/11/29 06:34:46 deraadt Exp $ */ /* $NetBSD: uvm_map.h,v 1.24 2001/02/18 21:19:08 chs Exp $ */ /* @@ -350,6 +350,7 @@ 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 */ /* XXX: number of kernel maps and entries to statically allocate */ @@ -395,6 +396,7 @@ int uvm_map_extract(struct vm_map*, vaddr_t, vsize_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_syscall(vm_map_t, vaddr_t, vaddr_t); int uvm_map_inherit(vm_map_t, vaddr_t, vaddr_t, vm_inherit_t); int uvm_map_advice(vm_map_t, vaddr_t, vaddr_t, int); void uvm_map_init(void); diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 30250a197b3..8e9bd66bc7b 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_mmap.c,v 1.159 2019/11/28 17:19:22 mlarkin Exp $ */ +/* $OpenBSD: uvm_mmap.c,v 1.160 2019/11/29 06:34:46 deraadt Exp $ */ /* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */ /* @@ -606,7 +606,7 @@ sys_msyscall(struct proc *p, void *v, register_t *retval) if (addr > SIZE_MAX - size) return (EINVAL); /* disallow wrap-around. */ - return (0); + return (uvm_map_syscall(&p->p_vmspace->vm_map, addr, addr+size)); } /* diff --git a/usr.sbin/procmap/procmap.c b/usr.sbin/procmap/procmap.c index aa6954e918c..02dcabc561e 100644 --- a/usr.sbin/procmap/procmap.c +++ b/usr.sbin/procmap/procmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procmap.c,v 1.65 2019/02/05 02:17:32 deraadt Exp $ */ +/* $OpenBSD: procmap.c,v 1.66 2019/11/29 06:34:46 deraadt Exp $ */ /* $NetBSD: pmap.c,v 1.1 2002/09/01 20:32:44 atatat Exp $ */ /* @@ -483,11 +483,11 @@ process_map(kvm_t *kd, pid_t pid, struct kinfo_proc *proc, struct sum *sum) /* headers */ #ifdef DISABLED_HEADERS if (print_map) - printf("%-*s %-*s rwx RWX CPY NCP I W A\n", + printf("%-*s %-*s rwxSe RWX CPY NCP I W A\n", (int)sizeof(long) * 2 + 2, "Start", (int)sizeof(long) * 2 + 2, "End"); if (print_maps) - printf("%-*s %-*s rwxp %-*s Dev Inode File\n", + printf("%-*s %-*s rwxSep %-*s Dev Inode File\n", (int)sizeof(long) * 2 + 0, "Start", (int)sizeof(long) * 2 + 0, "End", (int)sizeof(long) * 2 + 0, "Offset"); @@ -497,7 +497,7 @@ process_map(kvm_t *kd, pid_t pid, struct kinfo_proc *proc, struct sum *sum) (int)sizeof(int) * 2 - 1, "Size "); #endif if (print_all) - printf("%-*s %-*s %*s %-*s rwxpc RWX I/W/A Dev %*s - File\n", + printf("%-*s %-*s %*s %-*s rwxpcSe RWX I/W/A Dev %*s - File\n", (int)sizeof(long) * 2, "Start", (int)sizeof(long) * 2, "End", (int)sizeof(int) * 2, "Size ", @@ -719,11 +719,14 @@ dump_vm_map_entry(kvm_t *kd, struct kbit *vmspace, name = findname(kd, vmspace, vme, vp, vfs, uvm_obj); if (print_map) { - printf("0x%lx 0x%lx %c%c%c %c%c%c %s %s %d %d %d", - vme->start, vme->end, + printf("0x%-*lx 0x%-*lx %c%c%c%c%c %c%c%c %s %s %d %d %d", + (int)sizeof(long) * 2 + 0, vme->start, + (int)sizeof(long) * 2 + 0, vme->end, (vme->protection & PROT_READ) ? 'r' : '-', (vme->protection & PROT_WRITE) ? 'w' : '-', (vme->protection & PROT_EXEC) ? 'x' : '-', + (vme->etype & UVM_ET_STACK) ? 'S' : '-', + (vme->etype & UVM_ET_SYSCALL) ? 'e' : '-', (vme->max_protection & PROT_READ) ? 'r' : '-', (vme->max_protection & PROT_WRITE) ? 'w' : '-', (vme->max_protection & PROT_EXEC) ? 'x' : '-', @@ -743,12 +746,14 @@ dump_vm_map_entry(kvm_t *kd, struct kbit *vmspace, } if (print_maps) - printf("%0*lx-%0*lx %c%c%c%c %0*lx %02x:%02x %llu %s\n", + printf("0x%-*lx 0x%-*lx %c%c%c%c%c%c %0*lx %02x:%02x %llu %s\n", (int)sizeof(void *) * 2, vme->start, (int)sizeof(void *) * 2, vme->end, (vme->protection & PROT_READ) ? 'r' : '-', (vme->protection & PROT_WRITE) ? 'w' : '-', (vme->protection & PROT_EXEC) ? 'x' : '-', + (vme->etype & UVM_ET_STACK) ? 'S' : '-', + (vme->etype & UVM_ET_SYSCALL) ? 'e' : '-', (vme->etype & UVM_ET_COPYONWRITE) ? 'p' : 's', (int)sizeof(void *) * 2, (unsigned long)vme->offset, @@ -761,11 +766,14 @@ dump_vm_map_entry(kvm_t *kd, struct kbit *vmspace, vme->start, vme->end, vme->object.uvm_obj, (unsigned long)vme->offset, vme->aref.ar_amap, vme->aref.ar_pageoff); - printf("\tsubmap=%c, cow=%c, nc=%c, prot(max)=%d/%d, inh=%d, " + printf("\tsubmap=%c, cow=%c, nc=%c, stack=%c, " + "syscall=%c, prot(max)=%d/%d, inh=%d, " "wc=%d, adv=%d\n", (vme->etype & UVM_ET_SUBMAP) ? 'T' : 'F', (vme->etype & UVM_ET_COPYONWRITE) ? 'T' : 'F', (vme->etype & UVM_ET_NEEDSCOPY) ? 'T' : 'F', + (vme->etype & UVM_ET_STACK) ? 'T' : 'F', + (vme->etype & UVM_ET_SYSCALL) ? 'T' : 'F', vme->protection, vme->max_protection, vme->inheritance, vme->wired_count, vme->advice); if (inode && verbose) @@ -805,13 +813,15 @@ dump_vm_map_entry(kvm_t *kd, struct kbit *vmspace, } sz = (size_t)((vme->end - vme->start) / 1024); - printf("%0*lx-%0*lx %7luk %0*lx %c%c%c%c%c (%c%c%c) %d/%d/%d %02u:%02u %7llu - %s", + printf("%0*lx-%0*lx %7luk %0*lx %c%c%c%c%c%c%c (%c%c%c) %d/%d/%d %02u:%02u %7llu - %s", (int)sizeof(void *) * 2, vme->start, (int)sizeof(void *) * 2, vme->end - (vme->start != vme->end ? 1 : 0), (unsigned long)sz, (int)sizeof(void *) * 2, (unsigned long)vme->offset, (vme->protection & PROT_READ) ? 'r' : '-', (vme->protection & PROT_WRITE) ? 'w' : '-', (vme->protection & PROT_EXEC) ? 'x' : '-', + (vme->etype & UVM_ET_STACK) ? 'S' : '-', + (vme->etype & UVM_ET_SYSCALL) ? 'e' : '-', (vme->etype & UVM_ET_COPYONWRITE) ? 'p' : 's', (vme->etype & UVM_ET_NEEDSCOPY) ? '+' : '-', (vme->max_protection & PROT_READ) ? 'r' : '-', |