diff options
92 files changed, 1945 insertions, 616 deletions
@@ -5399,6 +5399,7 @@ f usr/lib/amd64/libsoftcrypto.so.1 0755 root bin s usr/lib/amd64/libsoftcrypto.so=libsoftcrypto.so.1 f usr/lib/amd64/libsrpt.so.1 0755 root bin s usr/lib/amd64/libsrpt.so=libsrpt.so.1 +f usr/lib/amd64/libssp_ns.a 0755 root bin f usr/lib/amd64/libstmf.so.1 0755 root bin s usr/lib/amd64/libstmf.so=libstmf.so.1 f usr/lib/amd64/libstmfproxy.so.1 0755 root bin @@ -6928,6 +6929,7 @@ f usr/lib/libsoftcrypto.so.1 0755 root bin s usr/lib/libsoftcrypto.so=libsoftcrypto.so.1 f usr/lib/libsrpt.so.1 0755 root bin s usr/lib/libsrpt.so=libsrpt.so.1 +f usr/lib/libssp_ns.a 0755 root bin f usr/lib/libstmf.so.1 0755 root bin s usr/lib/libstmf.so=libstmf.so.1 f usr/lib/libstmfproxy.so.1 0755 root bin @@ -12967,6 +12969,7 @@ s usr/share/man/man2/umount2.2=umount.2 f usr/share/man/man2/uname.2 0444 root bin f usr/share/man/man2/unlink.2 0444 root bin s usr/share/man/man2/unlinkat.2=unlink.2 +f usr/share/man/man2/upanic.2 0444 root bin f usr/share/man/man2/ustat.2 0444 root bin f usr/share/man/man2/utime.2 0444 root bin s usr/share/man/man2/utimensat.2=utimes.2 @@ -16103,6 +16106,7 @@ s usr/share/man/man3head/un.3head=un.h.3head f usr/share/man/man3head/un.h.3head 0444 root bin s usr/share/man/man3head/unistd.3head=unistd.h.3head f usr/share/man/man3head/unistd.h.3head 0444 root bin +f usr/share/man/man3head/upanic.h.3head 0444 root bin s usr/share/man/man3head/utime.3head=utime.h.3head f usr/share/man/man3head/utime.h.3head 0444 root bin s usr/share/man/man3head/utmpx.3head=utmpx.h.3head @@ -17618,6 +17622,8 @@ f usr/share/man/man3proc/Psysentry.3proc 0444 root bin s usr/share/man/man3proc/Psysexit.3proc=Psysentry.3proc f usr/share/man/man3proc/Puname.3proc 0444 root bin s usr/share/man/man3proc/Punsetflags.3proc=Psetflags.3proc +f usr/share/man/man3proc/Pupanic.3proc 0444 root bin +s usr/share/man/man3proc/Pupanic_free.3proc=Pupanic.3proc f usr/share/man/man3proc/Pupdate_maps.3proc 0444 root bin f usr/share/man/man3proc/Pupdate_syms.3proc 0444 root bin s usr/share/man/man3proc/Pwait.3proc=Pstopstatus.3proc diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master index b58eee10d5..ff35235c81 100644 --- a/usr/src/Makefile.master +++ b/usr/src/Makefile.master @@ -411,6 +411,45 @@ CCNOAGGRESSIVELOOPS= \ -_gcc8=-fno-aggressive-loop-optimizations \ -_gcc9=-fno-aggressive-loop-optimizations +# +# Options to control which version of stack-protector we enable. This +# gives us a bit of flexibility and is unfortunately necessary as some +# modules do not function correctly with our defaults (qede). +# +# o STACKPROTECT_ Sets the appropriate version for the compiler +# o STACKPROTECT_strong Sets us to use strong on all of the +# compilers it supports. This is the same +# as the default. +# +# o STACKPROTECT_none Disables the stack protector. +# +# o STACKPROTECT_all Enables it for everything. +# +# o STACKPROTECT_basic Enables the basic stack protector. +# +# -fstack-protector-strong is not available in gcc4 which is why we +# have per-compiler versions below. These are not added to the default +# global CFLAGS at this time as it's being incrementally enabled +# throughout the build. +# +STACKPROTECT_ = -_gcc4=-fstack-protector +STACKPROTECT_ += -_gcc7=-fstack-protector-strong +STACKPROTECT_ += -_gcc8=-fstack-protector-strong +STACKPROTECT_ += -_gcc9=-fstack-protector-strong + +STACKPROTECT_strong = $(STACKPROTECT_) +STACKPROTECT_none = +STACKPROTECT_all = -_gcc=-fstack-protector-all +STACKPROTECT_basic = -_gcc=-fstack-protector + +STACKPROTECT_LD_ = -lssp_ns +STACKPROTECT_LD_none = +STACKRPTOECT_LD_all = $(STACKRPOTECT_LD_) +STACKRPTOECT_LD_basic = $(STACKRPOTECT_LD_) + +CCSTACKPROTECT= $(STACKPROTECT_$(STACKPROTECT)) +LDSTACKPROTECT= $(STACKPROTECT_LD_$(STACKPROTECT)) + # One optimization the compiler might perform is to turn this: # #pragma weak foo # extern int foo; diff --git a/usr/src/cmd/Makefile.cmd b/usr/src/cmd/Makefile.cmd index b16a7532b2..b616d6a7ac 100644 --- a/usr/src/cmd/Makefile.cmd +++ b/usr/src/cmd/Makefile.cmd @@ -115,7 +115,13 @@ ROOTAUDIOSAMPAU=$(ROOTAUDIOSAMP)/au ISAEXEC= $(ROOT)/usr/lib/isaexec PLATEXEC= $(ROOT)/usr/lib/platexec -LDLIBS = $(LDLIBS.cmd) +# +# Enable the stack protector by default. +# +CFLAGS += $(CCSTACKPROTECT) +CFLAGS64 += $(CCSTACKPROTECT) + +LDLIBS = $(LDLIBS.cmd) $(LDSTACKPROTECT) LDFLAGS.cmd = \ $(BDIRECT) $(ENVLDFLAGS1) $(ENVLDFLAGS2) $(ENVLDFLAGS3) \ diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/Makefile b/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/Makefile index d577640c90..1f7c9b1ef7 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/Makefile +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/Makefile @@ -26,7 +26,7 @@ # MINCONN = minconn.so -PASSPROMPT = passprompt.so +PASSPROMPT = passprompt.so PPPOE = pppoe.so LIBRARIES = minconn.so passprompt.so pppoe.so @@ -52,11 +52,8 @@ $(MINCONN):= MAPFILES = mapfile-minconn $(PASSPROMPT):= MAPFILES = mapfile-passprompt $(PPPOE):= MAPFILES = mapfile-pppoe -# A bug in pmake causes redundancy when '+=' is conditionally assigned, so -# '=' is used with extra variables. -XXXLDLIBS = -$(PASSPROMPT):= XXXLDLIBS = -lc -LDLIBS += $(XXXLDLIBS) +$(PASSPROMPT):= LDLIBS += -lc +$(PPPOE):= LDLIBS += -lc CPPFLAGS += -I.. -I$(SRC)/uts/common # XX64 -- this should not be needed -- fix me diff --git a/usr/src/cmd/lp/cmd/Makefile b/usr/src/cmd/lp/cmd/Makefile index 1d31e19262..21fef0076b 100644 --- a/usr/src/cmd/lp/cmd/Makefile +++ b/usr/src/cmd/lp/cmd/Makefile @@ -54,11 +54,12 @@ LDFLAGS += $(MAPFILE.NGB:%=-Wl,-M%) # conditional assignments # lpfilter:= LDLIBS += $(LIBFLT) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \ - -lgen -lsecdb + -lgen -lsecdb $(LDSTACKPROTECT) lpforms:= LDLIBS += $(LIBFRM) $(LIBMSG) $(LIBREQ) $(LIBOAM) \ - $(LIBACC) $(LIBLP) -lsecdb -lpshut:= LDLIBS += $(LIBMSG) $(LIBOAM) $(LIBLP) -lpusers:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBUSR) $(LIBLP) + $(LIBACC) $(LIBLP) -lsecdb $(LDSTACKPROTECT) +lpshut:= LDLIBS += $(LIBMSG) $(LIBOAM) $(LIBLP) $(LDSTACKPROTECT) +lpusers:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBUSR) $(LIBLP) \ + $(LDSTACKPROTECT) .KEEP_STATE: diff --git a/usr/src/cmd/lp/cmd/lpadmin/Makefile b/usr/src/cmd/lp/cmd/lpadmin/Makefile index 4e2333ce29..ca2753b1e2 100644 --- a/usr/src/cmd/lp/cmd/lpadmin/Makefile +++ b/usr/src/cmd/lp/cmd/lpadmin/Makefile @@ -62,7 +62,7 @@ LPLIBS= $(LIBACC) \ SYSLIBS= -lcurses -LDLIBS += -lsecdb $(LPLIBS) $(SYSLIBS) $(I18N) +LDLIBS += -lsecdb $(LPLIBS) $(SYSLIBS) $(I18N) $(LDSTACKPROTECT) LDFLAGS += $(MAPFILE.NGB:%=-Wl,-M%) PROG= lpadmin diff --git a/usr/src/cmd/lp/cmd/lpsched/Makefile b/usr/src/cmd/lp/cmd/lpsched/Makefile index c5c645ffe8..42628a4b9d 100644 --- a/usr/src/cmd/lp/cmd/lpsched/Makefile +++ b/usr/src/cmd/lp/cmd/lpsched/Makefile @@ -22,8 +22,6 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # cmd/lp/cmd/lpsched/lpsched/Makefile # @@ -102,13 +100,13 @@ LPLIBS = \ SYSLIBS= -lcurses -lgen -lcurses -lnsl -ltsol -lsecdb -lbsm -LDLIBS += $(LPLIBS) $(SYSLIBS) +LDLIBS += $(LPLIBS) $(SYSLIBS) $(LDSTACKPROTECT) POFILE= lp_cmd_lpsched.po .KEEP_STATE: -all: $(PROG) +all: $(PROG) $(PROG): $(OBJS) $(LPLIBS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) diff --git a/usr/src/cmd/lp/model/Makefile b/usr/src/cmd/lp/model/Makefile index 5da2ee6539..40840ecee0 100644 --- a/usr/src/cmd/lp/model/Makefile +++ b/usr/src/cmd/lp/model/Makefile @@ -19,8 +19,6 @@ # CDDL HEADER END # # -# ident "%Z%%M% %I% %E% SMI" -# # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -62,8 +60,8 @@ ROOTMODELS = $(MODELS:%=$(ROOTLIBLPMODEL)/%) CPPFLAGS = -I$(LPINC) $(CPPFLAGS.master) # conditional assignments -lp.tell := LDLIBS += $(LIBMSG) $(LIBLP) -lp.set drain.output lp.cat := LDLIBS += $(LIBLP) -lcurses +lp.tell := LDLIBS += $(LIBMSG) $(LIBLP) $(LDSTACKPROTECT) +lp.set drain.output lp.cat := LDLIBS += $(LIBLP) -lcurses $(LDSTACKPROTECT) lp.tsol_separator := LDLIBS += -ltsol $(ROOTMISC) := FILEMODE = 0444 diff --git a/usr/src/cmd/mdb/Makefile.kmdb b/usr/src/cmd/mdb/Makefile.kmdb index be670d3fc6..0bbeaf5200 100644 --- a/usr/src/cmd/mdb/Makefile.kmdb +++ b/usr/src/cmd/mdb/Makefile.kmdb @@ -58,6 +58,11 @@ CFLAGS64 += $(STAND_FLAGS_64) ASFLAGS += -P -D_ASM $(INCDIRS:%=-I%) $(ARCHOPTS) +# +# kmdb has bootstrapping challenges with the stack protector. +# +STACKPROTECT = none + SUBDIR64_sparc = sparcv9 SUBDIR64_i386 = amd64 SUBDIR64 = $(SUBDIR64_$(MACH)) diff --git a/usr/src/cmd/mdb/Makefile.libstand b/usr/src/cmd/mdb/Makefile.libstand index 9668bbaafb..279194a6ef 100644 --- a/usr/src/cmd/mdb/Makefile.libstand +++ b/usr/src/cmd/mdb/Makefile.libstand @@ -66,6 +66,12 @@ $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG CPPFLAGS = $(INCDIRS:%=-I%) -D_KMDB # +# We cannot currently use the stack protector in kmdb's standalone +# environment. +# +STACKPROTECT = none + +# # kmdb is a kernel module, so we'll use the kernel's build flags. CFLAGS64 += $(STAND_FLAGS_64) diff --git a/usr/src/cmd/mdb/Makefile.libstandctf b/usr/src/cmd/mdb/Makefile.libstandctf index 11e77bafcc..bab6231894 100644 --- a/usr/src/cmd/mdb/Makefile.libstandctf +++ b/usr/src/cmd/mdb/Makefile.libstandctf @@ -51,6 +51,12 @@ CSTD = $(CSTD_GNU99) C99LMODE = -Xc99=%all # +# We cannot currently use the stack protector in the kmdb standalone +# environment. +# +STACKPROTECT = none + +# # kmdb is a kernel module, so we'll use the kernel's build flags. CFLAGS64 += $(STAND_FLAGS_64) diff --git a/usr/src/cmd/mdb/Makefile.module b/usr/src/cmd/mdb/Makefile.module index a6305b8ddf..86a9156e18 100644 --- a/usr/src/cmd/mdb/Makefile.module +++ b/usr/src/cmd/mdb/Makefile.module @@ -127,6 +127,7 @@ $(MODOBJS) := CFLAGS64 += $(C_BIGPICFLAGS) $(XREGSFLAG) $(KMODOBJS) := CPPFLAGS += -D_KMDB $(KMODOBJS) := V9CODESIZE = $(CCABS32) $(KMODOBJS) := DTS_ERRNO = +$(KMODFILE) := STACKPROTECT = none # Modules aren't allowed to export symbols MAPFILE = $(SRC)/cmd/mdb/common/modules/conf/mapfile diff --git a/usr/src/cmd/mdb/common/mdb/mdb_proc.c b/usr/src/cmd/mdb/common/mdb/mdb_proc.c index af4a6eac23..5169cfb6a5 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_proc.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_proc.c @@ -26,6 +26,7 @@ /* * Copyright 2018 Joyent, Inc. * Copyright (c) 2014 by Delphix. All rights reserved. + * Copyright 2020 Oxide Computer Company */ /* @@ -103,6 +104,7 @@ #include <stdio_ext.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #define PC_FAKE -1UL /* illegal pc value unequal 0 */ #define PANIC_BUFSIZE 1024 @@ -1574,6 +1576,38 @@ pt_print_reason(const lwpstatus_t *psp) } } +static void +pt_status_dcmd_upanic(prupanic_t *pru) +{ + size_t i; + + mdb_printf("process panicked\n"); + if ((pru->pru_flags & PRUPANIC_FLAG_MSG_ERROR) != 0) { + mdb_printf("warning: process upanic message was bad\n"); + return; + } + + if ((pru->pru_flags & PRUPANIC_FLAG_MSG_VALID) == 0) + return; + + if ((pru->pru_flags & PRUPANIC_FLAG_MSG_TRUNC) != 0) { + mdb_printf("warning: process upanic message truncated\n"); + } + + mdb_printf("upanic message: "); + + for (i = 0; i < PRUPANIC_BUFLEN; i++) { + if (pru->pru_data[i] == '\0') + break; + if (isascii(pru->pru_data[i]) && isprint(pru->pru_data[i])) { + mdb_printf("%c", pru->pru_data[i]); + } else { + mdb_printf("\\x%02x", pru->pru_data[i]); + } + } + mdb_printf("\n"); +} + /*ARGSUSED*/ static int pt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) @@ -1591,6 +1625,7 @@ pt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) uintptr_t panicstr; char *panicbuf = mdb_alloc(PANIC_BUFSIZE, UM_SLEEP); const siginfo_t *sip = &(psp->pr_lwp.pr_info); + prupanic_t *pru = NULL; char execname[MAXPATHLEN], buf[BUFSIZ]; char signame[SIG2STR_MAX + 4]; /* enough for SIG+name+\0 */ @@ -1696,12 +1731,19 @@ pt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) case PS_DEAD: if (cursig == 0 && WIFSIGNALED(pi.pr_wstat)) cursig = WTERMSIG(pi.pr_wstat); + + (void) Pupanic(P, &pru); + /* - * We can only use pr_wstat == 0 as a test for gcore if - * an NT_PRCRED note is present; these features were - * added at the same time in Solaris 8. + * Test for upanic first. We can only use pr_wstat == 0 + * as a test for gcore if an NT_PRCRED note is present; + * these features were added at the same time in Solaris + * 8. */ - if (pi.pr_wstat == 0 && Pstate(P) == PS_DEAD && + if (pru != NULL) { + pt_status_dcmd_upanic(pru); + Pupanic_free(pru); + } else if (pi.pr_wstat == 0 && Pstate(P) == PS_DEAD && Pcred(P, &cred, 1) == 0) { mdb_printf("process core file generated " "with gcore(1)\n"); @@ -1747,11 +1789,10 @@ pt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) sym.st_value) == sizeof (panicstr) && Pread_string(t->t_pshandle, panicbuf, PANIC_BUFSIZE, panicstr) > 0) { - mdb_printf("panic message: %s", + mdb_printf("libc panic message: %s", panicbuf); } - break; case PS_IDLE: @@ -4681,27 +4722,27 @@ pt_auxv(mdb_tgt_t *t, const auxv_t **auxvp) static const mdb_tgt_ops_t proc_ops = { pt_setflags, /* t_setflags */ - (int (*)())(uintptr_t) mdb_tgt_notsup, /* t_setcontext */ + (int (*)())(uintptr_t)mdb_tgt_notsup, /* t_setcontext */ pt_activate, /* t_activate */ pt_deactivate, /* t_deactivate */ pt_periodic, /* t_periodic */ pt_destroy, /* t_destroy */ pt_name, /* t_name */ - (const char *(*)()) mdb_conf_isa, /* t_isa */ + (const char *(*)())mdb_conf_isa, /* t_isa */ pt_platform, /* t_platform */ pt_uname, /* t_uname */ pt_dmodel, /* t_dmodel */ - (ssize_t (*)()) mdb_tgt_notsup, /* t_aread */ - (ssize_t (*)()) mdb_tgt_notsup, /* t_awrite */ + (ssize_t (*)())mdb_tgt_notsup, /* t_aread */ + (ssize_t (*)())mdb_tgt_notsup, /* t_awrite */ pt_vread, /* t_vread */ pt_vwrite, /* t_vwrite */ - (ssize_t (*)()) mdb_tgt_notsup, /* t_pread */ - (ssize_t (*)()) mdb_tgt_notsup, /* t_pwrite */ + (ssize_t (*)())mdb_tgt_notsup, /* t_pread */ + (ssize_t (*)())mdb_tgt_notsup, /* t_pwrite */ pt_fread, /* t_fread */ pt_fwrite, /* t_fwrite */ - (ssize_t (*)()) mdb_tgt_notsup, /* t_ioread */ - (ssize_t (*)()) mdb_tgt_notsup, /* t_iowrite */ - (int (*)())(uintptr_t) mdb_tgt_notsup, /* t_vtop */ + (ssize_t (*)())mdb_tgt_notsup, /* t_ioread */ + (ssize_t (*)())mdb_tgt_notsup, /* t_iowrite */ + (int (*)())(uintptr_t)mdb_tgt_notsup, /* t_vtop */ pt_lookup_by_name, /* t_lookup_by_name */ pt_lookup_by_addr, /* t_lookup_by_addr */ pt_symbol_iter, /* t_symbol_iter */ @@ -4720,9 +4761,9 @@ static const mdb_tgt_ops_t proc_ops = { pt_signal, /* t_signal */ pt_add_vbrkpt, /* t_add_vbrkpt */ pt_add_sbrkpt, /* t_add_sbrkpt */ - (int (*)())(uintptr_t) mdb_tgt_null, /* t_add_pwapt */ + (int (*)())(uintptr_t)mdb_tgt_null, /* t_add_pwapt */ pt_add_vwapt, /* t_add_vwapt */ - (int (*)())(uintptr_t) mdb_tgt_null, /* t_add_iowapt */ + (int (*)())(uintptr_t)mdb_tgt_null, /* t_add_iowapt */ pt_add_sysenter, /* t_add_sysenter */ pt_add_sysexit, /* t_add_sysexit */ pt_add_signal, /* t_add_signal */ @@ -4848,8 +4889,8 @@ pt_lwp_setfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, } static const pt_ptl_ops_t proc_lwp_ops = { - (int (*)())(uintptr_t) mdb_tgt_nop, - (void (*)())(uintptr_t) mdb_tgt_nop, + (int (*)())(uintptr_t)mdb_tgt_nop, + (void (*)())(uintptr_t)mdb_tgt_nop, pt_lwp_tid, pt_lwp_iter, pt_lwp_getregs, diff --git a/usr/src/cmd/picl/plugins/common/piclevent/Makefile b/usr/src/cmd/picl/plugins/common/piclevent/Makefile index 1b0ad54ea2..c1e4c4702a 100644 --- a/usr/src/cmd/picl/plugins/common/piclevent/Makefile +++ b/usr/src/cmd/picl/plugins/common/piclevent/Makefile @@ -36,7 +36,7 @@ include $(SRC)/cmd/picl/plugins/Makefile.com MODULES = picl_slm.so MOD_SRCS = picl_slm.c MOD_OBJS = picl_slm.o -MOD_LDLIBS = -L$(ROOT)/usr/lib -lsysevent -lnvpair -lc +MOD_LDLIBS = -L$(ROOT)/usr/lib -lsysevent -lnvpair -lc $(LDSTACKPROTECT) # sysevent SLM dirs SYSEVENT = sysevent diff --git a/usr/src/cmd/print/bsd-sysv-commands/Makefile b/usr/src/cmd/print/bsd-sysv-commands/Makefile index f2b8c41230..2821e90db8 100644 --- a/usr/src/cmd/print/bsd-sysv-commands/Makefile +++ b/usr/src/cmd/print/bsd-sysv-commands/Makefile @@ -60,7 +60,7 @@ CPPFLAGS += -I. CPPFLAGS += -I../../../lib/print/libpapi-common/common CPPFLAGS += -I$(ROOT)/usr/include CPPFLAGS += -I../../lp/include -LDLIBS += $(LIBLP) -lpapi -lc +LDLIBS += $(LIBLP) $(LDSTACKPROTECT) -lpapi -lc in.lpd:= CFLAGS += -DSOLARIS_PRIVATE_POST_0_9 in.lpd:= LDLIBS += -lnsl -lsocket @@ -85,14 +85,14 @@ $(ROOTUSRUCB)/%: $(ROOTUSRUCB) % $(ROOTLIBLPBIN)/%: % $(INS.file) -$(ROOTUCBSYMLINKS): +$(ROOTUCBSYMLINKS): $(RM) $@; $(SYMLINK) ../bin/$(@F) $@ # usr/lib links ROOTUSRLIBSYMLINKS = $(SBINPROGS:%=$(ROOTLIB)/%) $(ROOTLIB)/%: $(ROOTLIB) % -$(ROOTUSRLIBSYMLINKS): +$(ROOTUSRLIBSYMLINKS): $(RM) $@; $(SYMLINK) ../sbin/$(@F) $@ .KEEP_STATE: @@ -104,7 +104,7 @@ install: $(ROOTLIBLPPROGS) \ check: $(CHKMANIFEST) clean: - $(RM) $(OBJS) + $(RM) $(OBJS) CLOBBERFILES += $(BINPROGS) $(SBINPROGS) $(LIBPRINTPROGS) diff --git a/usr/src/cmd/rcm_daemon/Makefile.com b/usr/src/cmd/rcm_daemon/Makefile.com index a11c03bc4b..8267af63fc 100644 --- a/usr/src/cmd/rcm_daemon/Makefile.com +++ b/usr/src/cmd/rcm_daemon/Makefile.com @@ -135,7 +135,7 @@ SUNW_ip_rcm.so := LDLIBS_MODULES += -linetutil -ldladm -lipmp -lipadm -lnvpair - SUNW_ip_anon_rcm.so := LDLIBS_MODULES += -linetutil SUNW_bridge_rcm.so := LDLIBS_MODULES += -ldladm -lnvpair SUNW_mpxio_rcm.so := LDLIBS_MODULES += -ldevinfo -LDLIBS_MODULES += -lrcm -lc +LDLIBS_MODULES += -lrcm -lc $(LDSTACKPROTECT) LDLIBS += -lrcm -lnvpair diff --git a/usr/src/cmd/sgs/elfdump/common/corenote.c b/usr/src/cmd/sgs/elfdump/common/corenote.c index a5ba4e31b8..7b768a0309 100644 --- a/usr/src/cmd/sgs/elfdump/common/corenote.c +++ b/usr/src/cmd/sgs/elfdump/common/corenote.c @@ -26,6 +26,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ #include <stdlib.h> @@ -39,6 +40,8 @@ #include <_elfdump.h> #include <struct_layout.h> #include <conv.h> +#include <ctype.h> +#include <sys/sysmacros.h> /* @@ -94,7 +97,6 @@ print_strbuf(state, _title, &layout->_field) - /* * Structure used to maintain state data for a core note, or a subregion * (sub-struct) of a core note. These values would otherwise need to be @@ -136,26 +138,59 @@ typedef void (* dump_func_t)(note_state_t *state, const char *title); static const char * safe_str(const char *str, size_t n) { - static char buf[512]; - char *s; - size_t i; + static char buf[2048]; + size_t i, used; if (n == 0) return (MSG_ORIG(MSG_STR_EMPTY)); - for (i = 0; i < n; i++) + /* + * If the string is terminated and doesn't need escaping, we can return + * it as is. + */ + for (i = 0; i < n; i++) { if (str[i] == '\0') return (str); - i = (n >= sizeof (buf)) ? (sizeof (buf) - 4) : (n - 1); - (void) memcpy(buf, str, i); - s = buf + i; - if (n >= sizeof (buf)) { - *s++ = '.'; - *s++ = '.'; - *s++ = '.'; + if (!isascii(str[i]) || !isprint(str[i])) { + break; + } } - *s = '\0'; + + for (i = 0, used = 0; i < n; i++) { + if (str[i] == '\0') { + if (used + 1 > sizeof (buf)) + break; + buf[used++] = str[i]; + return (buf); + } else if (isascii(str[i]) && isprint(str[i])) { + if (used + 1 > sizeof (buf)) + break; + buf[used++] = str[i]; + } else { + size_t len = snprintf(NULL, 0, "\\x%02x", str[i]); + if (used + len > sizeof (buf)) + break; + (void) snprintf(buf + used, sizeof (buf) - used, + "\\x%02x", str[i]); + used += len; + } + } + + if (i == n && used < sizeof (buf)) { + buf[used] = '\0'; + return (buf); + } + + /* + * If we got here, we would have overflowed. Figure out where we need to + * start and truncate. + */ + used = MIN(used, sizeof (buf) - 4); + buf[used++] = '.'; + buf[used++] = '.'; + buf[used++] = '.'; + buf[used++] = '\0'; return (buf); } @@ -198,7 +233,7 @@ data_present(note_state_t *state, const sl_field_t *fdesc) /* * indent_enter/exit are used to start/end output for a subitem. * On entry, a title is output, and the indentation level is raised - * by one unit. On exit, the indentation level is restrored to its + * by one unit. On exit, the indentation level is restored to its * previous value. */ static void @@ -1759,6 +1794,40 @@ dump_asrset(note_state_t *state, const char *title) indent_exit(state); } +static void +dump_upanic(note_state_t *state, const char *title) +{ + const sl_prupanic_layout_t *layout = state->ns_arch->prupanic; + Conv_upanic_buf_t inv; + Word w; + + indent_enter(state, title, &layout->pru_version); + w = extract_as_word(state, &layout->pru_version); + if (w != PRUPANIC_VERSION_1) { + PRINT_DEC(MSG_INTL(MSG_NOTE_BAD_UPANIC_VER), pru_version); + dump_hex_bytes(state->ns_data, state->ns_len, state->ns_indent, + 4, 3); + } else { + PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PRU_VERSION), pru_version); + w = extract_as_word(state, &layout->pru_flags); + print_str(state, MSG_ORIG(MSG_CNOTE_T_PRU_FLAGS), + conv_prupanic(w, 0, &inv)); + + if ((w & PRUPANIC_FLAG_MSG_VALID) != 0) { + /* + * We have a message that is _probably_ a text string, + * but the interface allows for arbitrary data. The only + * guarantee is that someone using this is probably up + * to no good. As a result, we basically try to print + * this as a string, but in the face of certain types of + * data, we hex escape it. + */ + print_strbuf(state, MSG_ORIG(MSG_CNOTE_T_PRU_DATA), + &layout->pru_data); + } + } +} + corenote_ret_t corenote(Half mach, int do_swap, Word type, const char *desc, Word descsz) @@ -1928,6 +1997,11 @@ corenote(Half mach, int do_swap, Word type, state.ns_vcol = 20; dump_lwpname(&state, MSG_ORIG(MSG_CNOTE_DESC_PRLWPNAME_T)); return (CORENOTE_R_OK); + + case NT_UPANIC: + state.ns_vcol = 23; + dump_upanic(&state, MSG_ORIG(MSG_CNOTE_DESC_PRUPANIC_T)); + return (CORENOTE_R_OK); } return (CORENOTE_R_BADTYPE); diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg index 20fe3ceb02..239a1f77ac 100644 --- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg @@ -314,6 +314,7 @@ @ MSG_NOTE_BADCORETYPE "%s: unknown note type %#x\n" @ MSG_NOTE_BAD_SECFLAGS_VER "unknown prsecflags_t version: " +@ MSG_NOTE_BAD_UPANIC_VER "unknown prupanic_t version: " @ _END_ @@ -472,6 +473,7 @@ @ MSG_CNOTE_DESC_PRFDINFO_T "desc: (prfdinfo_core_t)" @ MSG_CNOTE_DESC_PRSECFLAGS_T "desc: (prsecflags_t)" @ MSG_CNOTE_DESC_PRLWPNAME_T "desc: (prlwpname_t)" +@ MSG_CNOTE_DESC_PRUPANIC_T "desc: (prupanic_t)" @ MSG_CNOTE_FMT_LINE "%*s%-*s%s" @ MSG_CNOTE_FMT_LINE_2UP "%*s%-*s%-*s%-*s%s" @@ -646,6 +648,9 @@ @ MSG_CNOTE_T_PR_INO "pr_ino:" @ MSG_CNOTE_T_PR_FILEFLAGS "pr_fileflags:" @ MSG_CNOTE_T_PR_FDFLAGS "pr_fdflags:" +@ MSG_CNOTE_T_PRU_VERSION "pru_version:" +@ MSG_CNOTE_T_PRU_FLAGS "pru_flags:" +@ MSG_CNOTE_T_PRU_DATA "pru_data:" # Names of fake sections generated from program header data diff --git a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c index 657ab05605..b307f40c72 100644 --- a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c +++ b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c @@ -61,3 +61,4 @@ struct utsname uts; prfdinfo_core_t ptfd; prsecflags_t psf; prlwpname_t psn; +prupanic_t pru; diff --git a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c index 4f3d8b4dac..80e2d4964d 100644 --- a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c +++ b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c @@ -610,6 +610,16 @@ gen_prlwpname(void) END; } +static void +gen_prupanic(void) +{ + START(prupanic, prupanic_t); + SCALAR_FIELD(prupanic_t, pru_version, 0); + SCALAR_FIELD(prupanic_t, pru_flags, 0); + ARRAY_FIELD(prupanic_t, pru_data, 0); + END; +} + /*ARGSUSED*/ int main(int argc, char *argv[]) @@ -652,6 +662,7 @@ main(int argc, char *argv[]) gen_prfdinfo(); gen_prsecflags(); gen_prlwpname(); + gen_prupanic(); /* * Generate the full arch_layout description @@ -681,6 +692,7 @@ main(int argc, char *argv[]) (void) printf(fmt, "prfdinfo"); (void) printf(fmt, "prsecflags"); (void) printf(fmt, "prlwpname"); + (void) printf(fmt, "prupanic"); (void) printf("};\n"); /* diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout.h b/usr/src/cmd/sgs/elfdump/common/struct_layout.h index 7c43c33f99..6dde111468 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout.h +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout.h @@ -543,6 +543,13 @@ typedef struct { sl_field_t pr_lwpname; } sl_prlwpname_layout_t; +typedef struct { + sl_field_t sizeof_struct; + sl_field_t pru_version; + sl_field_t pru_flags; + sl_field_t pru_data; +} sl_prupanic_layout_t; + /* * This type collects all of the layout definitions for * a given architecture. @@ -570,6 +577,7 @@ typedef struct { const sl_prfdinfo_layout_t *prfdinfo; /* prdinfo_t */ const sl_prsecflags_layout_t *prsecflags; /* prsecflags_t */ const sl_prlwpname_layout_t *prlwpname; /* prlwpname_t */ + const sl_prupanic_layout_t *prupanic; /* prupanic_t */ } sl_arch_layout_t; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c index f040da7f3d..3107f42948 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c @@ -396,6 +396,14 @@ static const sl_prlwpname_layout_t prlwpname_layout = { }; +static const sl_prupanic_layout_t prupanic_layout = { + { 0, 1032, 0, 0 }, /* sizeof (prupanic_t) */ + { 0, 4, 0, 0 }, /* pru_version */ + { 4, 4, 0, 0 }, /* pru_flags */ + { 8, 1, 1024, 0 }, /* pru_data[] */ +}; + + static const sl_arch_layout_t layout_amd64 = { @@ -421,6 +429,7 @@ static const sl_arch_layout_t layout_amd64 = { &prfdinfo_layout, &prsecflags_layout, &prlwpname_layout, + &prupanic_layout, }; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c index 0e37cc5b95..cbdfee90d6 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c @@ -396,6 +396,14 @@ static const sl_prlwpname_layout_t prlwpname_layout = { }; +static const sl_prupanic_layout_t prupanic_layout = { + { 0, 1032, 0, 0 }, /* sizeof (prupanic_t) */ + { 0, 4, 0, 0 }, /* pru_version */ + { 4, 4, 0, 0 }, /* pru_flags */ + { 8, 1, 1024, 0 }, /* pru_data[] */ +}; + + static const sl_arch_layout_t layout_i386 = { @@ -421,6 +429,7 @@ static const sl_arch_layout_t layout_i386 = { &prfdinfo_layout, &prsecflags_layout, &prlwpname_layout, + &prupanic_layout, }; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c index 3e3abf9d2b..1033e887a3 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c @@ -396,6 +396,14 @@ static const sl_prlwpname_layout_t prlwpname_layout = { }; +static const sl_prupanic_layout_t prupanic_layout = { + { 0, 1032, 0, 0 }, /* sizeof (prupanic_t) */ + { 0, 4, 0, 0 }, /* pru_version */ + { 4, 4, 0, 0 }, /* pru_flags */ + { 8, 1, 1024, 0 }, /* pru_data[] */ +}; + + static const sl_arch_layout_t layout_sparc = { @@ -421,6 +429,7 @@ static const sl_arch_layout_t layout_sparc = { &prfdinfo_layout, &prsecflags_layout, &prlwpname_layout, + &prupanic_layout, }; diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c index 7ca7b27b1d..b189261c3a 100644 --- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c +++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c @@ -396,6 +396,14 @@ static const sl_prlwpname_layout_t prlwpname_layout = { }; +static const sl_prupanic_layout_t prupanic_layout = { + { 0, 1032, 0, 0 }, /* sizeof (prupanic_t) */ + { 0, 4, 0, 0 }, /* pru_version */ + { 4, 4, 0, 0 }, /* pru_flags */ + { 8, 1, 1024, 0 }, /* pru_data[] */ +}; + + static const sl_arch_layout_t layout_sparcv9 = { @@ -421,6 +429,7 @@ static const sl_arch_layout_t layout_sparcv9 = { &prfdinfo_layout, &prsecflags_layout, &prlwpname_layout, + &prupanic_layout, }; diff --git a/usr/src/cmd/sgs/include/conv.h b/usr/src/cmd/sgs/include/conv.h index 2c78d95b04..cff2530673 100644 --- a/usr/src/cmd/sgs/include/conv.h +++ b/usr/src/cmd/sgs/include/conv.h @@ -27,6 +27,7 @@ * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. * Copyright 2016 RackTop Systems. + * Copyright 2020 Oxide Computer Company */ #ifndef _CONV_H @@ -335,6 +336,13 @@ typedef union { char buf[CONV_PRSECFLAGS_BUFSIZE]; } Conv_secflags_buf_t; +/* conv_prupanic() */ +#define CONV_PRUPANIC_BUFSIZE 56 +typedef union { + Conv_inv_buf_t inv_buf; + char buf[CONV_PRUPANIC_BUFSIZE]; +} Conv_upanic_buf_t; + /* conv_cnote_sigset() */ #define CONV_CNOTE_SIGSET_BUFSIZE 639 typedef union { @@ -350,7 +358,7 @@ typedef union { } Conv_cnote_fltset_buf_t; /* conv_cnote_sysset() */ -#define CONV_CNOTE_SYSSET_BUFSIZE 3195 +#define CONV_CNOTE_SYSSET_BUFSIZE 3227 typedef union { Conv_inv_buf_t inv_buf; char buf[CONV_CNOTE_SYSSET_BUFSIZE]; @@ -833,6 +841,8 @@ extern const char *conv_cnote_priv(int, Conv_fmt_flags_t, Conv_inv_buf_t *); extern const char *conv_prsecflags(secflagset_t, Conv_fmt_flags_t, Conv_secflags_buf_t *); +extern const char *conv_prupanic(uint32_t, Conv_fmt_flags_t, + Conv_upanic_buf_t *); extern const char *conv_cnote_psetid(int, Conv_fmt_flags_t, Conv_inv_buf_t *); extern const char *conv_cnote_sa_flags(int, Conv_fmt_flags_t, diff --git a/usr/src/cmd/sgs/libconv/Makefile.com b/usr/src/cmd/sgs/libconv/Makefile.com index daffcfa01e..4cc0f5d8bc 100644 --- a/usr/src/cmd/sgs/libconv/Makefile.com +++ b/usr/src/cmd/sgs/libconv/Makefile.com @@ -120,3 +120,9 @@ MSGSRCS= $(COMOBJS:%.o=../common/%.c) \ SGSMSGTARG= $(BLTOBJS:%_msg.o=../common/%.msg) CLEANFILES += $(BLTDATA) bld_vernote vernote.s + +# +# Disable the stack protector due to issues with bootstrapping rtld. See +# cmd/sgs/rtld/Makefile.com for more information. +# +STACKPROTECT = none diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c index f86d534450..10900b0d27 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.c +++ b/usr/src/cmd/sgs/libconv/common/corenote.c @@ -26,6 +26,7 @@ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright (c) 2018 Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* @@ -59,9 +60,9 @@ conv_cnote_type(Word type, Conv_fmt_flags_t fmt_flags, MSG_NT_PRPRIVINFO, MSG_NT_CONTENT, MSG_NT_ZONENAME, MSG_NT_FDINFO, MSG_NT_SPYMASTER, MSG_NT_SECFLAGS, - MSG_NT_LWPNAME, + MSG_NT_LWPNAME, MSG_NT_UPANIC }; -#if NT_NUM != NT_LWPNAME +#if NT_NUM != NT_UPANIC #error "NT_NUM has grown. Update core note types[]" #endif static const conv_ds_msg_t ds_types = { @@ -255,8 +256,8 @@ conv_cnote_syscall(Word sysnum, Conv_fmt_flags_t fmt_flags, MSG_SYS_MUNMAP, MSG_SYS_FPATHCONF, MSG_SYS_VFORK, MSG_SYS_FCHDIR, MSG_SYS_READV, MSG_SYS_WRITEV, - MSG_SYS_123, MSG_SYS_124, - MSG_SYS_125, MSG_SYS_126, + MSG_SYS_PREADV, MSG_SYS_PWRITEV, + MSG_SYS_UPANIC, MSG_SYS_GETRANDOM, MSG_SYS_MMAPOBJ, MSG_SYS_SETRLIMIT, MSG_SYS_GETRLIMIT, MSG_SYS_LCHOWN, MSG_SYS_MEMCNTL, MSG_SYS_GETPMSG, @@ -1956,10 +1957,10 @@ conv_cnote_fltset(uint32_t *maskarr, int n_mask, MSG_SYS_FCHDIR_ALT_SIZE /* 120 */ + \ MSG_SYS_READV_ALT_SIZE /* 121 */ + \ MSG_SYS_WRITEV_ALT_SIZE /* 122 */ + \ - MSG_SYS_123_SIZE /* 123 (unused) */ + \ - MSG_SYS_124_SIZE /* 124 (unused) */ + \ - MSG_SYS_125_SIZE /* 125 (unused) */ + \ - MSG_SYS_126_SIZE /* 126 (unused) */ + \ + MSG_SYS_PREADV_SIZE /* 123 */ + \ + MSG_SYS_PWRITEV_SIZE /* 124 */ + \ + MSG_SYS_UPANIC_SIZE /* 125 */ + \ + MSG_SYS_GETRANDOM_SIZE /* 126 */ + \ MSG_SYS_MMAPOBJ_ALT_SIZE /* 127 */ + \ MSG_SYS_SETRLIMIT_ALT_SIZE /* 128 */ + \ \ @@ -2279,10 +2280,10 @@ conv_cnote_sysset(uint32_t *maskarr, int n_mask, { 0x00800000, MSG_SYS_FCHDIR_ALT }, { 0x01000000, MSG_SYS_READV_ALT }, { 0x02000000, MSG_SYS_WRITEV_ALT }, - { 0x04000000, MSG_SYS_123 }, - { 0x08000000, MSG_SYS_124 }, - { 0x10000000, MSG_SYS_125 }, - { 0x20000000, MSG_SYS_126 }, + { 0x04000000, MSG_SYS_PREADV_ALT }, + { 0x08000000, MSG_SYS_PWRITEV_ALT }, + { 0x10000000, MSG_SYS_UPANIC_ALT }, + { 0x20000000, MSG_SYS_GETRANDOM_ALT }, { 0x40000000, MSG_SYS_MMAPOBJ_ALT }, { 0x80000000, MSG_SYS_SETRLIMIT_ALT }, { 0, 0 } @@ -2642,3 +2643,54 @@ conv_prsecflags(secflagset_t flags, Conv_fmt_flags_t fmt_flags, return ((const char *)secflags_buf->buf); } + + +#define UPANICFLGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ + MSG_MSG_VALID_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_MSG_ERROR_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_MSG_TRUNC_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE + +/* + * Ensure that Conv_upanic_buf_t is large enough: + * + * UPANICFLGSZ is the real minimum size of the buffer required by + * conv_prsecflags(). However, Conv_upanic_buf_t uses CONV_PRUPANIC_BUFSIZE to + * set the buffer size. We do things this way because the definition of + * UPANICFLGSZ uses information that is not available in the environment of + * other programs that include the conv.h header file. + */ +#if (CONV_PRUPANIC_BUFSIZE != UPANICFLGSZ) +#define REPORT_BUFSIZE UPANICFLGSZ +#include "report_bufsize.h" +#error "CONV_PRUPANIC_BUFSIZE does not match UPANICFLGSZ" +#endif + +const char * +conv_prupanic(uint32_t flags, Conv_fmt_flags_t fmt_flags, + Conv_upanic_buf_t *upanic_buf) +{ + /* + * Unfortunately, we cannot directly use the PRUPANIC_FLAG_* macros here + * because of the fact that this is also built natively and that would + * create an unresolvable flag day. + */ + static Val_desc vda[] = { + { 0x01, MSG_MSG_VALID }, + { 0x02, MSG_MSG_ERROR }, + { 0x04, MSG_MSG_TRUNC }, + { 0, 0 } + }; + static CONV_EXPN_FIELD_ARG conv_arg = { + NULL, sizeof (upanic_buf->buf) + }; + + if (flags == 0) + return (MSG_ORIG(MSG_GBL_ZERO)); + + conv_arg.buf = upanic_buf->buf; + conv_arg.oflags = conv_arg.rflags = flags; + (void) conv_expn_field(&conv_arg, vda, fmt_flags); + + return ((const char *)upanic_buf->buf); +} diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg index 78951cfb1d..7c75c5735e 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.msg +++ b/usr/src/cmd/sgs/libconv/common/corenote.msg @@ -25,6 +25,7 @@ # # Copyright 2012 DEY Storage Systems, Inc. All rights reserved. # Copyright (c) 2018 Joyent, Inc. +# Copyright 2020 Oxide Computer Company # @ MSG_NT_PRSTATUS "[ NT_PRSTATUS ]" @@ -50,6 +51,7 @@ @ MSG_NT_SPYMASTER "[ NT_SPYMASTER ]" @ MSG_NT_SECFLAGS "[ NT_SECFLAGS ]" @ MSG_NT_LWPNAME "[ NT_LWPNAME ]" +@ MSG_NT_UPANIC "[ NT_UPANIC ]" @ MSG_AUXV_AF_SUN_SETUGID "AF_SUN_SETUGID" @@ -291,6 +293,10 @@ @ MSG_FORBIDNULLMAP "FORBIDNULLMAP" @ MSG_NOEXECSTACK "NOEXECSTACK" +@ MSG_MSG_VALID "MSG_VALID" +@ MSG_MSG_ERROR "MSG_ERROR" +@ MSG_MSG_TRUNC "MSG_TRUNC" + @ MSG_PS_NONE "[ PS_NONE ]" @ MSG_PS_QUERY "[ PS_QUERY ]" @ MSG_PS_MYID "[ PS_MYID ]" @@ -829,10 +835,14 @@ @ MSG_SYS_READV_ALT "readv" @ MSG_SYS_WRITEV "[ writev ]" # 122 @ MSG_SYS_WRITEV_ALT "writev" -@ MSG_SYS_123 "123" # 123(u) -@ MSG_SYS_124 "124" # 124(u) -@ MSG_SYS_125 "125" # 125(u) -@ MSG_SYS_126 "126" # 126(u) +@ MSG_SYS_PREADV "[ preadv ]" # 123 +@ MSG_SYS_PREADV_ALT "preadv" +@ MSG_SYS_PWRITEV "[ pwritev ]" # 124 +@ MSG_SYS_PWRITEV_ALT "pwritev" +@ MSG_SYS_UPANIC "[ upanic ]" # 125 +@ MSG_SYS_UPANIC_ALT "upanic" +@ MSG_SYS_GETRANDOM "[ getrandom ]" # 126 +@ MSG_SYS_GETRANDOM_ALT "getrandom" @ MSG_SYS_MMAPOBJ "[ mmapobj ]" # 127 @ MSG_SYS_MMAPOBJ_ALT "mmapobj" @ MSG_SYS_SETRLIMIT "[ setrlimit ]" # 128 diff --git a/usr/src/cmd/sgs/rtld/Makefile.com b/usr/src/cmd/sgs/rtld/Makefile.com index 853fd5066b..4b1a9a328d 100644 --- a/usr/src/cmd/sgs/rtld/Makefile.com +++ b/usr/src/cmd/sgs/rtld/Makefile.com @@ -154,3 +154,19 @@ SRCS= $(AVLOBJ:%.o=$(VAR_AVLDIR)/%.c) \ CLEANFILES += $(CRTS) $(BLTFILES) CLOBBERFILES += $(RTLD) + +# +# We cannot currently enable the stack protector for rtld as it runs +# before libc initializes, which is where we always enable the stack +# protector values. Because rtld is likely on an alternate link map and +# links in the relevant portions of libc through libc_pic.a, there is +# probably a path to enabling an rtld specific version of the stack +# protector. +# +# As a result, this currently disables the stack protector in two +# related targets which really could use it. These are libconv and libc. +# Both of these end up building position-independent archive libraries +# that are directly linked into rtld. This situation can and should be +# improved. +# +STACKPROTECT = none diff --git a/usr/src/cmd/truss/main.c b/usr/src/cmd/truss/main.c index 23c2056314..9b7d7bac54 100644 --- a/usr/src/cmd/truss/main.c +++ b/usr/src/cmd/truss/main.c @@ -22,6 +22,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -59,7 +60,7 @@ */ typedef struct proc_set { pid_t pid; - const char *lwps; + const char *lwps; } proc_set_t; /* @@ -684,6 +685,7 @@ main(int argc, char *argv[]) praddset(&traceeven, SYS_open64); praddset(&traceeven, SYS_vfork); praddset(&traceeven, SYS_forksys); + praddset(&traceeven, SYS_upanic); /* for I/O buffer dumps, force tracing of read()s and write()s */ if (!isemptyset(&readfd)) { @@ -723,8 +725,10 @@ main(int argc, char *argv[]) /* special case -- sysexit never reached */ (void) Psysentry(Proc, SYS_exit, TRUE); (void) Psysentry(Proc, SYS_lwp_exit, TRUE); + (void) Psysentry(Proc, SYS_upanic, TRUE); (void) Psysexit(Proc, SYS_exit, FALSE); (void) Psysexit(Proc, SYS_lwp_exit, FALSE); + (void) Psysexit(Proc, SYS_upanic, FALSE); Psetsignal(Proc, &signals); /* trace these signals */ Psetfault(Proc, &faults); /* trace these faults */ @@ -1090,6 +1094,7 @@ worker_thread(void *arg) switch (what) { case SYS_exit: /* exit() */ case SYS_lwp_exit: /* lwp_exit() */ + case SYS_upanic: /* upanic() */ case SYS_context: /* [get|set]context() */ if (dotrace && cflag && prismember(&trace, what)) { @@ -2692,7 +2697,7 @@ letgo(private_t *pri) */ int is_empty(const uint32_t *sp, /* pointer to set (array of int32's) */ - size_t n) /* number of int32's in set */ + size_t n) /* number of int32's in set */ { if (n) { do { diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c index 9e4d1780f4..ecc8c66b3a 100644 --- a/usr/src/cmd/truss/systable.c +++ b/usr/src/cmd/truss/systable.c @@ -22,6 +22,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. 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 */ @@ -347,7 +348,7 @@ const struct systable systable[] = { {"writev", 3, DEC, NOV, DEC, HEX, DEC}, /* 122 */ {"preadv", 4, DEC, NOV, DEC, HEX, DEC, DEC}, /* 123 */ {"pwritev", 4, DEC, NOV, DEC, HEX, DEC, DEC}, /* 124 */ -{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX}, +{"upanic", 2, DEC, NOV, HEX, DEC}, /* 125 */ {"getrandom", 3, DEC, NOV, IOB, UNS, GRF}, /* 126 */ {"mmapobj", 5, DEC, NOV, DEC, MOB, HEX, HEX, HEX}, /* 127 */ {"setrlimit", 2, DEC, NOV, RLM, HEX}, /* 128 */ diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile index 1f598f5849..ac2e8a89f7 100644 --- a/usr/src/head/Makefile +++ b/usr/src/head/Makefile @@ -206,6 +206,7 @@ HDRS= $($(MACH)_HDRS) \ ucred.h \ ulimit.h \ unistd.h \ + upanic.h \ userdefs.h \ ustat.h \ utime.h \ diff --git a/usr/src/head/upanic.h b/usr/src/head/upanic.h new file mode 100644 index 0000000000..be34d02b84 --- /dev/null +++ b/usr/src/head/upanic.h @@ -0,0 +1,36 @@ +/* + * 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 + */ + +#ifndef _UPANIC_H +#define _UPANIC_H + +/* + * Support for guaranteed user process abort-like termination. + */ + +#include <sys/feature_tests.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern _NORETURN_KYWD void upanic(const char *, size_t) __NORETURN; + +#ifdef __cplusplus +} +#endif + +#endif /* _UPANIC_H */ diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index 2418a2ee02..8eb1cee005 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -47,6 +47,7 @@ include ../Makefile.master # Build libc and its dependencies SUBDIRS= \ + ssp_ns \ crt \ ../cmd/sgs/libconv \ ../cmd/sgs/libdl \ diff --git a/usr/src/lib/Makefile.lib b/usr/src/lib/Makefile.lib index 7eee86c18e..c1cb2513f3 100644 --- a/usr/src/lib/Makefile.lib +++ b/usr/src/lib/Makefile.lib @@ -182,6 +182,13 @@ INS.liblink64= -$(RM) $@; $(SYMLINK) $(LIBLINKPATH)$(LIBLINKS)$(VERS) $@ INS.liblinkccc64= -$(RM) $@; $(SYMLINK) $(LIBLINKPATH)$(LIBLINKSCCC)$(VERS) $@ # +# Default to adding stack protection to all libraries. +# +CFLAGS += $(CCSTACKPROTECT) +CFLAGS64 += $(CCSTACKPROTECT) +LDLIBS += $(LDSTACKPROTECT) + +# # If appropriate, augment POST_PROCESS_O and POST_PROCESS_SO to do CTF # processing. We'd like to just conditionally append to POST_PROCESS_O and # POST_PROCESS_SO, but ParallelMake has a bug which causes the same value to diff --git a/usr/src/lib/brand/lx/lx_vdso/tools/Makefile b/usr/src/lib/brand/lx/lx_vdso/tools/Makefile index 7907aa67c4..272234b66e 100644 --- a/usr/src/lib/brand/lx/lx_vdso/tools/Makefile +++ b/usr/src/lib/brand/lx/lx_vdso/tools/Makefile @@ -19,6 +19,9 @@ include ../../../../../cmd/Makefile.cmd OBJS = vdso_tool.o +# Native tool, doesn't need stack protection. +STACKPROTECT = none + CLOBBERFILES += $(PROG) NATIVECC_CFLAGS += $(CFLAGS) $(CCVERBOSE) diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index d8919e9201..710a72e87e 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -267,6 +267,7 @@ COMSYSOBJS= \ sigprocmsk.o \ sigsendset.o \ sigsuspend.o \ + ssp.o \ statfs.o \ statvfs.o \ stty.o \ @@ -279,6 +280,7 @@ COMSYSOBJS= \ ulimit.o \ umask.o \ umount2.o \ + upanic.o \ utssys.o \ uucopy.o \ vhangup.o \ @@ -1201,6 +1203,12 @@ pics/arc4random.o := CPPFLAGS += -I$(SRC)/common/crypto/chacha pics/__clock_gettime.o := CPPFLAGS += $(COMMPAGE_CPPFLAGS) pics/gettimeofday.o := CPPFLAGS += $(COMMPAGE_CPPFLAGS) +# +# Disable the stack protector due to issues with bootstrapping rtld. See +# cmd/sgs/rtld/Makefile.com for more information. +# +STACKPROTECT = none + .KEEP_STATE: all: $(LIBS) $(LIB_PIC) diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 293014892a..a074accf08 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -306,6 +306,7 @@ COMSYSOBJS= \ ulimit.o \ umask.o \ umount2.o \ + upanic.o \ utssys.o \ uucopy.o \ vhangup.o \ @@ -574,6 +575,7 @@ PORTGEN= \ sigsend.o \ sigsetops.o \ ssignal.o \ + ssp.o \ stack.o \ stpcpy.o \ stpncpy.o \ @@ -1266,6 +1268,12 @@ pics/arc4random.o := CPPFLAGS += -I$(SRC)/common/crypto/chacha pics/__clock_gettime.o := CPPFLAGS += $(COMMPAGE_CPPFLAGS) pics/gettimeofday.o := CPPFLAGS += $(COMMPAGE_CPPFLAGS) +# +# Disable the stack protector due to issues with bootstrapping rtld. See +# cmd/sgs/rtld/Makefile.com for more information. +# +STACKPROTECT = none + .KEEP_STATE: all: $(LIBS) $(LIB_PIC) diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index 7f08a0b8c4..65d73f9db7 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -1323,6 +1323,7 @@ extern void _flush_windows(void); #define _flush_windows() #endif extern void set_curthread(void *); +extern void ssp_init(void); /* * Utility function used when waking up many threads (more than MAXLWPS) diff --git a/usr/src/lib/libc/port/gen/ssp.c b/usr/src/lib/libc/port/gen/ssp.c new file mode 100644 index 0000000000..81d93829ea --- /dev/null +++ b/usr/src/lib/libc/port/gen/ssp.c @@ -0,0 +1,67 @@ +/* + * 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 <upanic.h> +#include <sys/random.h> + +/* + * This provides an implementation of the stack protector functions that are + * expected by gcc's ssp implementation. + * + * We attempt to initialize the stack guard with random data, which is our best + * protection. If that fails, we'd like to have a guard that is still meaningful + * and not totally predictable. The original StackGuard paper suggests using a + * terminator canary. To make this a little more difficult, we also use a + * portion of the data from gethrtime(). + * + * In a 32-bit environment, we only have four bytes worth of data. We use the + * lower two bytes of the gethrtime() value and then use pieces of the + * terminator canary, '\n\0'. In a 64-bit environment we use the full four byte + * terminator canary and then four bytes of gethrtime. + */ + +/* + * Use an array here so it's easier to get the length at compile time. + */ +static const char ssp_msg[] = "*** stack smashing detected"; + +uintptr_t __stack_chk_guard; + +void +ssp_init(void) +{ + if (getrandom(&__stack_chk_guard, sizeof (__stack_chk_guard), 0) != + sizeof (__stack_chk_guard)) { + /* + * This failed, attempt to get some data that might let us get + * off the ground. + */ + hrtime_t t = gethrtime(); +#ifdef _LP32 + const uint16_t guard = '\n' << 8 | '\0'; + __stack_chk_guard = guard << 16 | (uint16_t)t; +#else + const uint32_t guard = '\r' << 24 | '\n' << 16 | '\0' << 8 | + '\xff'; + __stack_chk_guard = (uint64_t)guard << 32 | (uint32_t)t; +#endif + } +} + +void +__stack_chk_fail(void) +{ + upanic(ssp_msg, sizeof (ssp_msg)); +} diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 92a58825d4..0dec599cf6 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -78,6 +78,18 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.37 { + global: + __stack_chk_guard; + protected: + __stack_chk_fail; +} ILLUMOS_0.36; + +SYMBOL_VERSION ILLUMOS_0.36 { + protected: + upanic; +} ILLUMOS_0.35; + SYMBOL_VERSION ILLUMOS_0.35 { protected: qsort_r; diff --git a/usr/src/lib/libc/port/sys/upanic.c b/usr/src/lib/libc/port/sys/upanic.c new file mode 100644 index 0000000000..2edfe4c4ff --- /dev/null +++ b/usr/src/lib/libc/port/sys/upanic.c @@ -0,0 +1,23 @@ +/* + * 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/types.h> +#include <sys/syscall.h> + +void +upanic(const void *buf, size_t len) +{ + (void) syscall(SYS_upanic, buf, len); +} diff --git a/usr/src/lib/libc/port/threads/assfail.c b/usr/src/lib/libc/port/threads/assfail.c index 1c032d8ea7..4af2fc5664 100644 --- a/usr/src/lib/libc/port/threads/assfail.c +++ b/usr/src/lib/libc/port/threads/assfail.c @@ -26,10 +26,12 @@ /* * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright 2015 Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ #include "lint.h" #include "thr_uberdata.h" +#include <upanic.h> const char *panicstr; ulwp_t *panic_thread; @@ -60,35 +62,19 @@ grab_assert_lock() } static void -Abort(const char *msg) +Abort(const char *msg, size_t buflen) { ulwp_t *self; struct sigaction act; sigset_t sigmask; - lwpid_t lwpid; /* to help with core file debugging */ panicstr = msg; if ((self = __curthread()) != NULL) { panic_thread = self; - lwpid = self->ul_lwpid; - } else { - lwpid = _lwp_self(); } - /* set SIGABRT signal handler to SIG_DFL w/o grabbing any locks */ - (void) memset(&act, 0, sizeof (act)); - act.sa_sigaction = SIG_DFL; - (void) __sigaction(SIGABRT, &act, NULL); - - /* delete SIGABRT from the signal mask */ - (void) sigemptyset(&sigmask); - (void) sigaddset(&sigmask, SIGABRT); - (void) __lwp_sigmask(SIG_UNBLOCK, &sigmask); - - (void) _lwp_kill(lwpid, SIGABRT); /* never returns */ - (void) kill(getpid(), SIGABRT); /* if it does, try harder */ - _exit(127); + upanic(msg, buflen); } /* @@ -117,7 +103,7 @@ common_panic(const char *head, const char *why) if (msg[len1 - 1] != '\n') msg[len1++] = '\n'; (void) __write(2, msg, len1); - Abort(msg); + Abort(msg, sizeof (msg)); } void @@ -246,7 +232,7 @@ lock_error(const mutex_t *mp, const char *who, void *cv, const char *msg) (void) strcat(buf, "\n\n"); (void) __write(2, buf, strlen(buf)); if (udp->uberflags.uf_thread_error_detection >= 2) - Abort(buf); + Abort(buf, sizeof (buf)); assert_thread = NULL; (void) _lwp_mutex_unlock(&assert_lock); if (self != NULL) @@ -335,7 +321,7 @@ rwlock_error(const rwlock_t *rp, const char *who, const char *msg) (void) strcat(buf, "\n\n"); (void) __write(2, buf, strlen(buf)); if (udp->uberflags.uf_thread_error_detection >= 2) - Abort(buf); + Abort(buf, sizeof (buf)); assert_thread = NULL; (void) _lwp_mutex_unlock(&assert_lock); if (self != NULL) @@ -383,7 +369,7 @@ thread_error(const char *msg) (void) strcat(buf, "\n\n"); (void) __write(2, buf, strlen(buf)); if (udp->uberflags.uf_thread_error_detection >= 2) - Abort(buf); + Abort(buf, sizeof (buf)); assert_thread = NULL; (void) _lwp_mutex_unlock(&assert_lock); if (self != NULL) @@ -455,7 +441,7 @@ __assfail(const char *assertion, const char *filename, int line_num) * if (self != NULL) * exit_critical(self); */ - Abort(buf); + Abort(buf, sizeof (buf)); } /* diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c index 8026ffad9c..66d0e524c2 100644 --- a/usr/src/lib/libc/port/threads/thr.c +++ b/usr/src/lib/libc/port/threads/thr.c @@ -1308,6 +1308,11 @@ libc_init(void) */ if (oldself != NULL && (oldself->ul_primarymap || !primary_link_map)) { __tdb_bootstrap = oldself->ul_uberdata->tdb_bootstrap; + /* + * Each link map has its own copy of the stack protector guard + * and must always be initialized. + */ + ssp_init(); mutex_setup(); atfork_init(); /* every link map needs atfork() processing */ init_progname(); @@ -1448,6 +1453,7 @@ libc_init(void) /* tls_size was zero when oldself was allocated */ lfree(oldself, sizeof (ulwp_t)); } + ssp_init(); mutex_setup(); atfork_init(); signal_init(); diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index da5a4b541a..217cd58dc8 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -322,6 +322,7 @@ COMSYSOBJS= \ ulimit.o \ umask.o \ umount2.o \ + upanic.o \ utssys.o \ uucopy.o \ vhangup.o \ @@ -601,6 +602,7 @@ PORTGEN= \ sigsend.o \ sigsetops.o \ ssignal.o \ + ssp.o \ stack.o \ stpcpy.o \ stpncpy.o \ @@ -1317,6 +1319,12 @@ pics/arc4random.o := CPPFLAGS += -I$(SRC)/common/crypto/chacha # Files which need extra optimization pics/getenv.o := sparc_COPTFLAG = -xO4 +# +# Disable the stack protector due to issues with bootstrapping rtld. See +# cmd/sgs/rtld/Makefile.com for more information. +# +STACKPROTECT = none + .KEEP_STATE: all: $(LIBS) $(LIB_PIC) diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index 7f659225d0..7689a5b66e 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -304,6 +304,7 @@ COMSYSOBJS= \ ulimit.o \ umask.o \ umount2.o \ + upanic.o \ utssys.o \ uucopy.o \ vhangup.o \ @@ -559,6 +560,7 @@ PORTGEN= \ sigsend.o \ sigsetops.o \ ssignal.o \ + ssp.o \ stack.o \ stpcpy.o \ stpncpy.o \ @@ -1240,6 +1242,12 @@ pics/arc4random.o := CPPFLAGS += -I$(SRC)/common/crypto/chacha # Files which need extra optimization pics/getenv.o := sparcv9_COPTFLAG = -xO4 +# +# Disable the stack protector due to issues with bootstrapping rtld. See +# cmd/sgs/rtld/Makefile.com for more information. +# +STACKPROTECT = none + .KEEP_STATE: all: $(LIBS) $(LIB_PIC) diff --git a/usr/src/lib/libdisasm/Makefile.com b/usr/src/lib/libdisasm/Makefile.com index 2173e5bb2c..e88d62335f 100644 --- a/usr/src/lib/libdisasm/Makefile.com +++ b/usr/src/lib/libdisasm/Makefile.com @@ -124,6 +124,12 @@ CERRWARN += $(CNOWARN_UNINIT) # not linted SMATCH=off +# +# The standalone environment currently does not support the stack +# protector. +# +STACKPROTECT = none + # We want the thread-specific errno in the library, but we don't want it in # the standalone. $(DTS_ERRNO) is designed to add -D_TS_ERRNO to $(CPPFLAGS), # in order to enable this feature. Conveniently, -D_REENTRANT does the same diff --git a/usr/src/lib/libdtrace/Makefile.com b/usr/src/lib/libdtrace/Makefile.com index e2296ca468..9a68e6729d 100644 --- a/usr/src/lib/libdtrace/Makefile.com +++ b/usr/src/lib/libdtrace/Makefile.com @@ -143,7 +143,7 @@ SMATCH=off YYCFLAGS = LDLIBS += -lgen -lproc -lrtld_db -lnsl -lsocket -lctf -lelf -lc -lzonecfg DRTILDLIBS = $(LDLIBS.lib) -lc -LIBDAUDITLIBS = $(LDLIBS.lib) -lmapmalloc -lc -lproc +LIBDAUDITLIBS = $(LDLIBS.lib) -lmapmalloc -lc -lproc $(LDSTACKPROTECT) yydebug := YYCFLAGS += -DYYDEBUG @@ -157,6 +157,14 @@ ROOTDLIBS = $(DLIBSRCS:%=$(ROOTDLIBDIR)/%) ROOTDOBJS = $(ROOTDLIBDIR)/$(DRTIOBJ) $(ROOTDLIBDIR)/$(LIBDAUDIT) ROOTDOBJS64 = $(ROOTDLIBDIR64)/$(DRTIOBJ) $(ROOTDLIBDIR64)/$(LIBDAUDIT) +# +# We do not build drti.o with the stack protector as otherwise +# everything that uses dtrace -G may have a surprise stack protector +# requirement right now. While in theory this could be handled by libc, +# this will make the overall default transition smoother. +# +$(DRTIOBJ) := STACKPROTECT = none + $(ROOTDLIBDIR)/%.d := FILEMODE=444 $(ROOTDLIBDIR)/%.o := FILEMODE=444 $(ROOTDLIBDIR64)/%.o := FILEMODE=444 diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c index b68adfb044..eda2737d91 100644 --- a/usr/src/lib/libproc/common/Pcontrol.c +++ b/usr/src/lib/libproc/common/Pcontrol.c @@ -1318,6 +1318,8 @@ Psecflags(struct ps_prochandle *P, prsecflags_t **psf) if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) { if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) { + free(*psf); + *psf = NULL; errno = EINVAL; return (-1); } diff --git a/usr/src/lib/libproc/common/Pcontrol.h b/usr/src/lib/libproc/common/Pcontrol.h index 550b6779dd..6121a7e79b 100644 --- a/usr/src/lib/libproc/common/Pcontrol.h +++ b/usr/src/lib/libproc/common/Pcontrol.h @@ -172,6 +172,7 @@ typedef struct core_info { /* information specific to core files */ priv_impl_info_t *core_ppii; /* NOTE entry for core_privinfo */ char *core_zonename; /* zone name from core file */ prsecflags_t *core_secflags; /* secflags from core file */ + prupanic_t *core_upanic; /* upanic from core file */ #if defined(__i386) || defined(__amd64) struct ssd *core_ldt; /* LDT entries from core file */ uint_t core_nldt; /* number of LDT entries in core file */ diff --git a/usr/src/lib/libproc/common/Pcore.c b/usr/src/lib/libproc/common/Pcore.c index cd539876b1..39424fad67 100644 --- a/usr/src/lib/libproc/common/Pcore.c +++ b/usr/src/lib/libproc/common/Pcore.c @@ -245,6 +245,8 @@ Pfini_core(struct ps_prochandle *P, void *data) free(core->core_zonename); if (core->core_secflags != NULL) free(core->core_secflags); + if (core->core_upanic != NULL) + free(core->core_upanic); #ifdef __x86 if (core->core_ldt != NULL) free(core->core_ldt); @@ -1201,6 +1203,34 @@ err: return (-1); } +static int +note_upanic(struct ps_prochandle *P, size_t nbytes) +{ + core_info_t *core = P->data; + prupanic_t *pru; + + if (core->core_upanic != NULL) + return (0); + + if (sizeof (*pru) != nbytes) { + dprintf("Pgrab_core: NT_UPANIC changed size." + " Need to handle a version change?\n"); + return (-1); + } + + if (nbytes != 0 && ((pru = malloc(nbytes)) != NULL)) { + if (read(P->asfd, pru, nbytes) != nbytes) { + dprintf("Pgrab_core: failed to read NT_UPANIC\n"); + free(pru); + return (-1); + } + + core->core_upanic = pru; + } + + return (0); +} + /*ARGSUSED*/ static int note_notsup(struct ps_prochandle *P, size_t nbytes) @@ -1266,6 +1296,7 @@ static int (*nhdlrs[])(struct ps_prochandle *, size_t) = { note_spymaster, /* 23 NT_SPYMASTER */ note_secflags, /* 24 NT_SECFLAGS */ note_lwpname, /* 25 NT_LWPNAME */ + note_upanic /* 26 NT_UPANIC */ }; static void @@ -2880,3 +2911,37 @@ Pgrab_core(const char *core, const char *aout, int gflag, int *perr) return (NULL); } + +int +Pupanic(struct ps_prochandle *P, prupanic_t **pru) +{ + core_info_t *core; + + if (P->state != PS_DEAD) { + errno = ENODATA; + return (-1); + } + + core = P->data; + if (core->core_upanic == NULL) { + errno = ENOENT; + return (-1); + } + + if (core->core_upanic->pru_version != PRUPANIC_VERSION_1) { + errno = EINVAL; + return (-1); + } + + if ((*pru = calloc(1, sizeof (prupanic_t))) == NULL) + return (-1); + (void) memcpy(*pru, core->core_upanic, sizeof (prupanic_t)); + + return (0); +} + +void +Pupanic_free(prupanic_t *pru) +{ + free(pru); +} diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index cdf789a621..a73f8af647 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -792,6 +792,12 @@ extern int proc_finistdio(void); typedef int proc_fdinfo_f(void *, const prfdinfo_t *); extern int Pfdinfo_iter(struct ps_prochandle *, proc_fdinfo_f *, void *); +/* + * NT_UPANIC information. + */ +extern int Pupanic(struct ps_prochandle *, prupanic_t **); +extern void Pupanic_free(prupanic_t *); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers index 1da5918393..61934de499 100644 --- a/usr/src/lib/libproc/common/mapfile-vers +++ b/usr/src/lib/libproc/common/mapfile-vers @@ -307,6 +307,8 @@ SYMBOL_VERSION SUNWprivate_1.1 { Punsetflags; Pupdate_maps; Pupdate_syms; + Pupanic; + Pupanic_free; Pwait; Pwrite; Pxcreate; diff --git a/usr/src/lib/libproc/common/proc_names.c b/usr/src/lib/libproc/common/proc_names.c index 314b01fbcd..65332da273 100644 --- a/usr/src/lib/libproc/common/proc_names.c +++ b/usr/src/lib/libproc/common/proc_names.c @@ -24,6 +24,7 @@ * Copyright (c) 2015, Joyent, Inc. All rights reserved. * Copyright 2019, Carlos Neira <cneirabustos@gmail.com> * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 Oxide Computer Company */ #include <stdio.h> @@ -241,7 +242,7 @@ static const char *const systable[] = { "writev", /* 122 */ "preadv", /* 123 */ "pwritev", /* 124 */ - NULL, /* 125 */ + "upanic", /* 125 */ "getrandom", /* 126 */ "mmapobj", /* 127 */ "setrlimit", /* 128 */ diff --git a/usr/src/lib/libsaveargs/Makefile.com b/usr/src/lib/libsaveargs/Makefile.com index 3f23249570..6e47b2839c 100644 --- a/usr/src/lib/libsaveargs/Makefile.com +++ b/usr/src/lib/libsaveargs/Makefile.com @@ -60,6 +60,12 @@ LINKTEST_OBJ = objs/linktest_stand.o CLOBBERFILES_standalone = $(LINKTEST_OBJ) CLOBBERFILES += $(CLOBBERFILES_$(CURTYPE)) +# +# The standalone environment currently does not support the stack +# protector. +# +$(STANDLIBRARY) := STACKPROTECT = none + LIBS_standalone = $(STANDLIBRARY) LIBS_library = $(DYNLIB) LIBS = $(LIBS_$(CURTYPE)) diff --git a/usr/src/lib/libumem/Makefile.com b/usr/src/lib/libumem/Makefile.com index 876940f995..aabff24f69 100644 --- a/usr/src/lib/libumem/Makefile.com +++ b/usr/src/lib/libumem/Makefile.com @@ -155,6 +155,12 @@ CFLAGS += $(CFLAGS_$(CURTYPE)) $(CFLAGS_common) CFLAGS64_standalone = $(STAND_FLAGS_64) CFLAGS64 += $(CCVERBOSE) $(CFLAGS64_$(CURTYPE)) $(CFLAGS64_common) +# +# For the standalone environment, disable the stack protector for the +# time being. +# +$(STANDLIBRARY) := STACKPROTECT = none + # false positive for umem_alloc_sizes_add() pics/umem.o := SMOFF += index_overflow objs/umem.o := SMOFF += index_overflow diff --git a/usr/src/lib/ssp_ns/Makefile b/usr/src/lib/ssp_ns/Makefile new file mode 100644 index 0000000000..e04e271f66 --- /dev/null +++ b/usr/src/lib/ssp_ns/Makefile @@ -0,0 +1,37 @@ +# +# 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 ../Makefile.lib + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install + +.KEEP_STATE: + +all clean clobber: $(SUBDIRS) + +install: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/ssp_ns/Makefile.com b/usr/src/lib/ssp_ns/Makefile.com new file mode 100644 index 0000000000..aaa9aa52a9 --- /dev/null +++ b/usr/src/lib/ssp_ns/Makefile.com @@ -0,0 +1,46 @@ +# +# 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 +# + +LIBRARY = libssp_ns.a +VERS = .1 +OBJECTS = ssp_ns.o + +include ../../Makefile.lib + +# +# We need to build an archive file; however, this is going to show up +# and be used in libraries and otherwise. So we need to still build it +# as position independent code. The Makefile system doesn't want to +# build a PIC file that's going into a .a file by default, so we have to +# do a little bit here. +# +LIBS = $(LIBRARY) +SRCDIR = ../common +CFLAGS += $($(MACH)_C_PICFLAGS) + +# +# Disable stack protection for the things providing the stack +# protection. +# +STACKPROTECT = none + +CLOBBERFILES += $(LIBRARY) + +.KEEP_STATE: + +all: $(LIBS) + + +include ../../Makefile.targ diff --git a/usr/src/lib/ssp_ns/amd64/Makefile b/usr/src/lib/ssp_ns/amd64/Makefile new file mode 100644 index 0000000000..59bd9673ce --- /dev/null +++ b/usr/src/lib/ssp_ns/amd64/Makefile @@ -0,0 +1,19 @@ +# +# 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 ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) diff --git a/usr/src/lib/ssp_ns/common/ssp_ns.c b/usr/src/lib/ssp_ns/common/ssp_ns.c new file mode 100644 index 0000000000..bf7c45cd90 --- /dev/null +++ b/usr/src/lib/ssp_ns/common/ssp_ns.c @@ -0,0 +1,37 @@ +/* + * 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/ccompile.h> + +/* + * To impement gcc's stack protector library, the compiler emits a function call + * to a symbol which can be called absolutely. As a result, to make that happen, + * we mimic what gcc does with libssp and create an archive file that can be + * used in the specs file to pull this in directly. This is a bit of a pain, but + * that's the best we can do given the architecture that we have. + * + * Warning: This is a static archive. Nothing beyond the call for + * __stack_chk_fail_local and calls to committed interfaces should be here. As + * this implementation will be linked into programs, one should exercise care to + * make sure we don't expose anything else here. + */ + +extern void __stack_chk_fail(void); + +void __HIDDEN +__stack_chk_fail_local(void) +{ + __stack_chk_fail(); +} diff --git a/usr/src/lib/ssp_ns/i386/Makefile b/usr/src/lib/ssp_ns/i386/Makefile new file mode 100644 index 0000000000..c5a17a19d7 --- /dev/null +++ b/usr/src/lib/ssp_ns/i386/Makefile @@ -0,0 +1,18 @@ +# +# 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 ../Makefile.com + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/ssp_ns/sparc/Makefile b/usr/src/lib/ssp_ns/sparc/Makefile new file mode 100644 index 0000000000..c5a17a19d7 --- /dev/null +++ b/usr/src/lib/ssp_ns/sparc/Makefile @@ -0,0 +1,18 @@ +# +# 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 ../Makefile.com + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/ssp_ns/sparcv9/Makefile b/usr/src/lib/ssp_ns/sparcv9/Makefile new file mode 100644 index 0000000000..59bd9673ce --- /dev/null +++ b/usr/src/lib/ssp_ns/sparcv9/Makefile @@ -0,0 +1,19 @@ +# +# 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 ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) diff --git a/usr/src/man/man2/Makefile b/usr/src/man/man2/Makefile index 8f664a56fc..60ed81daad 100644 --- a/usr/src/man/man2/Makefile +++ b/usr/src/man/man2/Makefile @@ -155,6 +155,7 @@ MANFILES= Intro.2 \ umount.2 \ uname.2 \ unlink.2 \ + upanic.2 \ ustat.2 \ utime.2 \ utimes.2 \ diff --git a/usr/src/man/man2/upanic.2 b/usr/src/man/man2/upanic.2 new file mode 100644 index 0000000000..351b7939d0 --- /dev/null +++ b/usr/src/man/man2/upanic.2 @@ -0,0 +1,95 @@ +.\" +.\" 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 +.\" +.Dd October 31, 2020 +.Dt UPANIC 2 +.Os +.Sh NAME +.Nm upanic +.Nd user process panic +.Sh SYNOPSIS +.In upanic.h +.Ft void noreturn +.Fo upanic +.Fa "const char *msg" +.Fa "size_t len" +.Fc +.Sh DESCRIPTION +The +.Fn upanic +system call terminates the calling process and generates a core file in +the process, subject to the current core file settings as described in +.Xr core 4 +and controlled by +.Xr coreadm 1M . +.Pp +Unlike +.Xr abort 3C , +signals are not generated, which avoids two related challenges: +.Bl -enum +.It +A signal handler attempting to catch a +.Dv SIGABRT . +.It +Needing to make multiple system calls and potentially unmasking the +signal. +.El +.Pp +The +.Fn upanic +system call allows an optional message to be transmitted that will be +put in a +.Dv NT_UPANIC +elf note in the resulting core file. +If a message is not desired, then one should pass +.Dv NULL +for +.Fa msg . +In general, it is expected that +.Fa msg +is a character string with a human-readable message; however, it may +include binary data. +The system will copy +.Fa len +bytes regardless of whether the string has a NUL character to terminate +it or not. +If +.Fa msg +points to an invalid value or +.Fa len +is a size that is larger than the system's internal maximum size, then +the process will still terminate; however, this will be noted in the +.Dv NT_UPANIC +elf note. +.Pp +The +.Fn upanic +system call is illumos-specific and not portable to other systems. +For portable applications, instead use +.Xr abort 3C . +.Sh RETURN VALUES +The +.Fn upanic +system call does not return. +It always terminates the process. +.Sh INTERFACE STABILITY +.Sy Committed +.Sh MT-LEVEL +.Sy Async-Signal-Safe +.Sh SEE ALSO +.Xr elfdump 1 , +.Xr mdb 1 , +.Xr coreadm 1M , +.Xr abort 3 , +.Xr upanic.h 3HEAD , +.Xr core 4 diff --git a/usr/src/man/man3head/Makefile b/usr/src/man/man3head/Makefile index e06cc32e57..c7889080a9 100644 --- a/usr/src/man/man3head/Makefile +++ b/usr/src/man/man3head/Makefile @@ -103,6 +103,7 @@ MANFILES= acct.h.3head \ ulimit.h.3head \ un.h.3head \ unistd.h.3head \ + upanic.h.3head \ utime.h.3head \ utmpx.h.3head \ utsname.h.3head \ diff --git a/usr/src/man/man3head/upanic.h.3head b/usr/src/man/man3head/upanic.h.3head new file mode 100644 index 0000000000..871cbbda7a --- /dev/null +++ b/usr/src/man/man3head/upanic.h.3head @@ -0,0 +1,41 @@ +.\" +.\" 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 +.\" +.Dd October 31, 2020 +.Dt UPANIC.H 3HEAD +.Os +.Sh NAME +.Nm upanic.h +.Nd user panic header +.Sh SYNOPSIS +.In upanic.h +.Sh DESCRIPTION +The +.In upanic.h +header provides illumos-specific routines that provide a means for a +process to terminate itself with an optional message left in a core +file. +.Pp +The +.In upanic.h +header defines the following functions: +.Bl -tag -width upanic +.It Xr upanic 2 +Panic a user process with an optional message, terminating it and +generating core files. +.El +.Sh INTERFACE STABILITY +.Sy Committed +.Sh SEE ALSO +.Xr upanic 2 , +.Xr core 4 diff --git a/usr/src/man/man3lib/libproc.3lib b/usr/src/man/man3lib/libproc.3lib index d68897dad4..72f1a22387 100644 --- a/usr/src/man/man3lib/libproc.3lib +++ b/usr/src/man/man3lib/libproc.3lib @@ -13,7 +13,7 @@ .\" Copyright (c) 2019 Carlos Neira <cneirabustos@gmail.com> .\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association. .\" -.Dd May 22, 2020 +.Dd October 31, 2020 .Dt LIBPROC 3LIB .Os .Sh NAME @@ -240,7 +240,8 @@ manipulation of the process itself. .It Sy Pstatus Ta Sy Pstop .It Sy Pstopstatus Ta Sy Psync .It Sy Psysentry Ta Sy Psysexit -.It Sy Puname Ta Sy Punsetflags +.It Sy Puname Ta Sy Pupanic +.It Sy Pupanic_free Ta Sy Punsetflags .It Sy Pupdate_maps Ta Sy Pupdate_syms .It Sy Pwait Ta Sy Pwrite .It Sy Pxecbkpt Ta Sy Pxecwapt @@ -1208,6 +1209,8 @@ changes may occur which break both source and binary compatibility. .Xr Psysentry 3PROC , .Xr Psysexit 3PROC , .Xr Puname 3PROC , +.Xr Pupanic 3PROC , +.Xr Pupanic_free 3PROC , .Xr Punsetflags 3PROC , .Xr Pupdate_maps 3PROC , .Xr Pupdate_syms 3PROC , diff --git a/usr/src/man/man3proc/Makefile b/usr/src/man/man3proc/Makefile index 422bc9a517..a0963ce22e 100644 --- a/usr/src/man/man3proc/Makefile +++ b/usr/src/man/man3proc/Makefile @@ -161,6 +161,7 @@ MANFILES= \ Psync.3proc \ Psysentry.3proc \ Puname.3proc \ + Pupanic.3proc \ Pupdate_maps.3proc \ Pupdate_syms.3proc \ Pwrite.3proc \ @@ -265,6 +266,7 @@ MANLINKS= \ Psymbol_iter_by_lmid.3proc \ Psymbol_iter_by_name.3proc \ Psysexit.3proc \ + Pupanic_free.3proc \ Punsetflags.3proc \ Pwait.3proc \ Pxcreate.3proc \ @@ -383,6 +385,8 @@ Lclearsig.3proc := LINKSRC = Pclearsig.3proc Lsetrun.3proc := LINKSRC = Psetrun.3proc +Pupanic_free.3proc := LINKSRC = Pupanic.3proc + Pzonepath.3proc := LINKSRC = Pzonename.3proc Pzoneroot.3proc := LINKSRC = Pzonename.3proc diff --git a/usr/src/man/man3proc/Pupanic.3proc b/usr/src/man/man3proc/Pupanic.3proc new file mode 100644 index 0000000000..975ca08eec --- /dev/null +++ b/usr/src/man/man3proc/Pupanic.3proc @@ -0,0 +1,103 @@ +.\" +.\" 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 Comptuer Company +.\" +.Dd October 31, 2020 +.Dt PUPANIC 3PROC +.Os +.Sh NAME +.Nm Pupanic , +.Nm Pupanic_free +.Nd get upanic information from a core file +.Sh LIBRARY +.Lb libproc +.Sh SYNOPSIS +.In libproc.h +.Ft int +.Fo Pupanic +.Fa "struct ps_prochandle *P" +.Fa "prupanic_t **prup" +.Fc +.Ft void +.Fo Pupanic_free +.Fa "prupanic_t *pru" +.Fc +.Sh DESCRIPTION +The +.Fn Pupanic +function copies the contents of the +.Dv NT_UPANIC +elf note from the process handle +.Fa P +that corresponds to a core file into +.Fa prup . +.Pp +The library will allocate the memory needed for a +.Ft prupanic_t +and it is the caller's responsibility to release it by calling the +.Fn Pupanic_free +function with the returned data when they are done with the data. +.Pp +The allocated data stored in +.Fa prup +has a lifetime independent of the underlying process handle +.Fa P . +That is, it is safe to continue using it whether the process handle is +still valid or has been released with +.Xr Pfree 3PROC . +.Pp +If the process handle doesn't correspond to a core file or this note is +not present in the core file, then the +.Fn Pupanic +function will fail. +.Sh RETURN VALUES +Upon successful completion, the +.Fn Pupanic +function returns +.Sy 0 +and stores the allocated +.Ft prupanic_t +structure in +.Fa prup . +Otherwise +.Sy -1 +is returned +and +.Vt errno +is set to indicate the error. +.Sh ERRORS +The +.Fn Pupanic +function will fail if: +.Bl -tag -width Er +.It Er ENODATA +The process handle +.Fa P +does not correspond to a core file. +.It Er ENOENT +The core file does not have a +.Dv NT_UPANIC +elf note. +.It Er EAGAIN, Er ENOMEM +An underlying memory allocation failed. +.El +.Sh INTERFACE STABILITY +.Sy Uncommitted +.Sh MT-LEVEL +See +.Sy LOCKING +in +.Xr libproc 3LIB . +.Sh SEE ALSO +.Xr upanic 3C , +.Xr libproc 3LIB , +.Xr core 4 diff --git a/usr/src/man/man4/core.4 b/usr/src/man/man4/core.4 index a718f93159..95c7fea692 100644 --- a/usr/src/man/man4/core.4 +++ b/usr/src/man/man4/core.4 @@ -1,482 +1,583 @@ -'\" te +'\" .\" Copyright (C) 2008, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright 2012 DEY Storage Systems, Inc. All rights reserved. .\" Copyright (c) 2013, Joyent, Inc. All rights reserved. .\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association. +.\" Copyright 2020 Oxide Computer Company .\" Copyright 1989 AT&T -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH CORE 4 "Jan 6, 2020" -.SH NAME -core \- process core file -.SH DESCRIPTION +.\" +.\" The contents of this file are subject to the terms of the +.\" Common Development and Distribution License (the "License"). +.\" You may not use this file except in compliance with the License. +.\" +.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" or http://www.opensolaris.org/os/licensing. +.\" See the License for the specific language governing permissions +.\" and limitations under the License. +.\" +.\" When distributing Covered Code, include this CDDL HEADER in each +.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" If applicable, add the following below this CDDL HEADER, with the +.\" fields enclosed by brackets "[]" replaced with your own identifying +.\" information: Portions Copyright [yyyy] [name of copyright owner] +.\" +.Dd October 31, 2020 +.Dt CORE 4 +.Os +.Sh NAME +.Nm core +.Nd process core file +.Sh DESCRIPTION The operating system writes out a core file for a process when the process is -terminated due to receiving certain signals. A core file is a disk copy of the -contents of the process address space at the time the process received the -signal, along with additional information about the state of the process. This -information can be consumed by a debugger. Core files can also be generated by -applying the \fBgcore\fR(1) utility to a running process. -.sp -.LP +terminated due to receiving certain signals. +A core file is a disk copy of the contents of the process address space at the +time the process received the signal, along with additional information about +the state of the process. +This information can be consumed by a debugger. +Core files can also be generated by applying the +.Xr gcore 1 +utility to a running process. +.Pp Typically, core files are produced following abnormal termination of a process -resulting from a bug in the corresponding application. Whatever the cause, the -core file itself provides invaluable information to the programmer or support -engineer to aid in diagnosing the problem. The core file can be inspected using -a debugger such as \fBdbx\fR(1) or \fBmdb\fR(1) or by applying one of the -\fBproc\fR(1) tools. -.sp -.LP +resulting from a bug in the corresponding application. +Whatever the cause, the core file itself provides invaluable information to the +programmer or support engineer to aid in diagnosing the problem. +The core file can be inspected using a debugger such as +.Xr mdb 1 , +gdb, dbx, or or by applying one of the +.Xr proc 1 +tools. +.Pp The operating system attempts to create up to two core files for each abnormally terminating process, using a global core file name pattern and a -per-process core file name pattern. These patterns are expanded to determine -the pathname of the resulting core files, and can be configured by -\fBcoreadm\fR(1M). By default, the global core file pattern is disabled and not -used, and the per-process core file pattern is set to \fBcore\fR. Therefore, by -default, the operating system attempts to create a core file named \fBcore\fR +per-process core file name pattern. +These patterns are expanded to determine the pathname of the resulting core +files, and can be configured by +.Xr coreadm 1M . +By default, the global core file pattern is disabled and not used, and the +per-process core file pattern is set to +.Sy core . +Therefore, by default, the operating system attempts to create a core file named +.Pa core in the process's current working directory. -.sp -.LP +.Pp A process terminates and produces a core file whenever it receives one of the -signals whose default disposition is to cause a core dump. The list of signals -that result in generating a core file is shown in \fBsignal.h\fR(3HEAD). +signals whose default disposition is to cause a core dump or the +.Xr upanic 2 +system call is used. +The list of signals that result in generating a core file is shown in +.Xr signal.h 3HEAD . Therefore, a process might not produce a core file if it has blocked or -modified the behavior of the corresponding signal. Additionally, no core dump -can be created under the following conditions: -.RS +4 -.TP -.ie t \(bu -.el o +modified the behavior of the corresponding signal. +Additionally, no core dump can be created under the following conditions: +.Bl -bullet +.It If normal file and directory access permissions prevent the creation or modification of the per-process core file pathname by the current process user -and group ID. This test does not apply to the global core file pathname -because, regardless of the UID of the process dumping core, the attempt to -write the global core file is made as the superuser. -.RE -.RS +4 -.TP -.ie t \(bu -.el o -Core files owned by the user \fBnobody\fR will not be produced. For example, -core files generated for the superuser on an NFS directory are owned by -\fBnobody\fR and are, therefore, not written. -.RE -.RS +4 -.TP -.ie t \(bu -.el o +and group ID. +This test does not apply to the global core file pathname because, regardless of +the UID of the process dumping core, the attempt to write the global core file +is made as the superuser. +.It +Core files owned by the user +.Sy nobody +will not be produced. +For example, core files generated for the superuser on an NFS directory are +owned by +.Sy nobody +and are, therefore, not written. +.It If the core file pattern expands to a pathname that contains intermediate -directory components that do not exist. For example, if the global pattern is -set to \fB/var/core/%n/core.%p\fR, and no directory \fB/var/core/`uname -n`\fR +directory components that do not exist. +For example, if the global pattern is set to +.Pa /var/core/%n/core.%p , +and no directory +.Pa /var/core/`uname -n` has been created, no global core files are produced. -.RE -.RS +4 -.TP -.ie t \(bu -.el o +.It If the destination directory is part of a filesystem that is mounted read-only. -.RE -.RS +4 -.TP -.ie t \(bu -.el o -If the resource limit \fBRLIMIT_CORE\fR has been set to \fB0\fR for the -process, no per-process core file is produced. Refer to \fBsetrlimit\fR(2) and -\fBulimit\fR(1) for more information on resource limits. -.RE -.RS +4 -.TP -.ie t \(bu -.el o +.It +If the resource limit +.Dv RLIMIT_CORE +has been set to +.Sy 0 +for the +process, no per-process core file is produced. +Refer to +.Xr setrlimit 2 +and +.Xr ulimit 1 +for more information on resource limits. +.It If the core file name already exists in the destination directory and is not a -regular file (that is, is a symlink, block or character special-file, and so -forth). -.RE -.RS +4 -.TP -.ie t \(bu -.el o -If the kernel cannot open the destination file \fBO_EXCL\fR, which can occur if -same file is being created by another process simultaneously. -.RE -.RS +4 -.TP -.ie t \(bu -.el o +regular file +.Pq that is, is a symlink, block or character special-file, and so forth . +.It +If the kernel cannot open the destination file +.Dv O_EXCL , +which can occur if same file is being created by another process simultaneously. +.It If the process's effective user ID is different from its real user ID or if its -effective group ID is different from its real group ID. Similarly, set-user-ID -and set-group-ID programs do not produce core files as this could potentially -compromise system security. These processes can be explicitly granted -permission to produce core files using \fBcoreadm\fR(1M), at the risk of -exposing secure information. -.RE -.sp -.LP +effective group ID is different from its real group ID. +Similarly, set-user-ID and set-group-ID programs do not produce core files as +this could potentially compromise system security. +These processes can be explicitly granted permission to produce core files using +.Xr coreadm 1M , +at the risk of exposing secure information. +.El +.Pp The core file contains all the process information pertinent to debugging: -contents of hardware registers, process status, and process data. The format of -a core file is object file specific. -.sp -.LP -For ELF executable programs (see \fBa.out\fR(4)), the core file generated is -also an ELF file, containing ELF program and file headers. The \fBe_type\fR -field in the file header has type \fBET_CORE\fR. The program header contains an -entry for every segment that was part of the process address space, including -shared library segments. The contents of the mappings specified by -\fBcoreadm\fR(1M) are also part of the core image. Each program header has its -\fBp_memsz\fR field set to the size of the mapping. The program headers that -represent mappings whose data is included in the core file have their -\fBp_filesz\fR field set the same as \fBp_memsz\fR, otherwise \fBp_filesz\fR is -\fBzero\fR. -.sp -.LP -A mapping's data can be excluded due to the core file content settings (see -\fBcoreadm\fR(1M)), due to a failure, or due to a signal received after -core dump initiation but before its completion. If the data is excluded -because of a failure, the program header entry will have the -\fBPF_SUNW_FAILURE\fR flag -set in its \fBp_flags\fR field; if the data is excluded because of a signal, -the segment's \fBp_flags\fR field will have the \fBPF_SUNW_KILLED\fR +contents of hardware registers, process status, and process data. +The format of a core file is object file specific. +.Pp +For ELF executable programs +.Po +see +.Xr a.out 4 +.Pc , +the core file generated is also an ELF file, containing ELF program and file +headers. +The +.Fa e_type +field in the file header has type +.Dv ET_CORE . +The program header contains an entry for every segment that was part of the +process address space, including shared library segments. +The contents of the mappings specified by +.Xr coreadm 1M +are also part of the core image. +Each program header has its +.Fa p_memsz +field set to the size of the mapping. +The program headers that represent mappings whose data is included in the core +file have their +.Fa p_filesz +field set the same as +.Fa p_memsz , +otherwise +.Fa p_filesz +is +.Sy zero . +.Pp +A mapping's data can be excluded due to the core file content settings +.Po +see +.Xr coreadm 1M +.Pc , +due to a failure, or due to a signal received after core dump initiation but +before its completion. +If the data is excluded because of a failure, the program header entry will +have the +.Dv PF_SUNW_FAILURE +flag set in its +.Fa p_flags +field; if the data is excluded because of a signal, the segment's +.Fa p_flags +field will have the +.Dv PF_SUNW_KILLED flag set. -.sp -.LP -The program headers of an \fBELF\fR core file also contain entries for two -\fBNOTE\fR segments, each containing several note entries as described below. -The note entry header and core file note type (\fBn_type\fR) definitions are -contained in <\fBsys/elf.h\fR>. The first \fBNOTE\fR segment exists for binary -compatibility with old programs that deal with core files. It contains -structures defined in <\fBsys/old_procfs.h\fR>. New programs should recognize -and skip this \fBNOTE\fR segment, advancing instead to the new \fBNOTE\fR -segment. The old \fBNOTE\fR segment is deleted from core files in a future -release. -.sp -.LP -The old \fBNOTE\fR segment contains the following entries. Each has entry name -\fB"CORE"\fR and presents the contents of a system structure: -.sp -.ne 2 -.na -\fB\fBprpsinfo_t\fR\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_PRPSINFO\fR. This entry contains information of interest to -the \fBps\fR(1) command, such as process status, \fBCPU\fR usage, \fBnice\fR -value, controlling terminal, user-ID, process-ID, the name of the executable, -and so forth. The \fBprpsinfo_t\fR structure is defined in -<\fBsys/old_procfs.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBchar\fR array\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_PLATFORM\fR. This entry contains a string describing the -specific model of the hardware platform on which this core file was created. -This information is the same as provided by \fBsysinfo\fR(2) when invoked with -the command \fBSI_PLATFORM\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBauxv_t\fR array\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_AUXV\fR. This entry contains the array of \fBauxv_t\fR +.Pp +The program headers of an +.Sy ELF +core file also contain entries for two +.Sy NOTE +segments, each containing several note entries as described below. +The note entry header and core file note type +.Pq Fa n_type +definitions are contained in +.In sys/elf.h . +The first +.Sy NOTE +segment exists for binary compatibility with old programs that deal with core +files. +It contains structures defined in +.In sys/old_procfs.h . +New programs should recognize and skip this +.Sy BNOTE +segment, advancing instead to the new +.Sy NOTE +segment. +The old +.Sy NOTE +segment is deleted from core files in a future release. +.Pp +The old +.Sy NOTE +segment contains the following entries. +Each has entry name +.Sy "CORE" +and presents the contents of a system structure: +.Bl -tag -width prpsinfo_t +.It Vt prpsinfo_t +.Fa n_type : +.Dv NT_PRPSINFO . +This entry contains information of interest to the +.Xr ps 1 +command, such as process status, CPU usage, nice value, controlling terminal, +user-ID, process-ID, the name of the executable, and so forth. +The +.Vt prpsinfo_t +structure is defined in +.In sys/old_procfs.h . +.It Vt char[] +.Fa n_type : +.Dv NT_PLATFORM . +This entry contains a string describing the specific model of the hardware +platform on which this core file was created. +This information is the same as provided by +.Xr sysinfo 2 +when invoked with the command +.Dv SI_PLATFORM . +.It Vt auxv_t[] +.Fa n_type : +.Dv NT_AUXV . +This entry contains the array of +.Vt Bauxv_t structures that was passed by the operating system as startup information to -the dynamic linker. Auxiliary vector information is defined in -<\fBsys/auxv.h\fR>. -.RE - -.sp -.LP +the dynamic linker. +Auxiliary vector information is defined in +.In sys/auxv.h . +.El +.Pp Following these entries, for each active (non-zombie) light-weight process -(LWP) in the process, the old \fBNOTE\fR segment contains an entry with a -\fBprstatus_t\fR structure, plus other optionally-present entries describing -the LWP, as follows: -.sp -.ne 2 -.na -\fB\fBprstatus_t\fR\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_PRSTATUS\fR. This structure contains things of interest to -a debugger from the operating system, such as the general registers, signal -dispositions, state, reason for stopping, process-ID, and so forth. The -\fBprstatus_t\fR structure is defined in <\fBsys/old_procfs.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBprfpregset_t\fR\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_PRFPREG\fR. This entry is present only if the \fBLWP\fR -used the floating-point hardware. It contains the floating-point registers. The -\fBprfpregset_t\fR structure is defined in <\fBsys/procfs_isa.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBgwindows_t\fR\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_GWINDOWS\fR. This entry is present only on a SPARC machine -and only if the system was unable to flush all of the register windows to the -stack. It contains all of the unspilled register windows. The \fBgwindows_t\fR -structure is defined in <\fBsys/regset.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBprxregset_t\fR\fR -.ad -.RS 16n -\fBn_type\fR: \fBNT_PRXREG\fR. This entry is present only if the machine has -extra register state associated with it. It contains the extra register state. -The \fBprxregset_t\fR structure is defined in <\fBsys/procfs_isa.h\fR>. -.RE - -.sp -.LP -The new \fBNOTE\fR segment contains the following entries. Each has entry name -"\fBCORE\fR" and presents the contents of a system structure: -.sp -.ne 2 -.na -\fB\fBpsinfo_t\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_PSINFO\fR. This structure contains information of interest -to the \fBps\fR(1) command, such as process status, \fBCPU\fR usage, \fBnice\fR -value, controlling terminal, user-ID, process-ID, the name of the executable, -and so forth. The \fBpsinfo_t\fR structure is defined in <\fBsys/procfs.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBpstatus_t\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_PSTATUS\fR. This structure contains things of interest to a -debugger from the operating system, such as pending signals, state, process-ID, -and so forth. The \fBpstatus_t\fR structure is defined in <\fBsys/procfs.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBchar\fR array\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_PLATFORM\fR. This entry contains a string describing the -specific model of the hardware platform on which this core file was created. -This information is the same as provided by \fBsysinfo\fR(2) when invoked with -the command \fBSI_PLATFORM\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBauxv_t\fR array\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_AUXV\fR. This entry contains the array of \fBauxv_t\fR +.Pq LWP +in the process, the old +.Sy NOTE +segment contains an entry with a +.Vt prstatus_t +structure, plus other optionally-present entries describing the LWP, as follows: +.Bl -tag -width "prfpregset_t" +.It Vt prstatus_t +.Fa n_type : +.Dv NT_PRSTATUS . +This structure contains things of interest to a debugger from the operating +system, such as the general registers, signal dispositions, state, reason for +stopping, process-ID, and so forth. +The +.Vt prstatus_t +structure is defined in +.In sys/old_procfs.h . +.It Vt prfpregset_t +.Fa n_type : +.Dv NT_PRFPREG . +This entry is present only if the +.Sy BLWP +used the floating-point hardware. +It contains the floating-point registers. +The +.Vt prfpregset_t +structure is defined in +.In sys/procfs_isa.h . +.It Vt gwindows_t +.Fa n_type : +.Dv NT_GWINDOWS . +This entry is present only on a SPARC machine and only if the system was unable +to flush all of the register windows to the stack. +It contains all of the unspilled register windows. +The +.Vt gwindows_t +structure is defined in +.In sys/regset.h . +.It Vt prxregset_t +.Fa n_type : +.Dv NT_PRXREG . +This entry is present only if the machine has extra register state associated +with it. +It contains the extra register state. +The +.Vt prxregset_t +structure is defined in +.Vt sys/procfs_isa.h . +.El +.Pp +The new +.Sy NOTE +segment contains the following entries. +Each has entry name +.Sy "CORE" +and presents the contents of a system structure: +.Bl -tag -width prxregset_t +.It Vt psinfo_t +.Fa n_type : +.Dv NT_PSINFO . +This structure contains information of interest to the +.Xr ps 1 +command, such as process status, CPU usage, nice value, controlling terminal, +user-ID, process-ID, the name of the executable, and so forth. +The +.Vt psinfo_t +structure is defined in +.In sys/procfs.h +.It Vt pstatus_t +.Fa n_type : +.Dv NT_PSTATUS . +This structure contains things of interest to a debugger from the operating +system, such as pending signals, state, process-ID, and so forth. +The +.Vt pstatus_t +structure is defined in +.In sys/procfs.h . +.It Vt char[] +.Fa n_type : +.Dv NT_PLATFORM . +This entry contains a string describing the specific model of the hardware +platform on which this core file was created. +This information is the same as provided by +.Xr sysinfo 2 +when invoked with the command +.Dv SI_PLATFORM . +.It auxv_t[] +.Fa n_type : +.Dv NT_AUXV . +This entry contains the array of +.Vt auxv_t structures that was passed by the operating system as startup information to -the dynamic linker. Auxiliary vector information is defined in -<\fBsys/auxv.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBstruct utsname\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_UTSNAME\fR. This structure contains the system information -that would have been returned to the process if it had performed a -\fBuname\fR(2) system call prior to dumping core. The \fButsname\fR structure -is defined in <\fBsys/utsname.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBprcred_t\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_PRCRED\fR. This structure contains the process credentials, -including the real, saved, and effective user and group IDs. The \fBprcred_t\fR -structure is defined in <\fBsys/procfs.h\fR>. Following the structure is an -optional array of supplementary group IDs. The total number of supplementary -group IDs is given by the \fBpr_ngroups\fR member of the \fBprcred_t\fR -structure, and the structure includes space for one supplementary group. If -\fBpr_ngroups\fR is greater than 1, there is \fBpr_ngroups - 1\fR \fBgid_t\fR +the dynamic linker. +Auxiliary vector information is defined in +.In sys/auxv.h . +.It Vt struct utsname +.Fa n_type : +.Dv NT_UTSNAME . +This structure contains the system information that would have been returned +to the process if it had performed a +.Xr uname 2 +system call prior to dumping core. +The +.Vt utsname +structure is defined in +.In sys/utsname.h . +.It pcred_t +.Fa n_type : +.Dv NT_PRCRED . +This structure contains the process credentials, including the real, saved, +and effective user and group IDs. +The +.Vt pcred_t +structure is defined in +.In sys/procfs.h . +Following the structure is an optional array of supplementary group IDs. +The total number of supplementary group IDs is given by the +.Fa pr_ngroups +member of the +.Vt pcred_t +structure, and the structure includes space for one supplementary group. +If +.Fa pr_ngroups +is greater than 1, there is +.So +.Fa pr_ngroups +- 1 +.Sc +.Fa gid_t items following the structure; otherwise, there is no additional data. -.RE - -.sp -.ne 2 -.na -\fB\fBchar array\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_ZONENAME\fR. This entry contains a string which describes -the name of the zone in which the process was running. See \fBzones\fR(5). The -information is the same as provided by \fBgetzonenamebyid\fR(3C) when invoked -with the numerical ID returned by \fBgetzoneid\fR(3C). -.RE - -.sp -.ne 2 -.na -\fB\fBprfdinfo_core_t\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_FDINFO\fR. This structure contains information about -any open file descriptors, including the path, flags, and -\fBstat\fR(2) information. The \fBprfdinfo_core_t\fR structure is defined in -<\fBsys/procfs.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBstruct ssd\fR array\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_LDT\fR. This entry is present only on an 32-bit x86 machine -and only if the process has set up a Local Descriptor Table (LDT). It contains -an array of structures of type \fBstruct ssd\fR, each of which was typically -used to set up the \fB%gs\fR segment register to be used to fetch the address -of the current thread information structure in a multithreaded process. The -\fBssd\fR structure is defined in <\fBsys/sysi86.h\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBcore_content_t\fR\fR -.ad -.RS 20n -\fBn_type\fR: \fBNT_CONTENT\fR. This optional entry indicates which parts of -the process image are specified to be included in the core file. See -\fBcoreadm\fR(1M). -.RE - -.sp -.LP -Following these entries, for each active and zombie \fBLWP\fR in the process, -the new \fBNOTE\fR segment contains an entry with an \fBlwpsinfo_t\fR structure -plus, for a non-zombie LWP, an entry with an \fBlwpstatus_t\fR structure, plus -other optionally-present entries describing the LWP, as follows. A zombie LWP -is a non-detached LWP that has terminated but has not yet been reaped by -another LWP in the same process. -.sp -.ne 2 -.na -\fB\fBlwpsinfo_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_LWPSINFO\fR. This structure contains information of -interest to the \fBps\fR(1) command, such as \fBLWP\fR status, \fBCPU\fR usage, -\fBnice\fR value, \fBLWP-ID\fR, and so forth. The \fBlwpsinfo_t\fR structure is -defined in <\fBsys/procfs.h\fR>. This is the only entry present for a zombie -LWP. -.RE - -.sp -.ne 2 -.na -\fB\fBlwpstatus_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_LWPSTATUS\fR. This structure contains things of interest to -a debugger from the operating system, such as the general registers, the -floating point registers, state, reason for stopping, \fBLWP-ID\fR, and so -forth. The \fBlwpstatus_t\fR structure is defined in <\fBsys/procfs.h>\fR>. -.RE - -.sp -.ne 2 -.na -\fB\fBgwindows_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_GWINDOWS\fR. This entry is present only on a SPARC machine -and only if the system was unable to flush all of the register windows to the -stack. It contains all of the unspilled register windows. The \fBgwindows_t\fR -structure is defined in \fB<sys/regset.h>\fR\&. -.RE - -.sp -.ne 2 -.na -\fB\fBprxregset_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_PRXREG\fR. This entry is present only if the machine has -extra register state associated with it. It contains the extra register state. -The \fBprxregset_t\fR structure is defined in \fB<sys/procfs_isa.h>\fR\&. -.RE - -.sp -.ne 2 -.na +.It Vt char[] +.Fa n_type : +.Dv NT_ZONENAME . +This entry contains a string which describes the name of the zone in +which the process was running. +See +.Xr zones 5 . +The information is the same as provided by +.Xr getzonenamebyid 3C +when invoked with the numerical ID returned by +.Xr getzoneid 3C . +.It Vt prfdinfo_core_t +.Fa n_type : +.Dv NT_FDINFO . +This structure contains information about any open file descriptors, including +the path, flags, and +.Xr stat 2 +information. +The +.Vt prfdinfo_core_t +structure is defined in +.In sys/procfs.h . +.It Vt struct ssd[] +.Fa n_type : +.Dv NT_LDT . +This entry is present only on an 32-bit x86 machine and only if the process has +set up a Local Descriptor Table +.Pq LDT . +It contains an array of structures of type +.Vt struct ssd , +each of which was typically used to set up the +.Sy %gs +segment register to be used to fetch the address of the current thread +information structure in a multithreaded process. +The +.Vt ssd +structure is defined in +.In sys/sysi86.h . +.It Vt core_content_t +.Fa n_type : +.Dv NT_CONTENT . +This optional entry indicates which parts of the process image are specified +to be included in the core file. +See +.Xr coreadm 1M . +.It Vt prsecflags_t +.Fa n_type : +.Dv NT_SECFLAGS . +This entry contains the process security-flags, see +.Xr security-flags 5 , +.Xr proc 4 , +and +.Xr psecflags 1 +for more information. +.It Vt prupanic_t +.Fa n_type : +.Dv NT_UPANIC . +This entry is included if a process terminated through the +.Xr upanic 2 +system call. +It is defined in +.In sys/procfs.h . +.Pp +The +.Fa pru_version +member indicates the current revision of the structure, which is expected to be +.Dv PRUPANIC_VERSION_1 +.Pq 1 . +The +.Fa pru_flags +member will be set to the bitwise-inclusive-OR of the following fields: +.Bl -tag -offset indent -width PRUPANIC_FLAG_MSG_TRUNC +.It Dv PRUPANIC_FLAG_MSG_VALID +Indicates that +.Fa pru_data +member has valid contents and that the process provided a message in the +.Xr upanic 2 +call . +.It Dv PRUPANIC_FLAG_MSG_ERROR +Indicates that the calling process attempted to include a message; however, the +provided address of the message did not point to valid memory. +.It Dv PRUPANIC_FLAG_MSG_TRUNC +Indicates that the calling process included a message; however, the message it +wanted to provide was larger than the current message length. +.El +The +.Fa pru_data +array contains binary data that the terminating process used to indicate that +the reason why it panicked. +This member should be ignored if the +.Dv PRUPANIC_FLAG_MSG_VALID +flag is not set in +.Fa pru_flags . +While it is recommended that processes terminate with an ASCII string, consumers +of this should not assume that the binary data is made of of printable +characters. +.El +.Pp +For each active and zombie +.Sy LWP +in the process, +the new +.Sy NOTE +segment contains an entry with an +.Vt lwpsinfo_t +structure plus, for a non-zombie LWP, an entry with an +.Vt lwpstatus_t +structure, plus other optionally-present entries describing the LWP, as follows. +A zombie LWP is a non-detached LWP that has terminated but has not yet been +reaped by another LWP in the same process. +.Bl -tag -width "prxregset_t" +.It Vt lwpsinfo_t +.Fa n_type : +.Dv NT_LWPSINFO . +This structure contains information of interest to the +.Xr ps 1 +command, such as LWP status, CPU usage, nice value, LWP-ID, and so forth. +The +.Vt lwpsinfo_t +structure is defined in +.In sys/procfs.h . +This is the only entry present for a zombie LWP. +.It lwpstatus_t +.Fa n_type : +.Dv NT_LWPSTATUS . +This structure contains things of interest to a debugger from the operating +system, such as the general registers, the floating point registers, state, +reason for stopping, LWP-ID, and so forth. +The +.Vt lwpstatus_t +structure is defined in +.In sys/procfs.h . +.Vt gwindows_t +.Fa n_type : +.Dv NT_GWINDOWS . +This entry is present only on a SPARC machine and only if the system was unable +to flush all of the register windows to the stack. +It contains all of the unspilled register windows. +The +.Vt gwindows_t +structure is defined in +.In sys/regset.h . +.It Vt prxregset_t +.Fa n_type : +.Dv NT_PRXREG . +This entry is present only if the machine has extra register state associated +with it. +It contains the extra register state. +The +.Vt prxregset_t +structure is defined in +.In sys/procfs_isa.h . +.It Vt asrset_t \fB\fBasrset_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_ASRS\fR. This entry is present only on a SPARC V9 machine -and only if the process is a 64-bit process. It contains the ancillary state -registers for the \fBLWP.\fR The \fBasrset_t\fR structure is defined in -\fB<sys/regset.h>\fR\&. -.RE - -.sp -.ne 2 -.na -\fB\fBpsinfo_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_SPYMASTER\fR. This entry is present only for an agent -LWP and contains the \fBpsinfo_t\fR of the process that created the agent -LWP. See the \fBproc\fR(4) description of the \fBspymaster\fR entry for -more details. -.RE - -.sp -.ne 2 -.na -\fB\fBprsecflags_t\fR\fR -.ad -.RS 15n -\fBn_type\fR: \fBNT_SECFLAGS\fR. This entry contains the process -security-flags, see \fBsecurity-flags\fR(5), \fBproc\fR(4), and -\fBpsecflags\fR(1) for more information. -.RE - -.sp -.LP -Depending on the \fBcoreadm\fR(1M) settings, the section header of an ELF core -file can contain entries for CTF, symbol table, and string table sections. The -\fBsh_addr\fR fields are set to the base address of the first mapping of the -load object that they came from to. This can be used to match those sections -with the corresponding load object. -.sp -.LP +.Fa n_type : +.Dv NT_ASRS . +This entry is present only on a SPARC V9 machine and only if the process is a +64-bit process. +It contains the ancillary state registers for the LWP. +The +.Vt asrset_t asrset_t +structure is defined in +.In sys/regset.h . +.It Vt psinfo_t +.Fa n_type : +.Dv NT_SPYMASTER . +This entry is present only for an agent LWP and contains the +.Vt psinfo_t +of the process that created the agent LWP. +See the +.Xr proc 4 description of the +.Sy spymaster +entry for more details. +.El +.Pp +Depending on the +.Xr coreadm 1M +settings, the section header of an ELF core file can contain entries for CTF, +symbol table, and string table sections. +The +.Fa sh_addr +fields are set to the base address of the first mapping of the load object that +they came from to. +This can be used to match those sections with the corresponding load object. +.Pp The size of the core file created by a process can be controlled by the user -(see \fBgetrlimit\fR(2)). -.SH SEE ALSO -\fBelfdump\fR(1), \fBgcore\fR(1), \fBmdb\fR(1), \fBproc\fR(1), \fBps\fR(1), -\fBcoreadm\fR(1M), \fBgetrlimit\fR(2), \fBsetrlimit\fR(2), \fBsetuid\fR(2), -\fBsysinfo\fR(2), \fBuname\fR(2), \fBgetzonenamebyid\fR(3C), -\fBgetzoneid\fR(3C), \fBelf\fR(3ELF), \fBsignal.h\fR(3HEAD), \fBa.out\fR(4), -\fBproc\fR(4), \fBzones\fR(5), \fBsecurity-flags\fR(5) -.sp -.LP -\fIANSI C Programmer's Guide\fR +.Po +see +.Xr getrlimit 2 +.Pc +.Sh SEE ALSO +.Xr elfdump 1 , +.Xr gcore 1 , +.Xr mdb 1 , +.Xr proc 1 , +.Xr ps 1 , +.Xr coreadm 1M , +.Xr getrlimit 2 , +.Xr setrlimit 2 , +.Xr setuid 2 , +.Xr sysinfo 2 , +.Xr uname 2 , +.Xr upanic 2 , +.Xr getzoneid 3C , +.Xr getzonenamebyid 3C , +.Xr elf 3ELF , +.Xr signal.h 3HEAD , +.Xr a.out 4 , +.Xr proc 4 , +.Xr security-flags 5 , +.Xr zones 5 diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf index 6ad8abf015..167851a8cb 100644 --- a/usr/src/pkg/manifests/system-header.mf +++ b/usr/src/pkg/manifests/system-header.mf @@ -1616,6 +1616,7 @@ file path=usr/include/umem.h file path=usr/include/umem_impl.h file path=usr/include/unctrl.h file path=usr/include/unistd.h +file path=usr/include/upanic.h file path=usr/include/user_attr.h file path=usr/include/userdefs.h file path=usr/include/ustat.h @@ -1921,6 +1922,7 @@ file path=usr/share/man/man3head/uio.h.3head file path=usr/share/man/man3head/ulimit.h.3head file path=usr/share/man/man3head/un.h.3head file path=usr/share/man/man3head/unistd.h.3head +file path=usr/share/man/man3head/upanic.h.3head file path=usr/share/man/man3head/utime.h.3head file path=usr/share/man/man3head/utmpx.h.3head file path=usr/share/man/man3head/utsname.h.3head diff --git a/usr/src/pkg/manifests/system-kernel.man2.inc b/usr/src/pkg/manifests/system-kernel.man2.inc index 6a45a39b55..493f86c642 100644 --- a/usr/src/pkg/manifests/system-kernel.man2.inc +++ b/usr/src/pkg/manifests/system-kernel.man2.inc @@ -151,6 +151,7 @@ file path=usr/share/man/man2/umask.2 file path=usr/share/man/man2/umount.2 file path=usr/share/man/man2/uname.2 file path=usr/share/man/man2/unlink.2 +file path=usr/share/man/man2/upanic.2 file path=usr/share/man/man2/ustat.2 file path=usr/share/man/man2/utime.2 file path=usr/share/man/man2/utimes.2 diff --git a/usr/src/pkg/manifests/system-library-c-runtime.mf b/usr/src/pkg/manifests/system-library-c-runtime.mf index 2151c03897..2b8bd7aafd 100644 --- a/usr/src/pkg/manifests/system-library-c-runtime.mf +++ b/usr/src/pkg/manifests/system-library-c-runtime.mf @@ -18,6 +18,7 @@ set name=variant.arch value=$(ARCH) file path=usr/lib/$(ARCH64)/crt1.o file path=usr/lib/$(ARCH64)/crti.o file path=usr/lib/$(ARCH64)/crtn.o +file path=usr/lib/$(ARCH64)/libssp_ns.a file path=usr/lib/$(ARCH64)/values-Xa.o file path=usr/lib/$(ARCH64)/values-Xc.o file path=usr/lib/$(ARCH64)/values-Xs.o @@ -27,6 +28,7 @@ file path=usr/lib/$(ARCH64)/values-xpg6.o file path=usr/lib/crt1.o file path=usr/lib/crti.o file path=usr/lib/crtn.o +file path=usr/lib/libssp_ns.a file path=usr/lib/values-Xa.o file path=usr/lib/values-Xc.o file path=usr/lib/values-Xs.o diff --git a/usr/src/pkg/manifests/system-library.man3proc.inc b/usr/src/pkg/manifests/system-library.man3proc.inc index 66edc6e142..c3388bb920 100644 --- a/usr/src/pkg/manifests/system-library.man3proc.inc +++ b/usr/src/pkg/manifests/system-library.man3proc.inc @@ -97,6 +97,7 @@ file path=usr/share/man/man3proc/Psymbol_iter.3proc file path=usr/share/man/man3proc/Psync.3proc file path=usr/share/man/man3proc/Psysentry.3proc file path=usr/share/man/man3proc/Puname.3proc +file path=usr/share/man/man3proc/Pupanic.3proc file path=usr/share/man/man3proc/Pupdate_maps.3proc file path=usr/share/man/man3proc/Pupdate_syms.3proc file path=usr/share/man/man3proc/Pwrite.3proc @@ -227,6 +228,7 @@ link path=usr/share/man/man3proc/Psymbol_iter_by_name.3proc \ target=Psymbol_iter.3proc link path=usr/share/man/man3proc/Psysexit.3proc target=Psysentry.3proc link path=usr/share/man/man3proc/Punsetflags.3proc target=Psetflags.3proc +link path=usr/share/man/man3proc/Pupanic_free.3proc target=Pupanic.3proc link path=usr/share/man/man3proc/Pwait.3proc target=Pstopstatus.3proc link path=usr/share/man/man3proc/Pxcreate.3proc target=Pcreate.3proc link path=usr/share/man/man3proc/Pxecwapt.3proc target=Pxecbkpt.3proc diff --git a/usr/src/stand/lib/Makefile.com b/usr/src/stand/lib/Makefile.com index 3c90551d8c..e5b9d21909 100644 --- a/usr/src/stand/lib/Makefile.com +++ b/usr/src/stand/lib/Makefile.com @@ -137,4 +137,10 @@ DHCPCPPFLAGS = -I$(CMNNETDIR)/dhcp # SOCKCPPFLAGS = -I$(STANDDIR)/lib/sock -D_SYS_STREAM_H +# +# Using Makefile.lib pulls in the stack protector. Explicitly disable it +# as it is not initialized or supported in this environment currently. +# +STACKPROTECT = none + .KEEP_STATE: diff --git a/usr/src/tools/Makefile.tools b/usr/src/tools/Makefile.tools index aeb9449af3..9fd747751d 100644 --- a/usr/src/tools/Makefile.tools +++ b/usr/src/tools/Makefile.tools @@ -63,6 +63,13 @@ LDFLAGS= $(MAPFILE.NES:%=-Wl,-M%) $(MAPFILE.NED:%=-Wl,-M%) \ # tools. GSHARED = -_cc=-G -_gcc=-shared +# +# To work around a bootstrapping problem, we don't assume that the +# compiler or environment are properly configured to make the stack +# protector work. Disable it right now for the tools. +# +STACKPROTECT = none + # Unset CW_LINKER so we run the default. We don't set LD here to avoid taking # the journey through LD_ALTEXEC unnecessarily. CW_LINKER= 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 /* diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index 636eebcb94..39166ec07f 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -129,36 +129,6 @@ CFLAGS += $(SPACEFLAG) CFLAGS += $(CCUNBOUND) CFLAGS += $(CFLAGS_uts) CFLAGS += -xstrconst - -# -# Options to control which version of stack-protector we enable. This -# gives us a bit of flexibility and is unfortunately necessary as some -# modules do not function correctly with our defaults (qede). -# -# o STACKPROTECT_ Sets the appropriate version for the compiler -# o STACKPROTECT_strong Sets us to use strong on all of the -# compilers it supports. This is the same -# as the default. -# -# o STACKPROTECT_none Disables the stack protector. -# -# o STACKPROTECT_all Enables it for everything. -# -# o STACKPROTECT_basic Enables the basic stack protector. -# -# -fstack-protector-strong is not available in our gcc4 which is why we -# have per-compiler versions below. -# -STACKPROTECT_ = -_gcc4=-fstack-protector -STACKPROTECT_ += -_gcc7=-fstack-protector-strong -STACKPROTECT_ += -_gcc8=-fstack-protector-strong -STACKPROTECT_ += -_gcc9=-fstack-protector-strong - -STACKPROTECT_strong = $(STACKPROTECT_) -STACKPROTECT_none = -_gcc=-fstack-protector-none -STACKPROTECT_all = -_gcc=-fstack-protector-all -STACKPROTECT_basic = -_gcc=-fstack-protector - CFLAGS += $(STACKPROTECT_$(STACKPROTECT)) ASFLAGS_XARCH_32 = $(i386_ASFLAGS) diff --git a/usr/src/uts/intel/os/name_to_sysnum b/usr/src/uts/intel/os/name_to_sysnum index 7fd73f512d..dd7b5ca3bb 100644 --- a/usr/src/uts/intel/os/name_to_sysnum +++ b/usr/src/uts/intel/os/name_to_sysnum @@ -118,6 +118,7 @@ readv 121 writev 122 preadv 123 pwritev 124 +upanic 125 getrandom 126 mmapobj 127 setrlimit 128 diff --git a/usr/src/uts/sparc/os/name_to_sysnum b/usr/src/uts/sparc/os/name_to_sysnum index 2db2e10d3a..9455163907 100644 --- a/usr/src/uts/sparc/os/name_to_sysnum +++ b/usr/src/uts/sparc/os/name_to_sysnum @@ -116,6 +116,7 @@ readv 121 writev 122 preadv 123 pwritev 124 +upanic 125 getrandom 126 mmapobj 127 setrlimit 128 |