summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/ld.so/Makefile4
-rw-r--r--libexec/ld.so/aarch64/syscall.h3
-rw-r--r--libexec/ld.so/alpha/syscall.h3
-rw-r--r--libexec/ld.so/amd64/syscall.h3
-rw-r--r--libexec/ld.so/arm/syscall.h3
-rw-r--r--libexec/ld.so/hppa/syscall.h3
-rw-r--r--libexec/ld.so/i386/syscall.h3
-rw-r--r--libexec/ld.so/library.c19
-rw-r--r--libexec/ld.so/library_mquery.c17
-rw-r--r--libexec/ld.so/m88k/syscall.h3
-rw-r--r--libexec/ld.so/mips64/syscall.h3
-rw-r--r--libexec/ld.so/powerpc/syscall.h3
-rw-r--r--libexec/ld.so/sh/syscall.h3
-rw-r--r--libexec/ld.so/sparc64/syscall.h3
-rw-r--r--sys/kern/exec_elf.c17
-rw-r--r--sys/kern/exec_subr.c7
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/kern_exec.c4
-rw-r--r--sys/sys/exec.h3
-rw-r--r--sys/sys/exec_elf.h34
-rw-r--r--sys/sys/syscall_mi.h6
-rw-r--r--sys/uvm/uvm.h3
-rw-r--r--sys/uvm/uvm_extern.h3
-rw-r--r--sys/uvm/uvm_map.c58
-rw-r--r--sys/uvm/uvm_map.h4
-rw-r--r--sys/uvm/uvm_mmap.c4
-rw-r--r--usr.sbin/procmap/procmap.c28
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' : '-',