diff options
Diffstat (limited to 'usr/src/lib')
43 files changed, 911 insertions, 45 deletions
diff --git a/usr/src/lib/auditd_plugins/syslog/systoken.c b/usr/src/lib/auditd_plugins/syslog/systoken.c index 7df46acf03..ce0c267176 100644 --- a/usr/src/lib/auditd_plugins/syslog/systoken.c +++ b/usr/src/lib/auditd_plugins/syslog/systoken.c @@ -1471,6 +1471,24 @@ privilege_token(parse_context_t *ctx) return (0); } +/* + * ----------------------------------------------------------------------- + * secflags_token() : Process secflags token and display contents + * + * Format of privilege token: + * secflags token id adr_char + * secflag set name adr_string + * secflags adr_string + * ----------------------------------------------------------------------- + */ +int +secflags_token(parse_context_t *ctx) +{ + skip_bytes(ctx); + skip_bytes(ctx); + + return (0); +} /* * Format of label token: diff --git a/usr/src/lib/auditd_plugins/syslog/systoken.h b/usr/src/lib/auditd_plugins/syslog/systoken.h index 0d3f1acee4..0c6b418831 100644 --- a/usr/src/lib/auditd_plugins/syslog/systoken.h +++ b/usr/src/lib/auditd_plugins/syslog/systoken.h @@ -98,6 +98,7 @@ extern void group_token(); extern void label_token(adr_t *, parse_context_t *); extern void privilege_token(adr_t *, parse_context_t *); extern void useofpriv_token(adr_t *, parse_context_t *); +extern void secflags_token(adr_t *, parse_context_t *); extern void zonename_token(adr_t *, parse_context_t *); extern void liaison_token(adr_t *, parse_context_t *); extern void newgroup_token(adr_t *, parse_context_t *); diff --git a/usr/src/lib/brand/ipkg/zone/config.xml b/usr/src/lib/brand/ipkg/zone/config.xml index 48857db50b..56616408e3 100644 --- a/usr/src/lib/brand/ipkg/zone/config.xml +++ b/usr/src/lib/brand/ipkg/zone/config.xml @@ -81,6 +81,7 @@ <privilege set="default" name="proc_audit" /> <privilege set="default" name="proc_lock_memory" /> <privilege set="default" name="proc_owner" /> + <privilege set="default" name="proc_secflags" /> <privilege set="default" name="proc_setid" /> <privilege set="default" name="proc_taskid" /> <privilege set="default" name="sys_acct" /> diff --git a/usr/src/lib/brand/labeled/zone/config.xml b/usr/src/lib/brand/labeled/zone/config.xml index 61db7bcbf3..dace07aac3 100644 --- a/usr/src/lib/brand/labeled/zone/config.xml +++ b/usr/src/lib/brand/labeled/zone/config.xml @@ -82,6 +82,7 @@ <privilege set="default" name="proc_audit" /> <privilege set="default" name="proc_lock_memory" /> <privilege set="default" name="proc_owner" /> + <privilege set="default" name="proc_secflags" /> <privilege set="default" name="proc_setid" /> <privilege set="default" name="proc_taskid" /> <privilege set="default" name="sys_acct" /> diff --git a/usr/src/lib/brand/sn1/zone/config.xml b/usr/src/lib/brand/sn1/zone/config.xml index ccbb08cf23..70cf37f931 100644 --- a/usr/src/lib/brand/sn1/zone/config.xml +++ b/usr/src/lib/brand/sn1/zone/config.xml @@ -75,6 +75,7 @@ <privilege set="default" name="proc_audit" /> <privilege set="default" name="proc_lock_memory" /> <privilege set="default" name="proc_owner" /> + <privilege set="default" name="proc_secflags" /> <privilege set="default" name="proc_setid" /> <privilege set="default" name="proc_taskid" /> <privilege set="default" name="sys_acct" /> diff --git a/usr/src/lib/libbsm/adt_record.dtd.1 b/usr/src/lib/libbsm/adt_record.dtd.1 index 0a40554c03..b65fe38353 100644 --- a/usr/src/lib/libbsm/adt_record.dtd.1 +++ b/usr/src/lib/libbsm/adt_record.dtd.1 @@ -280,6 +280,13 @@ first token (which is the record token): set-type CDATA #REQUIRED > +<!-- secflags token --> +<!ELEMENT secflags (#PCDATA)> +<!ATTLIST secflags + set-type CDATA #REQUIRED +> + + <!-- use_of_privilege token --> <!ELEMENT use_of_privilege (#PCDATA)> <!ATTLIST use_of_privilege diff --git a/usr/src/lib/libbsm/adt_record.xsl.1 b/usr/src/lib/libbsm/adt_record.xsl.1 index 5c19e548b3..fc3f323309 100644 --- a/usr/src/lib/libbsm/adt_record.xsl.1 +++ b/usr/src/lib/libbsm/adt_record.xsl.1 @@ -283,6 +283,14 @@ <xsl:value-of select="."/> </xsl:template> +<xsl:template match="secflags"> + <BR/> + <I>SECFLAGS: </I> + <I> set-type: </I><xsl:value-of select="@set-type"/> + <BR/> + <xsl:value-of select="."/> +</xsl:template> + <xsl:template match="sensitivity_label"> <BR/> <I>SENSITIVITY_LABEL: </I> <xsl:value-of select="."/> diff --git a/usr/src/lib/libbsm/audit_event.txt b/usr/src/lib/libbsm/audit_event.txt index 123af31251..1e87e1a21a 100644 --- a/usr/src/lib/libbsm/audit_event.txt +++ b/usr/src/lib/libbsm/audit_event.txt @@ -360,6 +360,7 @@ 309:AUE_FACCESSAT:faccessat(2):no 310:AUE_AUDITON_GETAMASK:auditon(2) - get default user preselection mask:aa 311:AUE_AUDITON_SETAMASK:auditon(2) - set default user preselection mask:as +312:AUE_PSECFLAGS:psecflags(2) - set process security flags:pm # # user level audit events # 2048 - 6143 Reserved diff --git a/usr/src/lib/libbsm/auditxml b/usr/src/lib/libbsm/auditxml index 6107b059eb..81d10d8aa1 100644 --- a/usr/src/lib/libbsm/auditxml +++ b/usr/src/lib/libbsm/auditxml @@ -613,6 +613,7 @@ sub generateTableC { 'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id 'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id 'return' => 'AUT_RETURN', + 'secflags' => 'AUT_SECFLAGS', # 'seq' => 'AUT_SEQ', # not defined # 'socket' => 'AUT_SOCKET', # not defined # 'socket-inet' => 'AUT_SOCKET_INET', diff --git a/usr/src/lib/libbsm/common/adt.xml b/usr/src/lib/libbsm/common/adt.xml index 894ff2fec9..d16c904bc0 100644 --- a/usr/src/lib/libbsm/common/adt.xml +++ b/usr/src/lib/libbsm/common/adt.xml @@ -984,7 +984,7 @@ Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. <external opt="none"/> </entry> </event> - + <event id="AUE_pool_import" header="0" idNo="45" omit="JNI"> <program>hald</program> <entry id="subject"> @@ -2609,6 +2609,8 @@ Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. </token> <token id="groups"> </token> + <token id="secflags"> + </token> <!-- the iport token take a single argument of type uint16_t if there are any other tokens following it that have arguments diff --git a/usr/src/lib/libc/Makefile.targ b/usr/src/lib/libc/Makefile.targ index bb9ccf467d..d78aace6d0 100644 --- a/usr/src/lib/libc/Makefile.targ +++ b/usr/src/lib/libc/Makefile.targ @@ -295,6 +295,10 @@ $(DTRACEOBJS:%=pics/%): $(SRC)/common/dtrace/$$(@F:.o=.c) $(COMPILE.c) -o $@ $(SRC)/common/dtrace/$(@F:.o=.c) $(POST_PROCESS_O) +$(SECFLAGSOBJS:%=pics/%): $(SRC)/common/secflags/$$(@F:.o=.c) + $(COMPILE.c) -o $@ $(SRC)/common/secflags/$(@F:.o=.c) + $(POST_PROCESS_O) + $(UNICODEOBJS:%=pics/%): $(SRC)/common/unicode/$$(@F:.o=.c) $(COMPILE.c) -o $@ $(SRC)/common/unicode/$(@F:.o=.c) $(POST_PROCESS_O) diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index b5514c4bed..a50c8d84be 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -246,6 +246,7 @@ COMSYSOBJS= \ processor_bind.o \ processor_info.o \ profil.o \ + psecflagsset.o \ putmsg.o \ putpmsg.o \ pwrite.o \ @@ -499,6 +500,7 @@ PORTGEN= \ priocntl.o \ privlib.o \ priv_str_xlate.o \ + psecflags.o \ psiginfo.o \ psignal.o \ pt.o \ @@ -812,6 +814,9 @@ RTOBJS= \ shm.o \ sigev_thread.o +SECFLAGSOBJS= \ + secflags.o + TPOOLOBJS= \ thread_pool.o @@ -965,6 +970,7 @@ MOSTOBJS= \ $(PORTSYS64) \ $(AIOOBJS) \ $(RTOBJS) \ + $(SECFLAGSOBJS) \ $(TPOOLOBJS) \ $(THREADSOBJS) \ $(THREADSMACHOBJS) \ @@ -1093,6 +1099,7 @@ SRCS= \ $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ $(THREADSMACHOBJS:%.o=threads/%.c) \ diff --git a/usr/src/lib/libc/common/sys/brk.s b/usr/src/lib/libc/common/sys/brk.s index fbd2f4c135..fe1413769d 100644 --- a/usr/src/lib/libc/common/sys/brk.s +++ b/usr/src/lib/libc/common/sys/brk.s @@ -37,5 +37,5 @@ ENTRY_NP(_brk_unlocked) SYSTRAP_RVAL1(brk) SYSCERROR - RETC + RET SET_SIZE(_brk_unlocked) diff --git a/usr/src/lib/libc/common/sys/psecflagsset.s b/usr/src/lib/libc/common/sys/psecflagsset.s new file mode 100644 index 0000000000..d47d3d8595 --- /dev/null +++ b/usr/src/lib/libc/common/sys/psecflagsset.s @@ -0,0 +1,21 @@ +/* + * 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 2015, Richard Lowe */ + + .file "psecflagsset.s" + +#include <sys/asm_linkage.h> +#include "SYS.h" + + SYSCALL2_RVAL1(__psecflagsset,psecflags) + RET + SET_SIZE(__psecflagsset) diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index d3176ce802..4f855d43da 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -113,6 +113,9 @@ COMOBJS= \ DTRACEOBJS= \ dtrace_data.o +SECFLAGSOBJS= \ + secflags.o + GENOBJS= \ $(COMMPAGE_OBJS) \ _div64.o \ @@ -270,6 +273,7 @@ COMSYSOBJS= \ processor_bind.o \ processor_info.o \ profil.o \ + psecflagsset.o \ putmsg.o \ putpmsg.o \ pwrite.o \ @@ -532,6 +536,7 @@ PORTGEN= \ priocntl.o \ privlib.o \ priv_str_xlate.o \ + psecflags.o \ psiginfo.o \ psignal.o \ pt.o \ @@ -1008,6 +1013,7 @@ MOSTOBJS= \ $(PORTSYS64) \ $(AIOOBJS) \ $(RTOBJS) \ + $(SECFLAGSOBJS) \ $(TPOOLOBJS) \ $(THREADSOBJS) \ $(THREADSMACHOBJS) \ @@ -1157,6 +1163,7 @@ SRCS= \ $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ diff --git a/usr/src/lib/libc/port/gen/priv_str_xlate.c b/usr/src/lib/libc/port/gen/priv_str_xlate.c index 9796a2d858..60ed80c122 100644 --- a/usr/src/lib/libc/port/gen/priv_str_xlate.c +++ b/usr/src/lib/libc/port/gen/priv_str_xlate.c @@ -72,8 +72,8 @@ priv_basic(void) */ priv_set_t * priv_str_to_set(const char *priv_names, - const char *separators, - const char **endptr) + const char *separators, + const char **endptr) { char *base; diff --git a/usr/src/lib/libc/port/gen/psecflags.c b/usr/src/lib/libc/port/gen/psecflags.c new file mode 100644 index 0000000000..5fe15df88c --- /dev/null +++ b/usr/src/lib/libc/port/gen/psecflags.c @@ -0,0 +1,112 @@ +/* + * 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 2015, Richard Lowe. */ + +#include "lint.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +#include <sys/proc.h> +#include <sys/procset.h> +#include <sys/syscall.h> +#include <sys/secflags.h> + +extern int __psecflagsset(procset_t *, psecflagwhich_t, secflagdelta_t *); + +int +psecflags(idtype_t idtype, id_t id, psecflagwhich_t which, + secflagdelta_t *delta) +{ + procset_t procset; + + setprocset(&procset, POP_AND, idtype, id, P_ALL, 0); + + return (__psecflagsset(&procset, which, delta)); +} + +int +secflags_parse(const secflagset_t *defaults, const char *flags, + secflagdelta_t *ret) +{ + char *flag; + char *s, *ss; + boolean_t current = B_FALSE; + + /* Guarantee a clean base */ + bzero(ret, sizeof (*ret)); + + if ((ss = s = strdup(flags)) == NULL) + return (-1); /* errno set for us */ + + + while ((flag = strsep(&s, ",")) != NULL) { + secflag_t sf = 0; + boolean_t del = B_FALSE; + + if (strcasecmp(flag, "default") == 0) { + if (defaults != NULL) { + secflags_union(&ret->psd_add, defaults); + } else { + free(ss); + errno = EINVAL; + return (-1); + } + continue; + } else if (strcasecmp(flag, "all") == 0) { + secflags_fullset(&ret->psd_add); + continue; + } else if (strcasecmp(flag, "none") == 0) { + secflags_fullset(&ret->psd_rem); + continue; + } else if (strcasecmp(flag, "current") == 0) { + current = B_TRUE; + continue; + } + + if ((flag[0] == '-') || (flag[0] == '!')) { + flag++; + del = B_TRUE; + } else if (flag[0] == '+') { + flag++; + } + + if ((secflag_by_name(flag, &sf)) != B_TRUE) { + free(ss); + errno = EINVAL; + return (-1); + } + + if (del) + secflag_set(&(ret->psd_rem), sf); + else + secflag_set(&(ret->psd_add), sf); + } + + /* + * If we're not using the current flags, this is strict assignment. + * Negatives "win". + */ + if (!current) { + secflags_copy(&ret->psd_assign, &ret->psd_add); + secflags_difference(&ret->psd_assign, &ret->psd_rem); + ret->psd_ass_active = B_TRUE; + secflags_zero(&ret->psd_add); + secflags_zero(&ret->psd_rem); + } + + free(ss); + return (0); +} diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 98efe9ed72..9185b621bc 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -3053,6 +3053,7 @@ $endif option_to_attr; __priv_bracket; __priv_relinquish; + psecflags; pset_assign_forced; pset_bind_lwp; _psignal; @@ -3069,6 +3070,26 @@ $endif _rpcsys; _sbrk_grow_aligned; scrwidth; + secflag_by_name; + secflag_clear; + secflags_copy; + secflags_difference; + secflags_fullset; + secflags_intersection; + secflags_isempty; + secflag_isset; + secflags_issubset; + secflags_issuperset; + secflag_set; + secflag_to_bit; + secflag_to_str; + secflags_union; + psecflags_validate_delta; + secflags_zero; + psecflags_default; + secflags_parse; + secflags_to_str; + psecflags_validate; semctl64; _semctl64; set_escaped_context_cleanup; diff --git a/usr/src/lib/libc/port/sys/sbrk.c b/usr/src/lib/libc/port/sys/sbrk.c index 156f7bd797..d7224599dd 100644 --- a/usr/src/lib/libc/port/sys/sbrk.c +++ b/usr/src/lib/libc/port/sys/sbrk.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #pragma weak _sbrk = sbrk #pragma weak _brk = brk @@ -40,12 +38,11 @@ #include "mtlib.h" #include "libc.h" -extern int _end; -void *_nd = &_end; +void *_nd = NULL; mutex_t __sbrk_lock = DEFAULTMUTEX; -extern int _brk_unlocked(void *); -extern void *_sbrk_unlocked(intptr_t); +extern intptr_t _brk_unlocked(void *); +void *_sbrk_unlocked(intptr_t); /* * The break must always be at least 8-byte aligned @@ -87,8 +84,15 @@ sbrk(intptr_t addend) void * _sbrk_unlocked(intptr_t addend) { - char *old_brk = BRKALIGN(_nd); - char *new_brk = BRKALIGN(old_brk + addend); + char *old_brk; + char *new_brk; + + if (_nd == NULL) { + _nd = (void *)_brk_unlocked(0); + } + + old_brk = BRKALIGN(_nd); + new_brk = BRKALIGN(old_brk + addend); if ((addend > 0 && new_brk < old_brk) || (addend < 0 && new_brk > old_brk)) { @@ -118,7 +122,7 @@ _sbrk_grow_aligned(size_t min_size, size_t low_align, size_t high_align, uintptr_t ret_brk; uintptr_t high_brk; uintptr_t new_brk; - int brk_result; + intptr_t brk_result; if (!primary_link_map) { errno = ENOTSUP; @@ -134,6 +138,9 @@ _sbrk_grow_aligned(size_t min_size, size_t low_align, size_t high_align, lmutex_lock(&__sbrk_lock); + if (_nd == NULL) + _nd = (void *)_brk_unlocked(0); + old_brk = (uintptr_t)BRKALIGN(_nd); ret_brk = P2ROUNDUP(old_brk, low_align); high_brk = ret_brk + min_size; @@ -163,7 +170,16 @@ _sbrk_grow_aligned(size_t min_size, size_t low_align, size_t high_align, int brk(void *new_brk) { - int result; + intptr_t result; + + /* + * brk(2) will return the current brk if given an argument of 0, so we + * need to fail it here + */ + if (new_brk == 0) { + errno = ENOMEM; + return (-1); + } if (!primary_link_map) { errno = ENOTSUP; diff --git a/usr/src/lib/libc/req.flg b/usr/src/lib/libc/req.flg index 79170e532a..b501dc546b 100644 --- a/usr/src/lib/libc/req.flg +++ b/usr/src/lib/libc/req.flg @@ -23,9 +23,9 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" find_files "s.*" usr/src/common/atomic -find_files "s.*" usr/src/common/util find_files "s.*" usr/src/common/dtrace +find_files "s.*" usr/src/common/secflags +find_files "s.*" usr/src/common/util find_files "s.*" usr/src/lib/common diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index c525f28b3d..164515f9d3 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -136,6 +136,9 @@ COMOBJS= \ DTRACEOBJS= \ dtrace_data.o +SECFLAGSOBJS= \ + secflags.o + GENOBJS= \ _getsp.o \ _xregs_clrptr.o \ @@ -285,6 +288,7 @@ COMSYSOBJS= \ processor_bind.o \ processor_info.o \ profil.o \ + psecflagsset.o \ putmsg.o \ putpmsg.o \ pwrite.o \ @@ -558,6 +562,7 @@ PORTGEN= \ priocntl.o \ privlib.o \ priv_str_xlate.o \ + psecflags.o \ psiginfo.o \ psignal.o \ pt.o \ @@ -1039,6 +1044,7 @@ MOSTOBJS= \ $(PORTSYS64) \ $(AIOOBJS) \ $(RTOBJS) \ + $(SECFLAGSOBJS) \ $(TPOOLOBJS) \ $(THREADSOBJS) \ $(THREADSMACHOBJS) \ @@ -1181,6 +1187,7 @@ SRCS= \ $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index ff896639e2..56f8980f36 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -269,6 +269,7 @@ COMSYSOBJS= \ processor_bind.o \ processor_info.o \ profil.o \ + psecflagsset.o \ putmsg.o \ putpmsg.o \ pwrite.o \ @@ -519,6 +520,7 @@ PORTGEN= \ priocntl.o \ privlib.o \ priv_str_xlate.o \ + psecflags.o \ psiginfo.o \ psignal.o \ pt.o \ @@ -830,6 +832,9 @@ RTOBJS= \ shm.o \ sigev_thread.o +SECFLAGSOBJS= \ + secflags.o + TPOOLOBJS= \ thread_pool.o @@ -978,6 +983,7 @@ MOSTOBJS= \ $(PORTSYS64) \ $(AIOOBJS) \ $(RTOBJS) \ + $(SECFLAGSOBJS) \ $(TPOOLOBJS) \ $(THREADSOBJS) \ $(THREADSMACHOBJS) \ @@ -1110,6 +1116,7 @@ SRCS= \ $(PORTSYS:%.o=$(LIBCDIR)/port/sys/%.c) \ $(AIOOBJS:%.o=$(LIBCDIR)/port/aio/%.c) \ $(RTOBJS:%.o=$(LIBCDIR)/port/rt/%.c) \ + $(SECFLAGSOBJS:%.o=$(SRC)/common/secflags/%.c) \ $(TPOOLOBJS:%.o=$(LIBCDIR)/port/tpool/%.c) \ $(THREADSOBJS:%.o=$(LIBCDIR)/port/threads/%.c) \ $(THREADSMACHOBJS:%.o=$(LIBCDIR)/$(MACH)/threads/%.c) \ diff --git a/usr/src/lib/libproc/common/Pcontrol.c b/usr/src/lib/libproc/common/Pcontrol.c index f9b1d9755b..f18d4cefd8 100644 --- a/usr/src/lib/libproc/common/Pcontrol.c +++ b/usr/src/lib/libproc/common/Pcontrol.c @@ -54,6 +54,7 @@ #include <sys/syscall.h> #include <sys/sysmacros.h> #include <sys/systeminfo.h> +#include <sys/secflags.h> #include "libproc.h" #include "Pcontrol.h" @@ -176,6 +177,13 @@ Pcred_live(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data) return (proc_get_cred(P->pid, pcrp, ngroups)); } +/* ARGSUSED */ +static int +Psecflags_live(struct ps_prochandle *P, prsecflags_t **psf, void *data) +{ + return (proc_get_secflags(P->pid, psf)); +} + /*ARGSUSED*/ static int Ppriv_live(struct ps_prochandle *P, prpriv_t **pprv, void *data) @@ -326,6 +334,7 @@ static const ps_ops_t P_live_ops = { .pop_uname = Puname_live, .pop_zonename = Pzonename_live, .pop_execname = Pexecname_live, + .pop_secflags = Psecflags_live, #if defined(__i386) || defined(__amd64) .pop_ldt = Pldt_live #endif @@ -424,11 +433,11 @@ dupfd(int fd, int dfd) */ struct ps_prochandle * Pxcreate(const char *file, /* executable file name */ - char *const *argv, /* argument vector */ - char *const *envp, /* environment */ - int *perr, /* pointer to error return code */ - char *path, /* if non-null, holds exec path name on return */ - size_t len) /* size of the path buffer */ + char *const *argv, /* argument vector */ + char *const *envp, /* environment */ + int *perr, /* pointer to error return code */ + char *path, /* if non-null, holds exec path name on return */ + size_t len) /* size of the path buffer */ { char execpath[PATH_MAX]; char procname[PATH_MAX]; @@ -1299,6 +1308,28 @@ Pcred(struct ps_prochandle *P, prcred_t *pcrp, int ngroups) return (P->ops.pop_cred(P, pcrp, ngroups, P->data)); } +/* Return an allocated prsecflags_t */ +int +Psecflags(struct ps_prochandle *P, prsecflags_t **psf) +{ + int ret; + + if ((ret = P->ops.pop_secflags(P, psf, P->data)) == 0) { + if ((*psf)->pr_version != PRSECFLAGS_VERSION_1) { + errno = EINVAL; + return (-1); + } + } + + return (ret); +} + +void +Psecflags_free(prsecflags_t *psf) +{ + free(psf); +} + static prheader_t * Plstatus(struct ps_prochandle *P) { @@ -1804,8 +1835,8 @@ prdump(struct ps_prochandle *P) */ int Pstopstatus(struct ps_prochandle *P, - long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ - uint_t msec) /* if non-zero, timeout in milliseconds */ + long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ + uint_t msec) /* if non-zero, timeout in milliseconds */ { int ctlfd = (P->agentctlfd >= 0)? P->agentctlfd : P->ctlfd; long ctl[3]; @@ -2070,8 +2101,8 @@ Pputareg(struct ps_prochandle *P, int regno, prgreg_t reg) int Psetrun(struct ps_prochandle *P, - int sig, /* signal to pass to process */ - int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ + int sig, /* signal to pass to process */ + int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ { int ctlfd = (P->agentctlfd >= 0) ? P->agentctlfd : P->ctlfd; int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP); @@ -2146,18 +2177,18 @@ Psetrun(struct ps_prochandle *P, ssize_t Pread(struct ps_prochandle *P, - void *buf, /* caller's buffer */ - size_t nbyte, /* number of bytes to read */ - uintptr_t address) /* address in process */ + void *buf, /* caller's buffer */ + size_t nbyte, /* number of bytes to read */ + uintptr_t address) /* address in process */ { return (P->ops.pop_pread(P, buf, nbyte, address, P->data)); } ssize_t Pread_string(struct ps_prochandle *P, - char *buf, /* caller's buffer */ - size_t size, /* upper limit on bytes to read */ - uintptr_t addr) /* address in process */ + char *buf, /* caller's buffer */ + size_t size, /* upper limit on bytes to read */ + uintptr_t addr) /* address in process */ { enum { STRSZ = 40 }; char string[STRSZ + 1]; @@ -2193,9 +2224,9 @@ Pread_string(struct ps_prochandle *P, ssize_t Pwrite(struct ps_prochandle *P, - const void *buf, /* caller's buffer */ - size_t nbyte, /* number of bytes to write */ - uintptr_t address) /* address in process */ + const void *buf, /* caller's buffer */ + size_t nbyte, /* number of bytes to write */ + uintptr_t address) /* address in process */ { return (P->ops.pop_pwrite(P, buf, nbyte, address, P->data)); } @@ -3402,8 +3433,8 @@ Lsync(struct ps_lwphandle *L) */ static int Lstopstatus(struct ps_lwphandle *L, - long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ - uint_t msec) /* if non-zero, timeout in milliseconds */ + long request, /* PCNULL, PCDSTOP, PCSTOP, PCWSTOP */ + uint_t msec) /* if non-zero, timeout in milliseconds */ { int ctlfd = L->lwp_ctlfd; long ctl[3]; @@ -3603,8 +3634,8 @@ Lputareg(struct ps_lwphandle *L, int regno, prgreg_t reg) int Lsetrun(struct ps_lwphandle *L, - int sig, /* signal to pass to LWP */ - int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ + int sig, /* signal to pass to LWP */ + int flags) /* PRSTEP|PRSABORT|PRSTOP|PRCSIG|PRCFAULT */ { int ctlfd = L->lwp_ctlfd; int sbits = (PR_DSTOP | PR_ISTOP | PR_ASLEEP); diff --git a/usr/src/lib/libproc/common/Pcontrol.h b/usr/src/lib/libproc/common/Pcontrol.h index 5840409651..7e19e8777c 100644 --- a/usr/src/lib/libproc/common/Pcontrol.h +++ b/usr/src/lib/libproc/common/Pcontrol.h @@ -45,6 +45,7 @@ #include <libctf.h> #include <limits.h> #include <libproc.h> +#include <sys/secflags.h> #ifdef __cplusplus extern "C" { @@ -167,6 +168,7 @@ typedef struct core_info { /* information specific to core files */ void *core_privinfo; /* system privileges info from core file */ 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 */ #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 dfa4cc6600..89c5ce47fa 100644 --- a/usr/src/lib/libproc/common/Pcore.c +++ b/usr/src/lib/libproc/common/Pcore.c @@ -159,6 +159,25 @@ Pcred_core(struct ps_prochandle *P, prcred_t *pcrp, int ngroups, void *data) /*ARGSUSED*/ static int +Psecflags_core(struct ps_prochandle *P, prsecflags_t **psf, void *data) +{ + core_info_t *core = data; + + if (core->core_secflags == NULL) { + errno = ENODATA; + return (-1); + } + + if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL) + return (-1); + + (void) memcpy(*psf, core->core_secflags, sizeof (prsecflags_t)); + + return (0); +} + +/*ARGSUSED*/ +static int Ppriv_core(struct ps_prochandle *P, prpriv_t **pprv, void *data) { core_info_t *core = data; @@ -222,6 +241,8 @@ Pfini_core(struct ps_prochandle *P, void *data) free(core->core_ppii); if (core->core_zonename != NULL) free(core->core_zonename); + if (core->core_secflags != NULL) + free(core->core_secflags); #ifdef __x86 if (core->core_ldt != NULL) free(core->core_ldt); @@ -308,6 +329,7 @@ static const ps_ops_t P_core_ops = { .pop_platform = Pplatform_core, .pop_uname = Puname_core, .pop_zonename = Pzonename_core, + .pop_secflags = Psecflags_core, #ifdef __x86 .pop_ldt = Pldt_core #endif @@ -746,6 +768,34 @@ note_platform(struct ps_prochandle *P, size_t nbytes) } static int +note_secflags(struct ps_prochandle *P, size_t nbytes) +{ + core_info_t *core = P->data; + prsecflags_t *psf; + + if (core->core_secflags != NULL) + return (0); /* Already seen */ + + if (sizeof (*psf) != nbytes) { + dprintf("Pgrab_core: NT_SECFLAGS changed size." + " Need to handle a version change?\n"); + return (-1); + } + + if (nbytes != 0 && ((psf = malloc(nbytes)) != NULL)) { + if (read(P->asfd, psf, nbytes) != nbytes) { + dprintf("Pgrab_core: failed to read NT_SECFLAGS\n"); + free(psf); + return (-1); + } + + core->core_secflags = psf; + } + + return (0); +} + +static int note_utsname(struct ps_prochandle *P, size_t nbytes) { core_info_t *core = P->data; @@ -1180,6 +1230,7 @@ static int (*nhdlrs[])(struct ps_prochandle *, size_t) = { note_zonename, /* 21 NT_ZONENAME */ note_fdinfo, /* 22 NT_FDINFO */ note_spymaster, /* 23 NT_SPYMASTER */ + note_secflags, /* 24 NT_SECFLAGS */ }; static void diff --git a/usr/src/lib/libproc/common/Pgcore.c b/usr/src/lib/libproc/common/Pgcore.c index b20ce2d12a..6ddf92ad2f 100644 --- a/usr/src/lib/libproc/common/Pgcore.c +++ b/usr/src/lib/libproc/common/Pgcore.c @@ -1418,6 +1418,22 @@ Pfgcore(struct ps_prochandle *P, int fd, core_content_t content) goto err; } + + { + prsecflags_t *psf = NULL; + + if (Psecflags(P, &psf) != 0) + goto err; + + if (write_note(fd, NT_SECFLAGS, psf, + sizeof (prsecflags_t), &doff) != 0) { + Psecflags_free(psf); + goto err; + } + + Psecflags_free(psf); + } + #if defined(__i386) || defined(__amd64) /* CSTYLED */ { @@ -1501,6 +1517,7 @@ err: */ (void) ftruncate64(fd, 0); free(pgc.pgc_chunk); + return (-1); } diff --git a/usr/src/lib/libproc/common/Pidle.c b/usr/src/lib/libproc/common/Pidle.c index c69bcaf860..db00268f9b 100644 --- a/usr/src/lib/libproc/common/Pidle.c +++ b/usr/src/lib/libproc/common/Pidle.c @@ -112,6 +112,7 @@ static const ps_ops_t P_idle_ops = { .pop_pwrite = Pwrite_idle, .pop_cred = (pop_cred_t)Pidle_int, .pop_priv = Ppriv_idle, + .pop_secflags = (pop_secflags_t)Pidle_int, .pop_psinfo = (pop_psinfo_t)Pidle_voidp, .pop_platform = (pop_platform_t)Pidle_voidp, .pop_uname = (pop_uname_t)Pidle_int, diff --git a/usr/src/lib/libproc/common/Putil.c b/usr/src/lib/libproc/common/Putil.c index f6f2aa862e..e42ac08de5 100644 --- a/usr/src/lib/libproc/common/Putil.c +++ b/usr/src/lib/libproc/common/Putil.c @@ -194,6 +194,7 @@ static const ps_ops_t P_default_ops = { .pop_uname = (pop_uname_t)Pdefault_int, .pop_zonename = (pop_zonename_t)Pdefault_voidp, .pop_execname = (pop_execname_t)Pdefault_voidp, + .pop_secflags = (pop_secflags_t)Pdefault_int, #if defined(__i386) || defined(__amd64) .pop_ldt = (pop_ldt_t)Pdefault_int #endif @@ -239,6 +240,8 @@ Pinit_ops(ps_ops_t *dst, const ps_ops_t *src) dst->pop_zonename = src->pop_zonename; if (src->pop_execname != NULL) dst->pop_execname = src->pop_execname; + if (src->pop_secflags != NULL) + dst->pop_secflags = src->pop_secflags; #if defined(__i386) || defined(__amd64) if (src->pop_ldt != NULL) dst->pop_ldt = src->pop_ldt; diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index de01309025..d74c08e828 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -55,6 +55,7 @@ #include <sys/socket.h> #include <sys/utsname.h> #include <sys/corectl.h> +#include <sys/secflags.h> #if defined(__i386) || defined(__amd64) #include <sys/sysi86.h> #endif @@ -192,6 +193,7 @@ typedef void (*pop_read_aux_t)(struct ps_prochandle *, auxv_t **, int *, typedef int (*pop_cred_t)(struct ps_prochandle *, prcred_t *, int, void *); typedef int (*pop_priv_t)(struct ps_prochandle *, prpriv_t **, void *); +typedef int (*pop_secflags_t)(struct ps_prochandle *, prsecflags_t **, void *); typedef const psinfo_t *(*pop_psinfo_t)(struct ps_prochandle *, psinfo_t *, void *); typedef void (*pop_status_t)(struct ps_prochandle *, pstatus_t *, void *); @@ -222,6 +224,7 @@ typedef struct ps_ops { pop_uname_t pop_uname; pop_zonename_t pop_zonename; pop_execname_t pop_execname; + pop_secflags_t pop_secflags; #if defined(__i386) || defined(__amd64) pop_ldt_t pop_ldt; #endif @@ -270,6 +273,8 @@ extern int Psetzoneid(struct ps_prochandle *, zoneid_t); extern int Pgetareg(struct ps_prochandle *, int, prgreg_t *); extern int Pputareg(struct ps_prochandle *, int, prgreg_t); extern int Psetrun(struct ps_prochandle *, int, int); +extern int Psecflags(struct ps_prochandle *, prsecflags_t **); +extern void Psecflags_free(prsecflags_t *); extern ssize_t Pread(struct ps_prochandle *, void *, size_t, uintptr_t); extern ssize_t Pread_string(struct ps_prochandle *, char *, size_t, uintptr_t); extern ssize_t Pwrite(struct ps_prochandle *, const void *, size_t, uintptr_t); @@ -696,6 +701,7 @@ extern prpriv_t *proc_get_priv(pid_t); extern void proc_free_priv(prpriv_t *); extern int proc_get_psinfo(pid_t, psinfo_t *); extern int proc_get_status(pid_t, pstatus_t *); +extern int proc_get_secflags(pid_t, prsecflags_t **); /* * Utility functions for debugging tools to convert numeric fault, diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers index a79e9d74a2..b3f9df9d97 100644 --- a/usr/src/lib/libproc/common/mapfile-vers +++ b/usr/src/lib/libproc/common/mapfile-vers @@ -212,6 +212,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { proc_get_cred; proc_get_priv; proc_get_psinfo; + proc_get_secflags; proc_get_status; proc_initstdio; proc_lwp_in_set; @@ -278,6 +279,8 @@ SYMBOL_VERSION SUNWprivate_1.1 { ps_ptread { FLAGS = NODYNSORT }; # Alias of ps_pread ps_ptwrite { FLAGS = NODYNSORT }; # Alias of ps_pwrite ps_pwrite; + Psecflags; + Psecflags_free; Pstack_iter; Pstate; Pstatus; diff --git a/usr/src/lib/libproc/common/proc_get_info.c b/usr/src/lib/libproc/common/proc_get_info.c index e0817c543f..19a84e060e 100644 --- a/usr/src/lib/libproc/common/proc_get_info.c +++ b/usr/src/lib/libproc/common/proc_get_info.c @@ -32,6 +32,7 @@ #include <fcntl.h> #include <string.h> #include <limits.h> +#include <sys/secflags.h> #include "Pcontrol.h" @@ -68,6 +69,27 @@ proc_get_cred(pid_t pid, prcred_t *credp, int ngroups) return (rv); } +int +proc_get_secflags(pid_t pid, prsecflags_t **psf) +{ + char fname[PATH_MAX]; + int fd; + int rv = -1; + + if ((*psf = calloc(1, sizeof (prsecflags_t))) == NULL) + return (-1); + + (void) snprintf(fname, sizeof (fname), "%s/%d/secflags", + procfs_path, (int)pid); + if ((fd = open(fname, O_RDONLY)) >= 0) { + if (read(fd, *psf, sizeof (prsecflags_t)) == + sizeof (prsecflags_t)) + rv = 0; + (void) close(fd); + } + return (rv); +} + void proc_free_priv(prpriv_t *prv) { diff --git a/usr/src/lib/librestart/common/librestart.c b/usr/src/lib/librestart/common/librestart.c index 671cdf99ea..cebaf54884 100644 --- a/usr/src/lib/librestart/common/librestart.c +++ b/usr/src/lib/librestart/common/librestart.c @@ -53,6 +53,7 @@ #include <syslog.h> #include <sys/corectl.h> #include <sys/machelf.h> +#include <sys/secflags.h> #include <sys/task.h> #include <sys/types.h> #include <time.h> @@ -2843,7 +2844,7 @@ restarter_get_method_context(uint_t version, scf_instance_t *inst, (prop = scf_property_create(h)) == NULL || (val = scf_value_create(h)) == NULL) { err = mc_error_create(err, scf_error(), - "Failed to create repository object: %s\n", + "Failed to create repository object: %s", scf_strerror(scf_error())); goto out; } @@ -2895,7 +2896,7 @@ restarter_get_method_context(uint_t version, scf_instance_t *inst, goto out; default: err = mc_error_create(err, ret, - "Get method environment failed : %s\n", scf_strerror(ret)); + "Get method environment failed: %s", scf_strerror(ret)); goto out; } @@ -3103,6 +3104,82 @@ restarter_get_method_context(uint_t version, scf_instance_t *inst, } } + /* get security flags */ + if ((methpg != NULL && scf_pg_get_property(methpg, + SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS) || + (instpg != NULL && scf_pg_get_property(instpg, + SCF_PROPERTY_SECFLAGS, prop) == SCF_SUCCESS)) { + if (scf_property_get_value(prop, val) != SCF_SUCCESS) { + ret = scf_error(); + switch (ret) { + case SCF_ERROR_CONNECTION_BROKEN: + err = mc_error_create(err, ret, RCBROKEN); + break; + + case SCF_ERROR_CONSTRAINT_VIOLATED: + err = mc_error_create(err, ret, + "\"%s\" property has multiple values.", + SCF_PROPERTY_SECFLAGS); + break; + + case SCF_ERROR_NOT_FOUND: + err = mc_error_create(err, ret, + "\"%s\" property has no values.", + SCF_PROPERTY_SECFLAGS); + break; + + default: + bad_fail("scf_property_get_value", ret); + } + + (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz); + } else { + ret = scf_value_get_astring(val, cip->vbuf, + cip->vbuf_sz); + assert(ret != -1); + } + mc_used++; + } else { + ret = scf_error(); + switch (ret) { + case SCF_ERROR_NOT_FOUND: + /* okay if missing. */ + (void) strlcpy(cip->vbuf, ":default", cip->vbuf_sz); + break; + + case SCF_ERROR_CONNECTION_BROKEN: + err = mc_error_create(err, ret, RCBROKEN); + goto out; + + case SCF_ERROR_DELETED: + err = mc_error_create(err, ret, + "Property group could not be found"); + goto out; + + case SCF_ERROR_HANDLE_MISMATCH: + case SCF_ERROR_INVALID_ARGUMENT: + case SCF_ERROR_NOT_SET: + default: + bad_fail("scf_pg_get_property", ret); + } + } + + + if (scf_default_secflags(h, &cip->def_secflags) != 0) { + err = mc_error_create(err, EINVAL, "couldn't fetch " + "default security-flags"); + goto out; + } + + if (strcmp(cip->vbuf, ":default") != 0) { + if (secflags_parse(NULL, cip->vbuf, + &cip->secflag_delta) != 0) { + err = mc_error_create(err, EINVAL, "couldn't parse " + "security flags: %s", cip->vbuf); + goto out; + } + } + /* get (optional) corefile pattern */ if ((methpg != NULL && scf_pg_get_property(methpg, SCF_PROPERTY_COREFILE_PATTERN, prop) == SCF_SUCCESS) || @@ -3343,6 +3420,12 @@ restarter_get_method_context(uint_t version, scf_instance_t *inst, cip->gid = 0; cip->euid = (uid_t)-1; cip->egid = (gid_t)-1; + + if (scf_default_secflags(h, &cip->def_secflags) != 0) { + err = mc_error_create(err, EINVAL, "couldn't fetch " + "default security-flags"); + goto out; + } } *mcpp = cip; @@ -3510,6 +3593,35 @@ restarter_set_method_context(struct method_context *cip, const char **fp) } } + + if (psecflags(P_PID, P_MYID, PSF_INHERIT, + &cip->def_secflags.ss_default) != 0) { + *fp = "psecflags (default inherit)"; + ret = errno; + goto out; + } + + if (psecflags(P_PID, P_MYID, PSF_LOWER, + &cip->def_secflags.ss_lower) != 0) { + *fp = "psecflags (default lower)"; + ret = errno; + goto out; + } + + if (psecflags(P_PID, P_MYID, PSF_UPPER, + &cip->def_secflags.ss_upper) != 0) { + *fp = "psecflags (default upper)"; + ret = errno; + goto out; + } + + if (psecflags(P_PID, P_MYID, PSF_INHERIT, + &cip->secflag_delta) != 0) { + *fp = "psecflags (from manifest)"; + ret = errno; + goto out; + } + if (restarter_rm_libs_loadable()) { if (cip->project == NULL) { if (settaskid(getprojid(), TASK_NORMAL) == -1) { diff --git a/usr/src/lib/librestart/common/librestart.h b/usr/src/lib/librestart/common/librestart.h index f5c247b7f1..9697c87db3 100644 --- a/usr/src/lib/librestart/common/librestart.h +++ b/usr/src/lib/librestart/common/librestart.h @@ -32,6 +32,7 @@ #include <priv.h> #include <pwd.h> #include <sys/types.h> +#include <sys/secflags.h> #ifdef __cplusplus extern "C" { @@ -265,7 +266,7 @@ int restarter_remove_contract(scf_instance_t *, ctid_t, ssize_t restarter_state_to_string(restarter_instance_state_t, char *, size_t); restarter_instance_state_t restarter_string_to_state(char *); -#define RESTARTER_METHOD_CONTEXT_VERSION 7 +#define RESTARTER_METHOD_CONTEXT_VERSION 8 struct method_context { /* Stable */ @@ -273,6 +274,8 @@ struct method_context { gid_t gid, egid; int ngroups; /* -1 means use initgroups(). */ gid_t groups[NGROUPS_MAX]; + scf_secflags_t def_secflags; + secflagdelta_t secflag_delta; priv_set_t *lpriv_set, *priv_set; char *corefile_pattern; /* Optional. */ char *project; /* NULL for no change */ diff --git a/usr/src/lib/libscf/common/highlevel.c b/usr/src/lib/libscf/common/highlevel.c index dddd551e51..7defe4ef51 100644 --- a/usr/src/lib/libscf/common/highlevel.c +++ b/usr/src/lib/libscf/common/highlevel.c @@ -33,10 +33,12 @@ #include <assert.h> #include <libuutil.h> #include <string.h> +#include <strings.h> #include <stdlib.h> #include <sys/systeminfo.h> #include <sys/uadmin.h> #include <sys/utsname.h> +#include <sys/secflags.h> #ifdef __x86 #include <smbios.h> @@ -353,3 +355,86 @@ scf_is_fastboot_default(void) return (boot_config & boot_config_ovr & UA_FASTREBOOT_DEFAULT); } + +/* + * Read the default security-flags from system/process-security and return a + * secflagset_t suitable for psecflags(2) + * + * Unfortunately, this symbol must _exist_ in the native build, for the sake + * of the mapfile, even though we don't ever use it, and it will never work. + */ +struct group_desc { + secflagdelta_t *delta; + char *fmri; +}; + +int +scf_default_secflags(scf_handle_t *hndl, scf_secflags_t *flags) +{ +#if !defined(NATIVE_BUILD) + scf_property_t *prop; + scf_value_t *val; + const char *flagname; + int flag; + struct group_desc *g; + struct group_desc groups[] = { + {NULL, "svc:/system/process-security/" + ":properties/default"}, + {NULL, "svc:/system/process-security/" + ":properties/lower"}, + {NULL, "svc:/system/process-security/" + ":properties/upper"}, + {NULL, NULL} + }; + + bzero(flags, sizeof (*flags)); + + groups[0].delta = &flags->ss_default; + groups[1].delta = &flags->ss_lower; + groups[2].delta = &flags->ss_upper; + + for (g = groups; g->delta != NULL; g++) { + for (flag = 0; (flagname = secflag_to_str(flag)) != NULL; + flag++) { + char *pfmri; + uint8_t flagval = 0; + + if ((val = scf_value_create(hndl)) == NULL) + return (-1); + + if ((prop = scf_property_create(hndl)) == NULL) { + scf_value_destroy(val); + return (-1); + } + + if ((pfmri = uu_msprintf("%s/%s", g->fmri, + flagname)) == NULL) + uu_die("Allocation failure\n"); + + if (scf_handle_decode_fmri(hndl, pfmri, + NULL, NULL, NULL, NULL, prop, NULL) != 0) + goto next; + + if (scf_property_get_value(prop, val) != 0) + goto next; + + (void) scf_value_get_boolean(val, &flagval); + + if (flagval != 0) + secflag_set(&g->delta->psd_add, flag); + else + secflag_set(&g->delta->psd_rem, flag); + +next: + uu_free(pfmri); + scf_value_destroy(val); + scf_property_destroy(prop); + } + } + + return (0); +#else + assert(0); + abort(); +#endif /* !NATIVE_BUILD */ +} diff --git a/usr/src/lib/libscf/common/mapfile-vers b/usr/src/lib/libscf/common/mapfile-vers index 643f5424f2..049912185c 100644 --- a/usr/src/lib/libscf/common/mapfile-vers +++ b/usr/src/lib/libscf/common/mapfile-vers @@ -328,6 +328,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { scf_get_boot_config_ovr; scf_is_fastboot_default; scf_fastreboot_default_set_transient; + scf_default_secflags; _check_services; _scf_handle_create_and_bind; _smf_refresh_all_instances; diff --git a/usr/src/lib/libscf/inc/libscf.h b/usr/src/lib/libscf/inc/libscf.h index 1940308f92..72005e668e 100644 --- a/usr/src/lib/libscf/inc/libscf.h +++ b/usr/src/lib/libscf/inc/libscf.h @@ -29,9 +29,13 @@ #include <stddef.h> -#include <sys/types.h> #include <libnvpair.h> +#ifndef NATIVE_BUILD +#include <sys/secflags.h> +#endif /* NATIVE_BUILD */ +#include <sys/types.h> + #ifdef __cplusplus extern "C" { #endif @@ -198,6 +202,26 @@ typedef enum scf_tmpl_error_type { typedef struct scf_tmpl_error scf_tmpl_error_t; /* + * This unfortunately needs to be public, because consumers of librestart must + * deal with it + */ +typedef struct { +#ifndef NATIVE_BUILD + secflagdelta_t ss_default; + secflagdelta_t ss_lower; + secflagdelta_t ss_upper; +#else + /* + * This is never used, but is necessary for bootstrapping. + * Not even the size matters. + */ + void *ss_default; + void *ss_lower; + void *ss_upper; +#endif /* NATIVE_BUILD */ +} scf_secflags_t; + +/* * scf_tmpl_strerror() human readable flag */ #define SCF_TMPL_STRERROR_HUMAN 0x1 @@ -329,6 +353,7 @@ typedef struct scf_tmpl_error scf_tmpl_error_t; #define SCF_PROPERTY_RESTART_INTERVAL ((const char *)"restart_interval") #define SCF_PROPERTY_RESTART_ON ((const char *)"restart_on") #define SCF_PROPERTY_RESTORE ((const char *)"restore") +#define SCF_PROPERTY_SECFLAGS ((const char *)"security_flags") #define SCF_PROPERTY_SINGLE_INSTANCE ((const char *)"single_instance") #define SCF_PROPERTY_START_METHOD_TIMESTAMP \ ((const char *)"start_method_timestamp") diff --git a/usr/src/lib/libscf/inc/libscf_priv.h b/usr/src/lib/libscf/inc/libscf_priv.h index 3e05042e0c..3ad2564322 100644 --- a/usr/src/lib/libscf/inc/libscf_priv.h +++ b/usr/src/lib/libscf/inc/libscf_priv.h @@ -29,6 +29,9 @@ #include <libscf.h> #include <unistd.h> +#if !defined(NATIVE_BUILD) +#include <sys/secflags.h> +#endif #ifdef __cplusplus extern "C" { @@ -592,6 +595,10 @@ int _scf_get_svc_notify_params(const char *, nvlist_t *, int32_t, int, int); */ int _scf_notify_get_params(scf_propertygroup_t *, nvlist_t *); +#if !defined(NATIVE_BUILD) +int scf_default_secflags(scf_handle_t *, scf_secflags_t *); +#endif + #define SCF_NOTIFY_PARAMS_SOURCE_NAME ((const char *)"preference_source") #ifdef __cplusplus diff --git a/usr/src/lib/libsecdb/auth_attr.txt b/usr/src/lib/libsecdb/auth_attr.txt index b92b42874d..677f17613f 100644 --- a/usr/src/lib/libsecdb/auth_attr.txt +++ b/usr/src/lib/libsecdb/auth_attr.txt @@ -176,6 +176,7 @@ solaris.smf.value.inetd:::Change values of SMF Inetd configuration paramaters::h solaris.smf.value.ipsec:::Change Values of SMF IPsec Properties::help=SmfValueIPsec.html solaris.smf.value.mdns:::Change Values of MDNS Service Properties::help=SmfValueMDNS.html solaris.smf.value.nwam:::Change Values of SMF Network Auto-Magic Properties::help=SmfValueNWAM.html +solaris.smf.value.process-security:::Change Values of Process Security properties::help=SmfValueProcSec.html solaris.smf.value.smb:::Change Values of SMB Service Properties::help=SmfValueSMB.html solaris.smf.read.smb:::Read permission for protected SMF SMB Service Properties::help=AuthReadSMB.html solaris.smf.value.smtp-notify:::Change values of Email Event Notification Agent properties:: diff --git a/usr/src/lib/libsecdb/help/auths/Makefile b/usr/src/lib/libsecdb/help/auths/Makefile index 64cb5e42d5..7d69dec2a8 100644 --- a/usr/src/lib/libsecdb/help/auths/Makefile +++ b/usr/src/lib/libsecdb/help/auths/Makefile @@ -113,6 +113,7 @@ HTMLENTS = \ SmfValueNDMP.html \ AuthReadNDMP.html \ SmfValueNWAM.html \ + SmfValueProcSec.html \ SmfValueRouting.html \ SmfValueSMB.html \ AuthReadSMB.html \ diff --git a/usr/src/lib/libsecdb/help/auths/SmfValueProcSec.html b/usr/src/lib/libsecdb/help/auths/SmfValueProcSec.html new file mode 100644 index 0000000000..766e4d59f4 --- /dev/null +++ b/usr/src/lib/libsecdb/help/auths/SmfValueProcSec.html @@ -0,0 +1,26 @@ +<HTML> +<!-- + Copyright 2015, Richard Lowe. + + 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. +--> +<!-- + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> +--> +<BODY> +When Value Process Security Properties is in the Authorizations Include +column, it grants the the authorization to change the default security-flags +for processes on this system +<P> +If Value Process Security Properties is grayed, then you are not entitled to +Add or Remove this authorization. +<BR> +</BODY> +</HTML> diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index 2bd4855138..c524901d48 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -103,6 +103,7 @@ #define DTD_ELEM_OBSOLETES (const xmlChar *) "obsoletes" #define DTD_ELEM_DEV_PERM (const xmlChar *) "dev-perm" #define DTD_ELEM_ADMIN (const xmlChar *) "admin" +#define DTD_ELEM_SECFLAGS (const xmlChar *) "security-flags" #define DTD_ATTR_ACTION (const xmlChar *) "action" #define DTD_ATTR_ADDRESS (const xmlChar *) "address" @@ -144,6 +145,10 @@ #define DTD_ATTR_USER (const xmlChar *) "user" #define DTD_ATTR_AUTHS (const xmlChar *) "auths" #define DTD_ATTR_FS_ALLOWED (const xmlChar *) "fs-allowed" +#define DTD_ATTR_DEFAULT (const xmlChar *) "default" +#define DTD_ATTR_LOWER (const xmlChar *) "lower" +#define DTD_ATTR_UPPER (const xmlChar *) "upper" + #define DTD_ENTITY_BOOLEAN "boolean" #define DTD_ENTITY_DEVPATH "devpath" @@ -2928,6 +2933,7 @@ zonecfg_add_admin(zone_dochandle_t handle, struct zone_admintab *tabptr, return (Z_OK); } + static int zonecfg_delete_auth_core(zone_dochandle_t handle, struct zone_admintab *tabptr, char *zonename) @@ -3040,6 +3046,159 @@ zonecfg_lookup_admin(zone_dochandle_t handle, struct zone_admintab *tabptr) return (Z_OK); } +static int +zonecfg_add_secflags_core(zone_dochandle_t handle, + struct zone_secflagstab *tabptr) +{ + xmlNodePtr newnode, cur = handle->zone_dh_cur; + int err; + + newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_SECFLAGS, NULL); + err = newprop(newnode, DTD_ATTR_DEFAULT, tabptr->zone_secflags_default); + if (err != Z_OK) + return (err); + err = newprop(newnode, DTD_ATTR_LOWER, tabptr->zone_secflags_lower); + if (err != Z_OK) + return (err); + err = newprop(newnode, DTD_ATTR_UPPER, tabptr->zone_secflags_upper); + if (err != Z_OK) + return (err); + + return (Z_OK); +} + +int +zonecfg_add_secflags(zone_dochandle_t handle, struct zone_secflagstab *tabptr) +{ + int err; + + + if (tabptr == NULL) + return (Z_INVAL); + + if ((err = operation_prep(handle)) != Z_OK) + return (err); + + if ((err = zonecfg_add_secflags_core(handle, tabptr)) != Z_OK) + return (err); + + return (Z_OK); +} + +static int +zonecfg_delete_secflags_core(zone_dochandle_t handle, + struct zone_secflagstab *tabptr) +{ + xmlNodePtr cur = handle->zone_dh_cur; + boolean_t def_match, low_match, up_match; + + for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { + if (xmlStrcmp(cur->name, DTD_ELEM_SECFLAGS) != 0) + continue; + + def_match = match_prop(cur, DTD_ATTR_DEFAULT, + tabptr->zone_secflags_default); + low_match = match_prop(cur, DTD_ATTR_LOWER, + tabptr->zone_secflags_lower); + up_match = match_prop(cur, DTD_ATTR_UPPER, + tabptr->zone_secflags_upper); + + if (def_match && low_match && up_match) { + xmlUnlinkNode(cur); + xmlFreeNode(cur); + return (Z_OK); + } + + } + return (Z_NO_RESOURCE_ID); +} + +int +zonecfg_delete_secflags(zone_dochandle_t handle, + struct zone_secflagstab *tabptr) +{ + int err; + + if (tabptr == NULL) + return (Z_INVAL); + + if ((err = operation_prep(handle)) != Z_OK) + return (err); + + if ((err = zonecfg_delete_secflags_core(handle, tabptr)) != Z_OK) + return (err); + + return (Z_OK); +} + +int +zonecfg_modify_secflags(zone_dochandle_t handle, + struct zone_secflagstab *oldtabptr, + struct zone_secflagstab *newtabptr) +{ + int err; + + if (oldtabptr == NULL || newtabptr == NULL) + return (Z_INVAL); + + if ((err = operation_prep(handle)) != Z_OK) + return (err); + + if ((err = zonecfg_delete_secflags_core(handle, oldtabptr)) + != Z_OK) + return (err); + + if ((err = zonecfg_add_secflags_core(handle, newtabptr)) != Z_OK) + return (err); + + return (Z_OK); +} + +int +zonecfg_lookup_secflags(zone_dochandle_t handle, + struct zone_secflagstab *tabptr) +{ + xmlNodePtr cur; + int err; + + if (tabptr == NULL) + return (Z_INVAL); + + if ((err = operation_prep(handle)) != Z_OK) + return (err); + + cur = handle->zone_dh_cur; + + for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { + if (xmlStrcmp(cur->name, DTD_ELEM_SECFLAGS) != 0) + continue; + + if ((err = fetchprop(cur, DTD_ATTR_DEFAULT, + tabptr->zone_secflags_default, + sizeof (tabptr->zone_secflags_default))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_LOWER, + tabptr->zone_secflags_lower, + sizeof (tabptr->zone_secflags_lower))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_UPPER, + tabptr->zone_secflags_upper, + sizeof (tabptr->zone_secflags_upper))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + return (Z_OK); + } + + return (Z_NO_ENTRY); +} /* Lock to serialize all devwalks */ static pthread_mutex_t zonecfg_devwalk_lock = PTHREAD_MUTEX_INITIALIZER; @@ -3223,7 +3382,8 @@ zonecfg_devperms_apply(zone_dochandle_t hdl, const char *inpath, uid_t owner, */ int zonecfg_find_mounts(char *rootpath, int (*callback)(const struct mnttab *, - void *), void *priv) { + void *), void *priv) +{ FILE *mnttab; struct mnttab m; size_t l; @@ -7445,6 +7605,61 @@ zonecfg_fix_obsolete(zone_dochandle_t handle) return (res); } +int +zonecfg_getsecflagsent(zone_dochandle_t handle, + struct zone_secflagstab *tabptr) +{ + int err; + xmlNodePtr cur; + + if (handle == NULL) + return (Z_INVAL); + + if ((err = zonecfg_setent(handle)) != Z_OK) + return (err); + + + if ((cur = handle->zone_dh_cur) == NULL) + return (Z_NO_ENTRY); + + for (; cur != NULL; cur = cur->next) { + if (xmlStrcmp(cur->name, DTD_ELEM_SECFLAGS) == 0) + break; + } + + if (cur == NULL) { + handle->zone_dh_cur = handle->zone_dh_top; + return (Z_NO_ENTRY); + } + + if ((err = fetchprop(cur, DTD_ATTR_DEFAULT, + tabptr->zone_secflags_default, + sizeof (tabptr->zone_secflags_default))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_LOWER, + tabptr->zone_secflags_lower, + sizeof (tabptr->zone_secflags_lower))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_UPPER, + tabptr->zone_secflags_upper, + sizeof (tabptr->zone_secflags_upper))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + handle->zone_dh_cur = cur->next; + + (void) zonecfg_endent(handle); + + return (err); +} + /* * Get the full tree of pkg metadata in a set of nested AVL trees. * pkgs_avl is an AVL tree of pkgs. @@ -8516,7 +8731,7 @@ zonecfg_insert_userauths(zone_dochandle_t handle, char *user, char *zonename) int zonecfg_remove_userauths(zone_dochandle_t handle, char *user, char *zonename, - boolean_t deauthorize) + boolean_t deauthorize) { zone_userauths_t *new, **prev, *next; diff --git a/usr/src/lib/libzonecfg/common/mapfile-vers b/usr/src/lib/libzonecfg/common/mapfile-vers index f9a17e4962..da4009d2fa 100644 --- a/usr/src/lib/libzonecfg/common/mapfile-vers +++ b/usr/src/lib/libzonecfg/common/mapfile-vers @@ -60,6 +60,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_add_rctl; zonecfg_add_rctl_value; zonecfg_add_scratch; + zonecfg_add_secflags; zonecfg_aliased_rctl_ok; zonecfg_apply_rctls; zonecfg_attach_manifest; @@ -85,6 +86,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_delete_pset; zonecfg_delete_rctl; zonecfg_delete_scratch; + zonecfg_delete_secflags; zonecfg_del_all_resources; zonecfg_destroy; zonecfg_destroy_snapshot; @@ -140,6 +142,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_get_privset; zonecfg_getpsetent; zonecfg_getrctlent; + zonecfg_getsecflagsent; zonecfg_get_root; zonecfg_get_sched_class; zonecfg_get_scratch; @@ -166,6 +169,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_lookup_nwif; zonecfg_lookup_pset; zonecfg_lookup_rctl; + zonecfg_lookup_secflags; zonecfg_modify_admin; zonecfg_modify_attr; zonecfg_modify_dev; @@ -174,6 +178,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_modify_nwif; zonecfg_modify_pset; zonecfg_modify_rctl; + zonecfg_modify_secflags; zonecfg_notify_bind; zonecfg_notify_create; zonecfg_notify_critical_abort; diff --git a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 index 3c7198efef..228bb8ace2 100644 --- a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 +++ b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 @@ -150,10 +150,16 @@ <!ATTLIST admin user CDATA #REQUIRED auths CDATA #REQUIRED> +<!ELEMENT security-flags EMPTY> + +<!ATTLIST security-flags default CDATA "" + lower CDATA "" + upper CDATA ""> + <!ELEMENT zone (filesystem | inherited-pkg-dir | network | device | deleted-device | rctl | attr | dataset | package | patch | dev-perm | tmp_pool | pset | - mcap | admin)*> + mcap | admin | security-flags)*> <!ATTLIST zone name CDATA #REQUIRED zonepath CDATA #REQUIRED |