diff options
author | Dan McDonald <danmcd@joyent.com> | 2020-11-17 14:48:44 -0500 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2020-11-17 14:48:44 -0500 |
commit | 2d6415143e9c1044d04ebf846f72f232883413cb (patch) | |
tree | 555fae9f2f89b0c9a4d8c4bbd66b02b70ded9fc7 /usr/src/uts/common | |
parent | 5a1b3228538dfeb09e05cc2bdfad707ee4d698d7 (diff) | |
parent | 5a0af8165ce9590e7a18f1ef4f9badc4dd72c6e6 (diff) | |
download | illumos-joyent-release-20201119.tar.gz |
[illumos-gate merge]release-20201119
commit 5a0af8165ce9590e7a18f1ef4f9badc4dd72c6e6
13274 enable -fstack-protector-strong by default in user land
commit 6a817834d81cc75ce12d0d393320837b1fec1e85
5788 Want support for GCC's stack protector in libc
commit 350ffdd54baf880f440ddf9697666e283894ded1
13273 want upanic(2)
commit 7fdea60d55a95f0e46066fd021c4ef1b1321bafc
13300 mlxcx_cq_setup() doesn't take required locks for ASSERTs
Merge notes:
- Manifest changes to match package changes (including shipping libssp_ns.a)
- Modified lx_vdso tools to not include SSP, to match other build-only tools.
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r-- | usr/src/uts/common/Makefile.files | 1 | ||||
-rw-r--r-- | usr/src/uts/common/exec/elf/elf_notes.c | 38 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx_ring.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/os/exit.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/os/sysent.c | 6 | ||||
-rw-r--r-- | usr/src/uts/common/os/upanic.c | 92 | ||||
-rw-r--r-- | usr/src/uts/common/sys/ccompile.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/elf.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/proc.h | 11 | ||||
-rw-r--r-- | usr/src/uts/common/sys/procfs.h | 15 | ||||
-rw-r--r-- | usr/src/uts/common/sys/syscall.h | 46 |
11 files changed, 201 insertions, 25 deletions
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 752fe56100..374fa41cee 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -387,6 +387,7 @@ GENUNIX_OBJS += \ uname.o \ unix_bb.o \ unlink.o \ + upanic.o \ urw.o \ utime.o \ utssys.o \ diff --git a/usr/src/uts/common/exec/elf/elf_notes.c b/usr/src/uts/common/exec/elf/elf_notes.c index 06f9ceb633..a88250b00f 100644 --- a/usr/src/uts/common/exec/elf/elf_notes.c +++ b/usr/src/uts/common/exec/elf/elf_notes.c @@ -164,6 +164,13 @@ setup_note_header(Phdr *v, proc_t *p) v[0].p_filesz += nlwp * sizeof (Note) + nlwp * roundup(sizeof (asrset_t), sizeof (Word)); #endif /* __sparc */ + + mutex_enter(&p->p_lock); + if ((p->p_upanicflag & P_UPF_PANICKED) != 0) { + v[0].p_filesz += sizeof (Note) + + roundup(sizeof (prupanic_t), sizeof (Word)); + } + mutex_exit(&p->p_lock); } int @@ -186,6 +193,7 @@ write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset, priv_impl_info_t prinfo; struct utsname uts; prsecflags_t psecflags; + prupanic_t upanic; } *bigwad; size_t xregsize = prhasx(p)? prgetprxregsize(p) : 0; @@ -599,6 +607,36 @@ write_elfnotes(proc_t *p, int sig, vnode_t *vp, offset_t offset, } ASSERT(nlwp == 0); + /* + * If a upanic occurred, add a note for it. + */ + mutex_enter(&p->p_lock); + if ((p->p_upanicflag & P_UPF_PANICKED) != 0) { + bzero(&bigwad->upanic, sizeof (prupanic_t)); + bigwad->upanic.pru_version = PRUPANIC_VERSION_1; + if ((p->p_upanicflag & P_UPF_INVALMSG) != 0) { + bigwad->upanic.pru_flags |= PRUPANIC_FLAG_MSG_ERROR; + } + + if ((p->p_upanicflag & P_UPF_TRUNCMSG) != 0) { + bigwad->upanic.pru_flags |= PRUPANIC_FLAG_MSG_TRUNC; + } + + if ((p->p_upanicflag & P_UPF_HAVEMSG) != 0) { + bigwad->upanic.pru_flags |= PRUPANIC_FLAG_MSG_VALID; + bcopy(p->p_upanic, bigwad->upanic.pru_data, + PRUPANIC_BUFLEN); + } + + error = elfnote(vp, &offset, NT_UPANIC, sizeof (prupanic_t), + &bigwad->upanic, rlimit, credp); + if (error != 0) { + mutex_exit(&p->p_lock); + goto done; + } + } + mutex_exit(&p->p_lock); + done: kmem_free(bigwad, bigsize); return (error); diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_ring.c b/usr/src/uts/common/io/mlxcx/mlxcx_ring.c index 17a09b9cae..6ce37ef1a0 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_ring.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_ring.c @@ -378,12 +378,14 @@ mlxcx_cq_setup(mlxcx_t *mlxp, mlxcx_event_queue_t *eq, mutex_exit(&cq->mlcq_mtx); mutex_enter(&eq->mleq_mtx); + mutex_enter(&cq->mlcq_arm_mtx); mutex_enter(&cq->mlcq_mtx); ASSERT0(cq->mlcq_state & MLXCX_CQ_EQAVL); avl_add(&eq->mleq_cqs, cq); atomic_or_uint(&cq->mlcq_state, MLXCX_CQ_EQAVL); mlxcx_arm_cq(mlxp, cq); mutex_exit(&cq->mlcq_mtx); + mutex_exit(&cq->mlcq_arm_mtx); mutex_exit(&eq->mleq_mtx); *cqp = cq; diff --git a/usr/src/uts/common/os/exit.c b/usr/src/uts/common/os/exit.c index 06e0117cd6..5563c0f4ab 100644 --- a/usr/src/uts/common/os/exit.c +++ b/usr/src/uts/common/os/exit.c @@ -22,6 +22,7 @@ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2018 Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -71,6 +72,7 @@ #include <sys/pool.h> #include <sys/sdt.h> #include <sys/corectl.h> +#include <sys/core.h> #include <sys/brand.h> #include <sys/libc_kernel.h> @@ -600,6 +602,14 @@ proc_exit(int why, int what) } /* + * If we had generated any upanic(2) state, free that now. + */ + if (p->p_upanic != NULL) { + kmem_free(p->p_upanic, PRUPANIC_BUFLEN); + p->p_upanic = NULL; + } + + /* * Remove any fpollinfo_t's for this (last) thread from our file * descriptors so closeall() can ASSERT() that they're all gone. */ diff --git a/usr/src/uts/common/os/sysent.c b/usr/src/uts/common/os/sysent.c index fb64000e4d..be45b7ad8f 100644 --- a/usr/src/uts/common/os/sysent.c +++ b/usr/src/uts/common/os/sysent.c @@ -25,6 +25,7 @@ * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2016 Joyent, Inc. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -330,6 +331,7 @@ int setsockopt(int, int, int, void *, socklen_t *, int); int sockconfig(int, void *, void *, void *, void *); ssize_t sendfilev(int, int, const struct sendfilevec *, int, size_t *); ssize_t getrandom(void *, size_t, unsigned int); +void upanic(void *, size_t); typedef int64_t (*llfcn_t)(); /* for casting one-word returns */ @@ -583,7 +585,7 @@ struct sysent sysent[NSYSCALL] = /* 122 */ SYSENT_CL("writev", writev, 3), /* 123 */ SYSENT_CL("preadv", preadv, 5), /* 124 */ SYSENT_CL("pwritev", pwritev, 5), - /* 125 */ SYSENT_LOADABLE(), /* (was fxstat) */ + /* 125 */ SYSENT_CI("upanic", upanic, 2), /* 126 */ SYSENT_CL("getrandom", getrandom, 3), /* 127 */ SYSENT_CI("mmapobj", mmapobjsys, 5), /* 128 */ IF_LP64( @@ -948,7 +950,7 @@ struct sysent sysent32[NSYSCALL] = /* 122 */ SYSENT_CI("writev", writev32, 3), /* 123 */ SYSENT_CI("preadv", preadv, 5), /* 124 */ SYSENT_CI("pwritev", pwritev, 5), - /* 125 */ SYSENT_LOADABLE32(), /* was fxstat32 */ + /* 125 */ SYSENT_CI("upanic", upanic, 2), /* 126 */ SYSENT_CI("getrandom", getrandom, 3), /* 127 */ SYSENT_CI("mmapobj", mmapobjsys, 5), /* 128 */ SYSENT_CI("setrlimit", setrlimit32, 2), diff --git a/usr/src/uts/common/os/upanic.c b/usr/src/uts/common/os/upanic.c new file mode 100644 index 0000000000..8acb9440f2 --- /dev/null +++ b/usr/src/uts/common/os/upanic.c @@ -0,0 +1,92 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Oxide Computer Company + */ + +#include <sys/proc.h> +#include <c2/audit.h> +#include <sys/procfs.h> +#include <sys/core.h> + +/* + * This function is meant to be a guaranteed abort that generates a core file + * that allows up to 1k of data to enter into an elfnote in the process. This is + * meant to insure that even in the face of other problems, this can get out. + */ + +void +upanic(void *addr, size_t len) +{ + kthread_t *t = curthread; + proc_t *p = curproc; + klwp_t *lwp = ttolwp(t); + uint32_t auditing = AU_AUDITING(); + uint32_t upflag = P_UPF_PANICKED; + void *buf; + int code; + + /* + * Before we worry about the data that the user has as a message, go + * ahead and make sure we try and get all the other threads stopped. + * That'll help us make sure that nothing else is going on and we don't + * lose a race. + */ + mutex_enter(&p->p_lock); + lwp->lwp_cursig = SIGABRT; + mutex_exit(&p->p_lock); + + proc_is_exiting(p); + if (exitlwps(1) != 0) { + mutex_enter(&p->p_lock); + lwp_exit(); + } + + /* + * Copy in the user data. We truncate it to PRUPANIC_BUFLEN no matter + * what and ensure that the last data was set to zero. + */ + if (addr != NULL && len > 0) { + size_t copylen; + + upflag |= P_UPF_HAVEMSG; + + if (len >= PRUPANIC_BUFLEN) { + copylen = PRUPANIC_BUFLEN; + upflag |= P_UPF_TRUNCMSG; + } else { + copylen = len; + } + + buf = kmem_zalloc(PRUPANIC_BUFLEN, KM_SLEEP); + if (copyin(addr, buf, copylen) != 0) { + upflag |= P_UPF_INVALMSG; + upflag &= ~P_UPF_HAVEMSG; + } else { + mutex_enter(&p->p_lock); + ASSERT3P(p->p_upanic, ==, NULL); + p->p_upanic = buf; + mutex_exit(&p->p_lock); + } + } + + mutex_enter(&p->p_lock); + p->p_upanicflag = upflag; + mutex_exit(&p->p_lock); + + if (auditing) /* audit core dump */ + audit_core_start(SIGABRT); + code = core(SIGABRT, B_FALSE); + if (auditing) /* audit core dump */ + audit_core_finish(code ? CLD_KILLED : CLD_DUMPED); + exit(code ? CLD_KILLED : CLD_DUMPED, SIGABRT); +} diff --git a/usr/src/uts/common/sys/ccompile.h b/usr/src/uts/common/sys/ccompile.h index de0031d6b0..e687fd99a3 100644 --- a/usr/src/uts/common/sys/ccompile.h +++ b/usr/src/uts/common/sys/ccompile.h @@ -160,6 +160,7 @@ extern "C" { #define __unused __sun_attr__((__unused__)) #define __used __attribute__((__used__)) #define __weak_symbol __attribute__((__weak__)) +#define __HIDDEN __attribute__((visibility("hidden"))) #ifdef __cplusplus } diff --git a/usr/src/uts/common/sys/elf.h b/usr/src/uts/common/sys/elf.h index 1a2ca397ef..384c6daf99 100644 --- a/usr/src/uts/common/sys/elf.h +++ b/usr/src/uts/common/sys/elf.h @@ -21,6 +21,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. @@ -1018,7 +1019,8 @@ typedef Elf64_Word Elf64_Capchain; #define NT_SPYMASTER 23 /* psinfo_t for agent LWP spymaster */ #define NT_SECFLAGS 24 /* process security-flags */ #define NT_LWPNAME 25 /* prlwpname_t */ -#define NT_NUM 25 +#define NT_UPANIC 26 /* prupanic_t */ +#define NT_NUM 26 #ifdef _KERNEL diff --git a/usr/src/uts/common/sys/proc.h b/usr/src/uts/common/sys/proc.h index 757bbc87e7..bb6f62f83f 100644 --- a/usr/src/uts/common/sys/proc.h +++ b/usr/src/uts/common/sys/proc.h @@ -22,6 +22,7 @@ /* * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2018 Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -355,6 +356,8 @@ typedef struct proc { kcondvar_t p_poolcv; /* synchronization with pools */ uint_t p_poolcnt; /* # threads inside pool barrier */ uint_t p_poolflag; /* pool-related flags (see below) */ + uint_t p_upanicflag; /* upanic-related flags (see below) */ + void *p_upanic; /* optional upanic data */ uintptr_t p_portcnt; /* event ports counter */ struct zone *p_zone; /* zone in which process lives */ struct vnode *p_execdir; /* directory that p_exec came from */ @@ -524,6 +527,14 @@ extern struct pid pid0; /* p0's pid */ #define PBWAIT 0x0001 /* process should wait outside fork/exec/exit */ #define PEXITED 0x0002 /* process exited and about to become zombie */ +/* + * p_upanicflag codes + */ +#define P_UPF_PANICKED 0x0001 +#define P_UPF_HAVEMSG 0x0002 +#define P_UPF_TRUNCMSG 0x0004 +#define P_UPF_INVALMSG 0x0008 + /* Macro to convert proc pointer to a user block pointer */ #define PTOU(p) (&(p)->p_user) diff --git a/usr/src/uts/common/sys/procfs.h b/usr/src/uts/common/sys/procfs.h index 517f2551b4..3d6760a7b4 100644 --- a/usr/src/uts/common/sys/procfs.h +++ b/usr/src/uts/common/sys/procfs.h @@ -678,6 +678,21 @@ typedef struct prheader { (((unsigned)((flag)-1) < 32*sizeof (*(sp))/sizeof (uint32_t)) && \ (((uint32_t *)(sp))[((flag)-1)/32] & (1U<<(((flag)-1)%32)))) +/* + * Core file upanic NT_UPANIC structure. + */ +#define PRUPANIC_VERSION_1 1 +#define PRUPANIC_VERSION_CURRENT PRUPANIC_VERSION_1 +#define PRUPANIC_FLAG_MSG_VALID 0x01 +#define PRUPANIC_FLAG_MSG_ERROR 0x02 +#define PRUPANIC_FLAG_MSG_TRUNC 0x04 +#define PRUPANIC_BUFLEN 1024 +typedef struct prupanic { + uint32_t pru_version; + uint32_t pru_flags; + uint8_t pru_data[PRUPANIC_BUFLEN]; +} prupanic_t; + #if defined(_SYSCALL32) /* diff --git a/usr/src/uts/common/sys/syscall.h b/usr/src/uts/common/sys/syscall.h index 8709f98c26..cd4f5445b0 100644 --- a/usr/src/uts/common/sys/syscall.h +++ b/usr/src/uts/common/sys/syscall.h @@ -24,6 +24,7 @@ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2015, Joyent, Inc. All rights reserved. + * Copyright 2020 Oxide Computer Company */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -168,38 +169,38 @@ extern "C" { #define SYS_tasksys 70 /* * subcodes: - * settaskid(...) :: tasksys(0, ...) - * gettaskid(...) :: tasksys(1, ...) - * getprojid(...) :: tasksys(2, ...) + * settaskid(...) :: tasksys(0, ...) + * gettaskid(...) :: tasksys(1, ...) + * getprojid(...) :: tasksys(2, ...) */ #define SYS_acctctl 71 #define SYS_exacctsys 72 /* * subcodes: - * getacct(...) :: exacct(0, ...) - * putacct(...) :: exacct(1, ...) - * wracct(...) :: exacct(2, ...) + * getacct(...) :: exacct(0, ...) + * putacct(...) :: exacct(1, ...) + * wracct(...) :: exacct(2, ...) */ #define SYS_getpagesizes 73 /* * subcodes: * getpagesizes2(...) :: getpagesizes(0, ...) - * getpagesizes(...) :: getpagesizes(1, ...) legacy + * getpagesizes(...) :: getpagesizes(1, ...) legacy */ #define SYS_rctlsys 74 /* * subcodes: - * getrctl(...) :: rctlsys(0, ...) - * setrctl(...) :: rctlsys(1, ...) - * rctllist(...) :: rctlsys(2, ...) - * rctlctl(...) :: rctlsys(3, ...) + * getrctl(...) :: rctlsys(0, ...) + * setrctl(...) :: rctlsys(1, ...) + * rctllist(...) :: rctlsys(2, ...) + * rctlctl(...) :: rctlsys(3, ...) */ #define SYS_sidsys 75 /* * subcodes: - * allocids(...) :: sidsys(0, ...) - * idmap_reg(...) :: sidsys(1, ...) - * idmap_unreg(...) :: sidsys(2, ...) + * allocids(...) :: sidsys(0, ...) + * idmap_reg(...) :: sidsys(1, ...) + * idmap_unreg(...) :: sidsys(2, ...) */ #define SYS_lwp_park 77 /* @@ -213,8 +214,8 @@ extern "C" { #define SYS_sendfilev 78 /* * subcodes : - * sendfilev() :: sendfilev(0, ...) - * sendfilev64() :: sendfilev(1, ...) + * sendfilev() :: sendfilev(0, ...) + * sendfilev64() :: sendfilev(1, ...) */ #define SYS_rmdir 79 #define SYS_mkdir 80 @@ -222,11 +223,11 @@ extern "C" { #define SYS_privsys 82 /* * subcodes: - * setppriv(...) :: privsys(0, ...) - * getppriv(...) :: privsys(1, ...) - * getimplinfo(...) :: privsys(2, ...) - * setpflags(...) :: privsys(3, ...) - * getpflags(...) :: privsys(4, ...) + * setppriv(...) :: privsys(0, ...) + * getppriv(...) :: privsys(1, ...) + * getimplinfo(...) :: privsys(2, ...) + * setpflags(...) :: privsys(3, ...) + * getpflags(...) :: privsys(4, ...) * issetugid(); :: privsys(5) */ #define SYS_ucredsys 83 @@ -297,6 +298,7 @@ extern "C" { #define SYS_writev 122 #define SYS_preadv 123 #define SYS_pwritev 124 +#define SYS_upanic 125 #define SYS_getrandom 126 #define SYS_mmapobj 127 #define SYS_setrlimit 128 @@ -368,7 +370,7 @@ extern "C" { #define SYS_meminfosys SYS_lgrpsys /* * subcodes: - * meminfo(...) :: meminfosys(MISYS_MEMINFO, ...) + * meminfo(...) :: meminfosys(MISYS_MEMINFO, ...) */ #define SYS_rusagesys 181 /* |