summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorRichard Lowe <richlowe@richlowe.net>2014-04-16 02:39:14 +0100
committerRichard Lowe <richlowe@richlowe.net>2016-10-15 12:02:16 -0400
commitd2a70789f056fc6c9ce3ab047b52126d80b0e3da (patch)
treebcf5eedbc5aeec80cac59ea37052e3b87108c253 /usr/src/cmd
parent8ab1c3f559468e655c4eb8acce993320403dd72b (diff)
downloadillumos-joyent-d2a70789f056fc6c9ce3ab047b52126d80b0e3da.tar.gz
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (ASLR) 7031 noexec_user_stack should be a security-flag 7032 want a means to forbid mappings around NULL Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net> Reviewed by: Patrick Mooney <pmooney@joyent.com> Approved by: Dan McDonald <danmcd@omniti.com>
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/auditreduce/token.c14
-rw-r--r--usr/src/cmd/praudit/praudit.xcl2
-rw-r--r--usr/src/cmd/praudit/token.c29
-rw-r--r--usr/src/cmd/praudit/toktable.c1
-rw-r--r--usr/src/cmd/praudit/toktable.h1
-rw-r--r--usr/src/cmd/priocntl/subr.c5
-rw-r--r--usr/src/cmd/ptools/Makefile5
-rw-r--r--usr/src/cmd/ptools/Makefile.bld35
-rw-r--r--usr/src/cmd/ptools/psecflags/psecflags.c318
-rw-r--r--usr/src/cmd/sgs/dump/common/dump.c19
-rw-r--r--usr/src/cmd/sgs/elfdump/common/corenote.c52
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.msg9
-rw-r--r--usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c2
-rw-r--r--usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c18
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout.c3
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout.h10
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c11
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c11
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c11
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c13
-rw-r--r--usr/src/cmd/sgs/include/conv.h10
-rw-r--r--usr/src/cmd/sgs/include/libld.h1
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.c61
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.msg6
-rw-r--r--usr/src/cmd/sgs/libconv/common/dynamic.c12
-rw-r--r--usr/src/cmd/sgs/libconv/common/dynamic.msg3
-rw-r--r--usr/src/cmd/sgs/libld/common/args.c27
-rw-r--r--usr/src/cmd/sgs/libld/common/libld.msg5
-rw-r--r--usr/src/cmd/sgs/libld/common/sections.c7
-rw-r--r--usr/src/cmd/sgs/libld/common/update.c7
-rw-r--r--usr/src/cmd/svc/dtd/service_bundle.dtd.11
-rw-r--r--usr/src/cmd/svc/milestone/Makefile1
-rw-r--r--usr/src/cmd/svc/milestone/global.xml11
-rw-r--r--usr/src/cmd/svc/milestone/process-security.xml86
-rw-r--r--usr/src/cmd/svc/milestone/restarter.xml53
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_libscf.c15
-rw-r--r--usr/src/cmd/svc/svccfg/svccfg_xml.c10
-rw-r--r--usr/src/cmd/truss/print.c95
-rw-r--r--usr/src/cmd/truss/print.h4
-rw-r--r--usr/src/cmd/truss/systable.c2
-rw-r--r--usr/src/cmd/zoneadmd/vplat.c96
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.c325
-rw-r--r--usr/src/cmd/zonecfg/zonecfg.h8
-rw-r--r--usr/src/cmd/zonecfg/zonecfg_grammar.y17
-rw-r--r--usr/src/cmd/zonecfg/zonecfg_lex.l11
45 files changed, 1373 insertions, 70 deletions
diff --git a/usr/src/cmd/auditreduce/token.c b/usr/src/cmd/auditreduce/token.c
index c1d67d910c..5153522865 100644
--- a/usr/src/cmd/auditreduce/token.c
+++ b/usr/src/cmd/auditreduce/token.c
@@ -1941,6 +1941,20 @@ privilege_token(adr_t *adr)
}
/*
+ * Format of security flags token:
+ * security flag set string
+ * security flags string
+ */
+
+int
+secflags_token(adr_t *adr)
+{
+ skip_string(adr); /* set name */
+ skip_string(adr); /* security flags */
+ return (-1);
+}
+
+/*
* Format of label token:
* label ID 1 byte
* compartment length 1 byte
diff --git a/usr/src/cmd/praudit/praudit.xcl b/usr/src/cmd/praudit/praudit.xcl
index 02dccf50f0..93bda8e4c0 100644
--- a/usr/src/cmd/praudit/praudit.xcl
+++ b/usr/src/cmd/praudit/praudit.xcl
@@ -289,3 +289,5 @@ msgid "fmri"
msgstr
msgid "user"
msgstr
+msgid "secflags"
+msgstr
diff --git a/usr/src/cmd/praudit/token.c b/usr/src/cmd/praudit/token.c
index e7d56beb9d..f930d253d5 100644
--- a/usr/src/cmd/praudit/token.c
+++ b/usr/src/cmd/praudit/token.c
@@ -2346,3 +2346,32 @@ privilege_token(pr_context_t *context)
/* privilege: */
return (pa_adr_string(context, returnstat, 1));
}
+
+/*
+ * -----------------------------------------------------------------------
+ * secflags_token() : Process privilege token and display contents
+ * return codes : -1 - error
+ * : 0 - successful
+ * NOTE: At the time of call, the secflags token id has been retrieved
+ *
+ * Format of secflags token:
+ * secflags token id adr_char
+ * secflag set name adr_string
+ * secflags adr_string
+ * -----------------------------------------------------------------------
+ */
+int
+secflags_token(pr_context_t *context)
+{
+ int returnstat;
+
+ /* Set name */
+ returnstat = process_tag(context, TAG_SETTYPE, 0, 0);
+
+ /* Done with attributes; force end of token open */
+ if (returnstat == 0)
+ returnstat = finish_open_tag(context);
+
+ /* set */
+ return (pa_adr_string(context, returnstat, 1));
+}
diff --git a/usr/src/cmd/praudit/toktable.c b/usr/src/cmd/praudit/toktable.c
index ef7f09121e..d8c71916a1 100644
--- a/usr/src/cmd/praudit/toktable.c
+++ b/usr/src/cmd/praudit/toktable.c
@@ -119,6 +119,7 @@ init_tokens(void)
table_initx(AUT_LABEL, "sensitivity label", "sensitivity_label",
label_token, T_ELEMENT);
table_init(AUT_PRIV, "privilege", privilege_token, T_EXTENDED);
+ table_init(AUT_SECFLAGS, "secflags", secflags_token, T_EXTENDED);
table_initx(AUT_UPRIV, "use of privilege", "use_of_privilege",
useofpriv_token, T_EXTENDED);
table_init(AUT_LIAISON, "liaison", liaison_token, T_ELEMENT);
diff --git a/usr/src/cmd/praudit/toktable.h b/usr/src/cmd/praudit/toktable.h
index 128686d1ec..77c11cf0ac 100644
--- a/usr/src/cmd/praudit/toktable.h
+++ b/usr/src/cmd/praudit/toktable.h
@@ -214,6 +214,7 @@ extern int attribute32_token();
extern int useofauth_token();
extern int user_token();
extern int zonename_token();
+extern int secflags_token();
/*
* X windows tokens
diff --git a/usr/src/cmd/priocntl/subr.c b/usr/src/cmd/priocntl/subr.c
index a9caf5fff5..fa03ad921f 100644
--- a/usr/src/cmd/priocntl/subr.c
+++ b/usr/src/cmd/priocntl/subr.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -72,8 +70,7 @@ int a1, a2, a3, a4, a5;
/*
* Structure defining idtypes known to the priocntl command
- * along with the corresponding names and a liberal guess
- * of the max number of procs sharing any given ID of that type.
+ * along with the corresponding names
* The idtype values themselves are defined in <sys/procset.h>.
*/
static struct idtypes {
diff --git a/usr/src/cmd/ptools/Makefile b/usr/src/cmd/ptools/Makefile
index 88806787e8..aec951e44b 100644
--- a/usr/src/cmd/ptools/Makefile
+++ b/usr/src/cmd/ptools/Makefile
@@ -54,7 +54,8 @@ NEW_SUBDIRS = \
plgrp \
pmadvise \
ppriv \
- preap
+ preap \
+ psecflags
SUBDIRS = $(LEGACY_SUBDIRS) $(NEW_SUBDIRS)
@@ -73,7 +74,7 @@ pmadvise/pmadvise.po := CPPFLAGS += -I$(PMAP)
#
# Commands with messages support
#
-POFILES = plgrp/plgrp.po pmadvise/pmadvise.po
+POFILES = plgrp/plgrp.po pmadvise/pmadvise.po psecflags/psecflags.po
POFILE = ptools.po
.KEEP_STATE:
diff --git a/usr/src/cmd/ptools/Makefile.bld b/usr/src/cmd/ptools/Makefile.bld
index f5b50f5ea1..c34bf5dc8d 100644
--- a/usr/src/cmd/ptools/Makefile.bld
+++ b/usr/src/cmd/ptools/Makefile.bld
@@ -34,23 +34,24 @@ FILEMODE = 0555
# libproc is added individually as pwait doesn't need it.
# These are defined this way so lint can use them
-LDLIBS_pargs = -lproc
-LDLIBS_pcred = -lproc
-LDLIBS_pfiles = -lproc -lnsl
-LDLIBS_pflags = -lproc
-LDLIBS_pldd = -lproc
-LDLIBS_plgrp = -lproc -llgrp
-LDLIBS_pmap = -lproc
-LDLIBS_pmadvise = -lproc
-LDLIBS_ppriv = -lproc
-LDLIBS_preap = -lproc
-LDLIBS_prun = -lproc
-LDLIBS_psig = -lproc
-LDLIBS_pstack = -lproc -lc_db
-LDLIBS_pstop = -lproc
-LDLIBS_ptime = -lproc
-LDLIBS_ptree = -lproc -lcontract
-LDLIBS_pwdx = -lproc
+LDLIBS_pargs = -lproc
+LDLIBS_pcred = -lproc
+LDLIBS_pfiles = -lproc -lnsl
+LDLIBS_pflags = -lproc
+LDLIBS_pldd = -lproc
+LDLIBS_plgrp = -lproc -llgrp
+LDLIBS_pmap = -lproc
+LDLIBS_pmadvise = -lproc
+LDLIBS_ppriv = -lproc
+LDLIBS_preap = -lproc
+LDLIBS_prun = -lproc
+LDLIBS_psecflags = -lproc -lproject
+LDLIBS_psig = -lproc
+LDLIBS_pstack = -lproc -lc_db
+LDLIBS_pstop = -lproc
+LDLIBS_ptime = -lproc
+LDLIBS_ptree = -lproc -lcontract
+LDLIBS_pwdx = -lproc
LDLIBS += $(LDLIBS_$(PROG))
diff --git a/usr/src/cmd/ptools/psecflags/psecflags.c b/usr/src/cmd/ptools/psecflags/psecflags.c
new file mode 100644
index 0000000000..b26139b88c
--- /dev/null
+++ b/usr/src/cmd/ptools/psecflags/psecflags.c
@@ -0,0 +1,318 @@
+/*
+ * 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 <err.h>
+#include <errno.h>
+#include <grp.h>
+#include <libintl.h>
+#include <procfs.h>
+#include <project.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/secflags.h>
+#include <sys/types.h>
+
+#include <libproc.h>
+#include <libzonecfg.h>
+
+extern const char *__progname;
+
+static void
+print_flags(const char *set, secflagset_t flags)
+{
+ char buf[1024];
+
+ secflags_to_str(flags, buf, sizeof (buf));
+ (void) printf("\t%s:\t%s\n", set, buf);
+}
+
+/*
+ * Structure defining idtypes known to the priocntl command
+ * along with the corresponding names.
+ * The idtype values themselves are defined in <sys/procset.h>.
+ */
+static struct idtypes {
+ idtype_t type;
+ char *name;
+} idtypes [] = {
+ { P_ALL, "all" },
+ { P_CTID, "contract" },
+ { P_CTID, "ctid" },
+ { P_GID, "gid" },
+ { P_GID, "group" },
+ { P_PGID, "pgid" },
+ { P_PID, "pid" },
+ { P_PPID, "ppid" },
+ { P_PROJID, "project" },
+ { P_PROJID, "projid" },
+ { P_SID, "session", },
+ { P_SID, "sid" },
+ { P_SID, "sid" },
+ { P_TASKID, "taskid" },
+ { P_UID, "uid" },
+ { P_UID, "user" },
+ { P_ZONEID, "zone" },
+ { P_ZONEID, "zoneid" },
+ { 0, NULL }
+};
+
+static int
+str2idtype(char *idtypnm, idtype_t *idtypep)
+{
+ struct idtypes *curp;
+
+ for (curp = idtypes; curp->name != NULL; curp++) {
+ if (strncasecmp(curp->name, idtypnm,
+ strlen(curp->name)) == 0) {
+ *idtypep = curp->type;
+ return (0);
+ }
+ }
+ return (-1);
+}
+
+static id_t
+getid(idtype_t type, char *value)
+{
+ struct passwd *pwd;
+ struct group *grp;
+ id_t ret;
+ char *endp;
+
+ switch (type) {
+ case P_UID:
+ if ((pwd = getpwnam(value)) != NULL)
+ return (pwd->pw_uid);
+ break;
+ case P_GID:
+ if ((grp = getgrnam(value)) != NULL)
+ return (grp->gr_gid);
+ break;
+ case P_PROJID:
+ if ((ret = getprojidbyname(value)) != (id_t)-1)
+ return (ret);
+ break;
+ case P_ZONEID:
+ if (zone_get_id(value, &ret) == 0)
+ return (ret);
+ break;
+ default:
+ break;
+ }
+
+ errno = 0;
+
+ ret = (id_t)strtoul(value, &endp, 10);
+
+ if ((errno != 0) || (*endp != '\0'))
+ return ((id_t)-1);
+
+ return (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ secflagdelta_t act;
+ psecflagwhich_t which = PSF_INHERIT;
+ int ret = 0;
+ int pgrab_flags = PGRAB_RDONLY;
+ int opt;
+ char *idtypename = NULL;
+ idtype_t idtype = P_PID;
+ boolean_t usage = B_FALSE;
+ boolean_t e_flag = B_FALSE;
+ boolean_t l_flag = B_FALSE;
+ boolean_t s_flag = B_FALSE;
+ int errc = 0;
+
+ while ((opt = getopt(argc, argv, "eFi:ls:")) != -1) {
+ switch (opt) {
+ case 'e':
+ e_flag = B_TRUE;
+ break;
+ case 'F':
+ pgrab_flags |= PGRAB_FORCE;
+ break;
+ case 'i':
+ idtypename = optarg;
+ break;
+ case 's':
+ s_flag = B_TRUE;
+ if ((strlen(optarg) >= 2) &&
+ ((optarg[1] == '='))) {
+ switch (optarg[0]) {
+ case 'L':
+ which = PSF_LOWER;
+ break;
+ case 'U':
+ which = PSF_UPPER;
+ break;
+ case 'I':
+ which = PSF_INHERIT;
+ break;
+ case 'E':
+ errx(1, "the effective flags cannot "
+ "be changed", optarg[0]);
+ default:
+ errx(1, "unknown security flag "
+ "set: '%c'", optarg[0]);
+ }
+
+ optarg += 2;
+ }
+
+ if (secflags_parse(NULL, optarg, &act) == -1)
+ errx(1, "couldn't parse security flags: %s",
+ optarg);
+ break;
+ case 'l':
+ l_flag = B_TRUE;
+ break;
+ default:
+ usage = B_TRUE;
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (l_flag && ((idtypename != NULL) || s_flag || (argc != 0)))
+ usage = B_TRUE;
+ if ((idtypename != NULL) && !s_flag)
+ usage = B_TRUE;
+ if (e_flag && !s_flag)
+ usage = B_TRUE;
+ if (!l_flag && argc <= 0)
+ usage = B_TRUE;
+
+ if (usage) {
+ (void) fprintf(stderr,
+ gettext("usage:\t%s [-F] { pid | core } ...\n"),
+ __progname);
+ (void) fprintf(stderr,
+ gettext("\t%s -s spec [-i idtype] id ...\n"),
+ __progname);
+ (void) fprintf(stderr,
+ gettext("\t%s -s spec -e command [arg]...\n"),
+ __progname);
+ (void) fprintf(stderr, gettext("\t%s -l\n"), __progname);
+ return (2);
+ }
+
+ if (l_flag) {
+ secflag_t i;
+ const char *name;
+
+ for (i = 0; (name = secflag_to_str(i)) != NULL; i++)
+ (void) printf("%s\n", name);
+ return (0);
+ } else if (s_flag && e_flag) {
+ /*
+ * Don't use the strerror() message for EPERM, "Not Owner"
+ * which is misleading.
+ */
+ errc = psecflags(P_PID, P_MYID, which, &act);
+ switch (errc) {
+ case 0:
+ break;
+ case EPERM:
+ errx(1, gettext("failed setting "
+ "security-flags: Permission denied"));
+ break;
+ default:
+ err(1, gettext("failed setting security-flags"));
+ }
+
+ (void) execvp(argv[0], &argv[0]);
+ err(1, "%s", argv[0]);
+ } else if (s_flag) {
+ int i;
+ id_t id;
+
+ if (idtypename != NULL)
+ if (str2idtype(idtypename, &idtype) == -1)
+ errx(1, gettext("No such id type: '%s'"),
+ idtypename);
+
+ for (i = 0; i < argc; i++) {
+ if ((id = getid(idtype, argv[i])) == (id_t)-1) {
+ errx(1, gettext("invalid or non-existent "
+ "identifier: '%s'"), argv[i]);
+ }
+
+ /*
+ * Don't use the strerror() message for EPERM, "Not
+ * Owner" which is misleading.
+ */
+ if (psecflags(idtype, id, which, &act) != 0) {
+ switch (errno) {
+ case EPERM:
+ errx(1, gettext("failed setting "
+ "security-flags: "
+ "Permission denied"));
+ break;
+ default:
+ err(1, gettext("failed setting "
+ "security-flags"));
+ }
+ }
+ }
+
+ return (0);
+ }
+
+ /* Display the flags for the given pids */
+ while (argc-- > 0) {
+ struct ps_prochandle *Pr;
+ const char *arg;
+ psinfo_t psinfo;
+ prsecflags_t *psf;
+ int gcode;
+
+ if ((Pr = proc_arg_grab(arg = *argv++, PR_ARG_ANY,
+ pgrab_flags, &gcode)) == NULL) {
+ warnx(gettext("cannot examine %s: %s"),
+ arg, Pgrab_error(gcode));
+ ret = 1;
+ continue;
+ }
+
+ (void) memcpy(&psinfo, Ppsinfo(Pr), sizeof (psinfo_t));
+ proc_unctrl_psinfo(&psinfo);
+
+ if (Pstate(Pr) == PS_DEAD) {
+ (void) printf(gettext("core '%s' of %d:\t%.70s\n"),
+ arg, (int)psinfo.pr_pid, psinfo.pr_psargs);
+ } else {
+ (void) printf("%d:\t%.70s\n",
+ (int)psinfo.pr_pid, psinfo.pr_psargs);
+ }
+
+ if (Psecflags(Pr, &psf) != 0)
+ err(1, gettext("cannot read secflags of %s"), arg);
+
+ print_flags("E", psf->pr_effective);
+ print_flags("I", psf->pr_inherit);
+ print_flags("L", psf->pr_lower);
+ print_flags("U", psf->pr_upper);
+
+ Psecflags_free(psf);
+ Prelease(Pr, 0);
+ }
+
+ return (ret);
+}
diff --git a/usr/src/cmd/sgs/dump/common/dump.c b/usr/src/cmd/sgs/dump/common/dump.c
index 665ee85e49..016f045dc1 100644
--- a/usr/src/cmd/sgs/dump/common/dump.c
+++ b/usr/src/cmd/sgs/dump/common/dump.c
@@ -281,8 +281,8 @@ print_rawdata(unsigned char *p_sec, size_t size)
*/
static void
print_rela(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data,
- GElf_Ehdr * p_ehdr, size_t reloc_size, size_t sym_size, char *filename,
- SCNTAB *reloc_symtab)
+ GElf_Ehdr * p_ehdr, size_t reloc_size, size_t sym_size, char *filename,
+ SCNTAB *reloc_symtab)
{
GElf_Rela rela;
GElf_Sym sym;
@@ -386,8 +386,8 @@ print_rela(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data,
*/
static void
print_rel(Elf *elf_file, SCNTAB *p_scns, Elf_Data *rdata, Elf_Data *sym_data,
- GElf_Ehdr *p_ehdr, size_t reloc_size, size_t sym_size, char *filename,
- SCNTAB *reloc_symtab)
+ GElf_Ehdr *p_ehdr, size_t reloc_size, size_t sym_size, char *filename,
+ SCNTAB *reloc_symtab)
{
GElf_Rel rel;
GElf_Sym sym;
@@ -513,7 +513,7 @@ demangled_name(char *s)
*/
static void
print_symtab(Elf *elf_file, SCNTAB *p_symtab, Elf_Data *sym_data,
- long range, int index)
+ long range, int index)
{
GElf_Sym sym;
int adj = 0; /* field adjustment for elf64 */
@@ -759,7 +759,7 @@ check_range(int low, int hi, size_t bound, char *filename)
*/
static void
dump_reloc_table(Elf *elf_file, GElf_Ehdr *p_ehdr,
- SCNTAB *p_scns, int num_scns, char *filename)
+ SCNTAB *p_scns, int num_scns, char *filename)
{
Elf_Data *rel_data;
Elf_Data *sym_data;
@@ -1225,6 +1225,7 @@ dump_dynamic(Elf *elf_file, SCNTAB *p_scns, int num_scns, char *filename)
case DT_SUNW_STRPAD:
case DT_SUNW_CAPCHAINENT:
case DT_SUNW_CAPCHAINSZ:
+ case DT_SUNW_ASLR:
(void) printf(pdyn_Fmtptr,
EC_XWORD(p_dyn.d_un.d_val));
break;
@@ -1464,7 +1465,7 @@ dump_elf_header(Elf *elf_file, char *filename, GElf_Ehdr * elf_head_p)
*/
static void
print_section(Elf *elf_file,
- GElf_Ehdr *p_ehdr, SCNTAB *p, int num_scns, char *filename)
+ GElf_Ehdr *p_ehdr, SCNTAB *p, int num_scns, char *filename)
{
unsigned char *p_sec;
int i;
@@ -1531,7 +1532,7 @@ print_section(Elf *elf_file,
*/
static void
dump_section(Elf *elf_file,
- GElf_Ehdr *p_ehdr, SCNTAB *s, int num_scns, char *filename)
+ GElf_Ehdr *p_ehdr, SCNTAB *s, int num_scns, char *filename)
{
SCNTAB *n_range, *d_range; /* for use with -n and -d modifiers */
int i;
@@ -1740,7 +1741,7 @@ dump_section_table(Elf *elf_file, GElf_Ehdr *elf_head_p, char *filename)
*/
static struct stab_list_s *
load_arstring_table(struct stab_list_s *STabList,
- int fd, Elf *elf_file, Elf_Arhdr *p_ar, char *filename)
+ int fd, Elf *elf_file, Elf_Arhdr *p_ar, char *filename)
{
off_t here;
struct stab_list_s *STL_entry, *STL_next;
diff --git a/usr/src/cmd/sgs/elfdump/common/corenote.c b/usr/src/cmd/sgs/elfdump/common/corenote.c
index 57930866e2..7de5e9dfcc 100644
--- a/usr/src/cmd/sgs/elfdump/common/corenote.c
+++ b/usr/src/cmd/sgs/elfdump/common/corenote.c
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/corectl.h>
+#include <procfs.h>
#include <msg.h>
#include <_elfdump.h>
#include <struct_layout.h>
@@ -166,7 +167,7 @@ extract_as_word(note_state_t *state, const sl_field_t *fdesc)
{
return (sl_extract_as_word(state->ns_data, state->ns_swap, fdesc));
}
-static Word
+static Lword
extract_as_lword(note_state_t *state, const sl_field_t *fdesc)
{
return (sl_extract_as_lword(state->ns_data, state->ns_swap, fdesc));
@@ -436,6 +437,7 @@ dump_auxv(note_state_t *state, const char *title)
Conv_cap_val_hw2_buf_t hw2;
Conv_cnote_auxv_af_buf_t auxv_af;
Conv_ehdr_flags_buf_t ehdr_flags;
+ Conv_secflags_buf_t secflags;
Conv_inv_buf_t inv;
} conv_buf;
sl_fmtbuf_t buf;
@@ -827,6 +829,46 @@ dump_timestruc(note_state_t *state, const char *title)
indent_exit(state);
}
+/*
+ * Output information from prsecflags_t structure.
+ */
+static void
+dump_secflags(note_state_t *state, const char *title)
+{
+ const sl_prsecflags_layout_t *layout = state->ns_arch->prsecflags;
+ Conv_secflags_buf_t inv;
+ Lword lw;
+ Word w;
+
+ indent_enter(state, title, &layout->pr_version);
+
+ w = extract_as_word(state, &layout->pr_version);
+
+ if (w != PRSECFLAGS_VERSION_1) {
+ PRINT_DEC(MSG_INTL(MSG_NOTE_BAD_SECFLAGS_VER), pr_version);
+ dump_hex_bytes(state->ns_data, state->ns_len, state->ns_indent,
+ 4, 3);
+ } else {
+ PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_VERSION), pr_version);
+ lw = extract_as_lword(state, &layout->pr_effective);
+ print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_EFFECTIVE),
+ conv_prsecflags(lw, 0, &inv));
+
+ lw = extract_as_lword(state, &layout->pr_inherit);
+ print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_INHERIT),
+ conv_prsecflags(lw, 0, &inv));
+
+ lw = extract_as_lword(state, &layout->pr_lower);
+ print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_LOWER),
+ conv_prsecflags(lw, 0, &inv));
+
+ lw = extract_as_lword(state, &layout->pr_upper);
+ print_str(state, MSG_ORIG(MSG_CNOTE_T_PR_UPPER),
+ conv_prsecflags(lw, 0, &inv));
+ }
+
+ indent_exit(state);
+}
/*
* Output information from utsname structure.
@@ -1097,6 +1139,7 @@ dump_pstatus(note_state_t *state, const char *title)
state->ns_vcol += 5;
state->ns_t2col += 5;
state->ns_v2col += 5;
+
PRINT_SUBTYPE(MSG_ORIG(MSG_CNOTE_T_PR_LWP), pr_lwp, dump_lwpstatus);
state->ns_vcol -= 5;
state->ns_t2col -= 5;
@@ -1857,6 +1900,13 @@ corenote(Half mach, int do_swap, Word type,
state.ns_v2col = 58;
dump_psinfo(&state, MSG_ORIG(MSG_CNOTE_DESC_PSINFO_T));
return (CORENOTE_R_OK);
+
+ case NT_SECFLAGS:
+ state.ns_vcol = 23;
+ state.ns_t2col = 41;
+ state.ns_v2col = 54;
+ dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_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 e17d8b43e1..e7488d5373 100644
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
@@ -311,6 +311,8 @@
otherwise malformed\n"
@ MSG_NOTE_BADCORETYPE "%s: unknown note type %#x\n"
+@ MSG_NOTE_BAD_SECFLAGS_VER "unknown prsecflags_t version: "
+
@ _END_
# The following strings represent reserved words, files, pathnames and symbols.
@@ -466,7 +468,7 @@
@ MSG_CNOTE_DESC_PSTATUS_T "desc: (pstatus_t)"
@ MSG_CNOTE_DESC_STRUCT_UTSNAME "desc: (struct utsname)"
@ MSG_CNOTE_DESC_PRFDINFO_T "desc: (prfdinfo_t)"
-
+@ MSG_CNOTE_DESC_PRSECFLAGS_T "desc: (prsecflags_t)"
@ MSG_CNOTE_FMT_LINE "%*s%-*s%s"
@ MSG_CNOTE_FMT_LINE_2UP "%*s%-*s%-*s%-*s%s"
@@ -596,6 +598,11 @@
@ MSG_CNOTE_T_PR_WSTAT "pr_wstat:"
@ MSG_CNOTE_T_PR_ZOMB "pr_zomb:"
@ MSG_CNOTE_T_PR_ZONEID "pr_zoneid:"
+@ MSG_CNOTE_T_PR_EFFECTIVE "pr_effective:"
+@ MSG_CNOTE_T_PR_INHERIT "pr_inherit:"
+@ MSG_CNOTE_T_PR_LOWER "pr_lower:"
+@ MSG_CNOTE_T_PR_UPPER "pr_upper:"
+@ MSG_CNOTE_T_PR_VERSION "pr_version:"
@ MSG_CNOTE_T_SA_FLAGS "sa_flags:"
@ MSG_CNOTE_T_SA_HANDLER "sa_handler:"
@ MSG_CNOTE_T_SA_MASK "sa_mask:"
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 43c195e0e5..f7af1c1543 100644
--- a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c
+++ b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c
@@ -27,6 +27,7 @@
#include <sys/auxv.h>
#include <sys/old_procfs.h>
#include <sys/utsname.h>
+#include <sys/secflags.h>
/* prgregset_t is a define on intel */
#ifdef prgregset_t
@@ -56,3 +57,4 @@ sysset_t sysset;
timestruc_t ts;
struct utsname uts;
prfdinfo_t ptfd;
+prsecflags_t psf;
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 67d5378db3..d90363c5de 100644
--- a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c
+++ b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c
@@ -587,6 +587,17 @@ gen_prfdinfo(void)
END;
}
+static void
+gen_prsecflags(void)
+{
+ START(prsecflags, prsecflags_t);
+ SCALAR_FIELD(prsecflags_t, pr_version, 0);
+ SCALAR_FIELD(prsecflags_t, pr_effective, 0);
+ SCALAR_FIELD(prsecflags_t, pr_inherit, 0);
+ SCALAR_FIELD(prsecflags_t, pr_lower, 0);
+ SCALAR_FIELD(prsecflags_t, pr_upper, 0);
+ END;
+}
/*ARGSUSED*/
int
@@ -628,7 +639,7 @@ main(int argc, char *argv[])
gen_timestruc();
gen_utsname();
gen_prfdinfo();
-
+ gen_prsecflags();
/*
* Generate the full arch_layout description
@@ -656,6 +667,7 @@ main(int argc, char *argv[])
(void) printf(fmt, "timestruc");
(void) printf(fmt, "utsname");
(void) printf(fmt, "prfdinfo");
+ (void) printf(fmt, "prsecflags");
(void) printf("};\n");
/*
@@ -759,7 +771,7 @@ do_scalar_field(char *tname, char *fname, int _sign, char *dotfield)
static void
do_array_field(char *tname, char *fname,
- int _sign, char *dotfield)
+ int _sign, char *dotfield)
{
char comment[100];
ctf_arinfo_t ai;
@@ -835,7 +847,7 @@ static int gfi_iter(const char *fname, ctf_id_t mbrtid,
*/
static int
get_field_info(char *tname, char *fname, char *dotname,
- int *offp, int *tidp)
+ int *offp, int *tidp)
{
struct gfinfo gfi;
ctf_id_t stype;
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout.c b/usr/src/cmd/sgs/elfdump/common/struct_layout.c
index ea9bff305b..1f4b32f319 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout.c
@@ -23,7 +23,6 @@
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <stdio.h>
@@ -120,7 +119,7 @@ sl_extract_as_word(const char *data, int do_swap, const sl_field_t *fdesc)
/*
* Extract the given integer field, and return its value, cast
- * to Word. Note that this operation must not be used on values
+ * to Lword. Note that this operation must not be used on values
* that can be negative, as information can be lost.
*/
Lword
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout.h b/usr/src/cmd/sgs/elfdump/common/struct_layout.h
index 11dbcc4b83..b0592d6909 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout.h
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout.h
@@ -526,6 +526,15 @@ typedef struct {
sl_field_t pr_path;
} sl_prfdinfo_layout_t;
+typedef struct {
+ sl_field_t sizeof_struct;
+ sl_field_t pr_version;
+ sl_field_t pr_effective;
+ sl_field_t pr_inherit;
+ sl_field_t pr_lower;
+ sl_field_t pr_upper;
+} sl_prsecflags_layout_t;
+
/*
* This type collects all of the layout definitions for
* a given architecture.
@@ -551,6 +560,7 @@ typedef struct {
const sl_timestruc_layout_t *timestruc; /* timestruc_t */
const sl_utsname_layout_t *utsname; /* struct utsname */
const sl_prfdinfo_layout_t *prfdinfo; /* prdinfo_t */
+ const sl_prsecflags_layout_t *prsecflags; /* prsecflags_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 3ddda2ef08..2b9469a022 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c
@@ -377,6 +377,16 @@ static const sl_prfdinfo_layout_t prfdinfo_layout = {
};
+static const sl_prsecflags_layout_t prsecflags_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prsecflags_t) */
+ { 0, 4, 0, 0 }, /* pr_version */
+ { 8, 8, 0, 0 }, /* pr_effective */
+ { 16, 8, 0, 0 }, /* pr_inherit */
+ { 24, 8, 0, 0 }, /* pr_lower */
+ { 32, 8, 0, 0 }, /* pr_upper */
+};
+
+
static const sl_arch_layout_t layout_amd64 = {
@@ -400,6 +410,7 @@ static const sl_arch_layout_t layout_amd64 = {
&timestruc_layout,
&utsname_layout,
&prfdinfo_layout,
+ &prsecflags_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 591b6c5439..6a516bc225 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c
@@ -377,6 +377,16 @@ static const sl_prfdinfo_layout_t prfdinfo_layout = {
};
+static const sl_prsecflags_layout_t prsecflags_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prsecflags_t) */
+ { 0, 4, 0, 0 }, /* pr_version */
+ { 8, 8, 0, 0 }, /* pr_effective */
+ { 16, 8, 0, 0 }, /* pr_inherit */
+ { 24, 8, 0, 0 }, /* pr_lower */
+ { 32, 8, 0, 0 }, /* pr_upper */
+};
+
+
static const sl_arch_layout_t layout_i386 = {
@@ -400,6 +410,7 @@ static const sl_arch_layout_t layout_i386 = {
&timestruc_layout,
&utsname_layout,
&prfdinfo_layout,
+ &prsecflags_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 2cf4f7b776..b3d1c34f26 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
@@ -376,6 +376,16 @@ static const sl_prfdinfo_layout_t prfdinfo_layout = {
};
+static const sl_prsecflags_layout_t prsecflags_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prsecflags_t) */
+ { 0, 4, 0, 0 }, /* pr_version */
+ { 8, 8, 0, 0 }, /* pr_effective */
+ { 16, 8, 0, 0 }, /* pr_inherit */
+ { 24, 8, 0, 0 }, /* pr_lower */
+ { 32, 8, 0, 0 }, /* pr_upper */
+};
+
+
static const sl_arch_layout_t layout_sparc = {
@@ -399,6 +409,7 @@ static const sl_arch_layout_t layout_sparc = {
&timestruc_layout,
&utsname_layout,
&prfdinfo_layout,
+ &prsecflags_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 23ad0aa0b1..d068f148c2 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c
@@ -377,6 +377,16 @@ static const sl_prfdinfo_layout_t prfdinfo_layout = {
};
+static const sl_prsecflags_layout_t prsecflags_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prsecflags_t) */
+ { 0, 4, 0, 0 }, /* pr_version */
+ { 8, 8, 0, 0 }, /* pr_effective */
+ { 16, 8, 0, 0 }, /* pr_inherit */
+ { 24, 8, 0, 0 }, /* pr_lower */
+ { 32, 8, 0, 0 }, /* pr_upper */
+};
+
+
static const sl_arch_layout_t layout_sparcv9 = {
@@ -400,9 +410,12 @@ static const sl_arch_layout_t layout_sparcv9 = {
&timestruc_layout,
&utsname_layout,
&prfdinfo_layout,
+ &prsecflags_layout,
};
+
+
const sl_arch_layout_t *
struct_layout_sparcv9(void)
{
diff --git a/usr/src/cmd/sgs/include/conv.h b/usr/src/cmd/sgs/include/conv.h
index 8f4dd4a584..624d9ee3b8 100644
--- a/usr/src/cmd/sgs/include/conv.h
+++ b/usr/src/cmd/sgs/include/conv.h
@@ -41,6 +41,8 @@
#include <sgs.h>
#include <sgsmsg.h>
+#include <sys/secflags.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -325,6 +327,12 @@ typedef union {
char buf[CONV_CNOTE_PROC_FLAG_BUFSIZE];
} Conv_cnote_proc_flag_buf_t;
+/* conv_prsecflags() */
+#define CONV_PRSECFLAGS_BUFSIZE 57
+typedef union {
+ Conv_inv_buf_t inv_buf;
+ char buf[CONV_PRSECFLAGS_BUFSIZE];
+} Conv_secflags_buf_t;
/* conv_cnote_sigset() */
#define CONV_CNOTE_SIGSET_BUFSIZE 639
@@ -822,6 +830,8 @@ extern const char *conv_cnote_pr_why(short, Conv_fmt_flags_t,
Conv_inv_buf_t *);
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_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/include/libld.h b/usr/src/cmd/sgs/include/libld.h
index ddb0fb2506..dfcc1e78ef 100644
--- a/usr/src/cmd/sgs/include/libld.h
+++ b/usr/src/cmd/sgs/include/libld.h
@@ -406,6 +406,7 @@ struct ofl_desc {
avl_tree_t *ofl_wrap; /* -z wrap symbols */
ofl_guideflag_t ofl_guideflags; /* -z guide flags */
APlist *ofl_assdeflib; /* -z assert-deflib exceptions */
+ int ofl_aslr; /* -z aslr, -1 disable, 1 enable */
};
#define FLG_OF_DYNAMIC 0x00000001 /* generate dynamic output module */
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c
index eb998bae45..c52c21e80a 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.c
+++ b/usr/src/cmd/sgs/libconv/common/corenote.c
@@ -37,6 +37,7 @@
#include <stdio.h>
#include <procfs.h>
#include <sys/corectl.h>
+#include <sys/secflags.h>
#include <string.h>
#include <_conv.h>
#include <corenote_msg.h>
@@ -57,9 +58,9 @@ conv_cnote_type(Word type, Conv_fmt_flags_t fmt_flags,
MSG_NT_LWPSINFO, MSG_NT_PRPRIV,
MSG_NT_PRPRIVINFO, MSG_NT_CONTENT,
MSG_NT_ZONENAME, MSG_NT_FDINFO,
- MSG_NT_SPYMASTER
+ MSG_NT_SPYMASTER, MSG_NT_SECFLAGS
};
-#if NT_NUM != NT_SPYMASTER
+#if NT_NUM != NT_SECFLAGS
#error "NT_NUM has grown. Update core note types[]"
#endif
static const conv_ds_msg_t ds_types = {
@@ -109,7 +110,7 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags,
MSG_AUXV_AT_SUN_LDDATA, MSG_AUXV_AT_SUN_AUXFLAGS,
MSG_AUXV_AT_SUN_EMULATOR, MSG_AUXV_AT_SUN_BRANDNAME,
MSG_AUXV_AT_SUN_BRAND_AUX1, MSG_AUXV_AT_SUN_BRAND_AUX2,
- MSG_AUXV_AT_SUN_BRAND_AUX3, MSG_AUXV_AT_SUN_HWCAP2
+ MSG_AUXV_AT_SUN_BRAND_AUX3, MSG_AUXV_AT_SUN_HWCAP2,
};
static const conv_ds_msg_t ds_types_2014_2023 = {
CONV_DS_MSG_INIT(2014, types_2014_2023) };
@@ -2582,3 +2583,57 @@ conv_cnote_filemode(uint32_t mode, Conv_fmt_flags_t fmt_flags,
(void) conv_expn_field(&arg, vda, fmt_flags);
return (buf);
}
+
+
+#define PROCSECFLGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \
+ MSG_ASLR_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_FORBIDNULLMAP_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ MSG_NOEXECSTACK_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+ CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
+
+/*
+ * Ensure that Conv_cnote_pr_secflags_buf_t is large enough:
+ *
+ * PROCSECFLGSZ is the real minimum size of the buffer required by
+ * conv_prsecflags(). However, Conv_cnote_pr_secflags_buf_t uses
+ * CONV_CNOTE_PSECFLAGS_FLAG_BUFSIZE to set the buffer size. We do things this
+ * way because the definition of PROCSECFLGSZ uses information that is not
+ * available in the environment of other programs that include the conv.h
+ * header file.
+ */
+#if (CONV_PRSECFLAGS_BUFSIZE != PROCSECFLGSZ) && !defined(__lint)
+#define REPORT_BUFSIZE PROCSECFLGSZ
+#include "report_bufsize.h"
+#error "CONV_PRSECFLAGS_BUFSIZE does not match PROCSECFLGSZ"
+#endif
+
+const char *
+conv_prsecflags(secflagset_t flags, Conv_fmt_flags_t fmt_flags,
+ Conv_secflags_buf_t *secflags_buf)
+{
+ /*
+ * The values are initialized later, based on position in this array
+ */
+ static Val_desc vda[] = {
+ { 0, MSG_ASLR },
+ { 0, MSG_FORBIDNULLMAP },
+ { 0, MSG_NOEXECSTACK },
+ { 0, 0 }
+ };
+ static CONV_EXPN_FIELD_ARG conv_arg = {
+ NULL, sizeof (secflags_buf->buf)
+ };
+ int i;
+
+ for (i = 0; vda[i].v_msg != 0; i++)
+ vda[i].v_val = secflag_to_bit(i);
+
+ if (flags == 0)
+ return (MSG_ORIG(MSG_GBL_ZERO));
+
+ conv_arg.buf = secflags_buf->buf;
+ conv_arg.oflags = conv_arg.rflags = flags;
+ (void) conv_expn_field(&conv_arg, vda, fmt_flags);
+
+ return ((const char *)secflags_buf->buf);
+}
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg
index f5866a5b69..e01c4ae606 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.msg
+++ b/usr/src/cmd/sgs/libconv/common/corenote.msg
@@ -48,6 +48,7 @@
@ MSG_NT_ZONENAME "[ NT_ZONENAME ]"
@ MSG_NT_FDINFO "[ NT_FDINFO ]"
@ MSG_NT_SPYMASTER "[ NT_SPYMASTER ]"
+@ MSG_NT_SECFLAGS "[ NT_SECFLAGS ]"
@ MSG_AUXV_AF_SUN_SETUGID "AF_SUN_SETUGID"
@@ -101,7 +102,6 @@
@ MSG_AUXV_AT_SUN_BRAND_AUX3 "SUN_BRAND_AUX3"
@ MSG_AUXV_AT_SUN_HWCAP2 "SUN_HWCAP2"
-
@ MSG_CC_CONTENT_STACK "STACK"
@ MSG_CC_CONTENT_HEAP "HEAP"
@ MSG_CC_CONTENT_SHFILE "SHFILE"
@@ -277,6 +277,10 @@
@ MSG_PROC_FLAG_SSYS "SSYS"
@ MSG_PROC_FLAG_SMSACCT "SMSACCT"
+@ MSG_ASLR "ASLR"
+@ MSG_FORBIDNULLMAP "FORBIDNULLMAP"
+@ MSG_NOEXECSTACK "NOEXECSTACK"
+
@ MSG_PS_NONE "[ PS_NONE ]"
@ MSG_PS_QUERY "[ PS_QUERY ]"
@ MSG_PS_MYID "[ PS_MYID ]"
diff --git a/usr/src/cmd/sgs/libconv/common/dynamic.c b/usr/src/cmd/sgs/libconv/common/dynamic.c
index de601f5a16..8b15ba075e 100644
--- a/usr/src/cmd/sgs/libconv/common/dynamic.c
+++ b/usr/src/cmd/sgs/libconv/common/dynamic.c
@@ -556,7 +556,9 @@ conv_dyn_tag_strings(conv_iter_osabi_t osabi, Half mach,
MSG_DT_SUNW_STRPAD_CF, MSG_DT_SUNW_CAPCHAIN_CF,
MSG_DT_SUNW_LDMACH_CF, 0,
MSG_DT_SUNW_CAPCHAINENT_CF, 0,
- MSG_DT_SUNW_CAPCHAINSZ_CF
+ MSG_DT_SUNW_CAPCHAINSZ_CF, 0,
+ 0, 0,
+ MSG_DT_SUNW_ASLR_CF
};
static const Msg tags_sunw_auxiliary_cfnp[] = {
MSG_DT_SUNW_AUXILIARY_CFNP, MSG_DT_SUNW_RTLDINF_CFNP,
@@ -568,7 +570,9 @@ conv_dyn_tag_strings(conv_iter_osabi_t osabi, Half mach,
MSG_DT_SUNW_STRPAD_CFNP, MSG_DT_SUNW_CAPCHAIN_CFNP,
MSG_DT_SUNW_LDMACH_CFNP, 0,
MSG_DT_SUNW_CAPCHAINENT_CFNP, 0,
- MSG_DT_SUNW_CAPCHAINSZ_CFNP
+ MSG_DT_SUNW_CAPCHAINSZ_CFNP, 0,
+ 0, 0,
+ MSG_DT_SUNW_ASLR_CFNP
};
static const Msg tags_sunw_auxiliary_nf[] = {
MSG_DT_SUNW_AUXILIARY_NF, MSG_DT_SUNW_RTLDINF_NF,
@@ -580,7 +584,9 @@ conv_dyn_tag_strings(conv_iter_osabi_t osabi, Half mach,
MSG_DT_SUNW_STRPAD_NF, MSG_DT_SUNW_CAPCHAIN_NF,
MSG_DT_SUNW_LDMACH_NF, 0,
MSG_DT_SUNW_CAPCHAINENT_NF, 0,
- MSG_DT_SUNW_CAPCHAINSZ_NF
+ MSG_DT_SUNW_CAPCHAINSZ_NF, 0,
+ 0, 0,
+ MSG_DT_SUNW_ASLR_NF
};
static const conv_ds_msg_t ds_sunw_auxiliary_cf = {
CONV_DS_MSG_INIT(DT_SUNW_AUXILIARY, tags_sunw_auxiliary_cf) };
diff --git a/usr/src/cmd/sgs/libconv/common/dynamic.msg b/usr/src/cmd/sgs/libconv/common/dynamic.msg
index 340a67cb3a..1c0a51516b 100644
--- a/usr/src/cmd/sgs/libconv/common/dynamic.msg
+++ b/usr/src/cmd/sgs/libconv/common/dynamic.msg
@@ -178,6 +178,9 @@
@ MSG_DT_SUNW_CAPCHAINSZ_CF "DT_SUNW_CAPCHAINSZ" # 0x6000001d
@ MSG_DT_SUNW_CAPCHAINSZ_CFNP "SUNW_CAPCHAINSZ"
@ MSG_DT_SUNW_CAPCHAINSZ_NF "sunw_capchainsz"
+@ MSG_DT_SUNW_ASLR_CF "DT_SUNW_ASLR" # 0x60000023
+@ MSG_DT_SUNW_ASLR_CFNP "SUNW_ASLR"
+@ MSG_DT_SUNW_ASLR_NF "sunw_aslr"
@ MSG_DT_GNU_PRELINKED_CF "DT_GNU_PRELINKED" # 0x6ffffdf5
@ MSG_DT_GNU_PRELINKED_CFNP "GNU_PRELINKED"
diff --git a/usr/src/cmd/sgs/libld/common/args.c b/usr/src/cmd/sgs/libld/common/args.c
index 1080168bbd..495fed322c 100644
--- a/usr/src/cmd/sgs/libld/common/args.c
+++ b/usr/src/cmd/sgs/libld/common/args.c
@@ -940,7 +940,6 @@ assdeflib_parse(Ofl_desc *ofl, char *optarg)
MSG_STR_SOEXT_SIZE;
if (olen > MSG_ARG_ASSDEFLIB_SIZE) {
if (optarg[MSG_ARG_ASSDEFLIB_SIZE] != '=') {
- ld_eprintf(ofl, ERR_FATAL, "Missing =\n");
ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ILLEGAL),
MSG_ORIG(MSG_ARG_ASSDEFLIB), optarg);
return (TRUE);
@@ -1437,6 +1436,32 @@ parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage)
if (ld_wrap_enter(ofl,
optarg + MSG_ARG_WRAP_SIZE) == NULL)
return (S_ERROR);
+ } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASLR),
+ MSG_ARG_ASLR_SIZE) == 0) {
+ char *p = optarg + MSG_ARG_ASLR_SIZE;
+ if (*p == '\0') {
+ ofl->ofl_aslr = 1;
+ } else if (*p == '=') {
+ p++;
+
+ if (strcmp(p,
+ MSG_ORIG(MSG_ARG_ENABLED)) == 0) {
+ ofl->ofl_aslr = 1;
+ } else if (strcmp(p,
+ MSG_ORIG(MSG_ARG_DISABLED)) == 0) {
+ ofl->ofl_aslr = -1;
+ } else {
+ ld_eprintf(ofl, ERR_FATAL,
+ MSG_INTL(MSG_ARG_ILLEGAL),
+ MSG_ORIG(MSG_ARG_ZASLR), p);
+ return (S_ERROR);
+ }
+ } else {
+ ld_eprintf(ofl, ERR_FATAL,
+ MSG_INTL(MSG_ARG_ILLEGAL),
+ MSG_ORIG(MSG_ARG_Z), optarg);
+ return (S_ERROR);
+ }
} else if ((strncmp(optarg, MSG_ORIG(MSG_ARG_GUIDE),
MSG_ARG_GUIDE_SIZE) == 0) &&
((optarg[MSG_ARG_GUIDE_SIZE] == '=') ||
diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg
index 0b3db8ede3..dd77130b40 100644
--- a/usr/src/cmd/sgs/libld/common/libld.msg
+++ b/usr/src/cmd/sgs/libld/common/libld.msg
@@ -1357,6 +1357,7 @@
@ MSG_ARG_CYU "-YU"
@ MSG_ARG_Z "-z"
@ MSG_ARG_ZDEFNODEF "-z[defs|nodefs]"
+@ MSG_ARG_ZASLR "-zaslr"
@ MSG_ARG_ZGUIDE "-zguidance"
@ MSG_ARG_ZNODEF "-znodefs"
@ MSG_ARG_ZNOINTERP "-znointerp"
@@ -1373,6 +1374,7 @@
@ MSG_ARG_ABSEXEC "absexec"
@ MSG_ARG_ALTEXEC64 "altexec64"
+@ MSG_ARG_ASLR "aslr"
@ MSG_ARG_NOCOMPSTRTAB "nocompstrtab"
@ MSG_ARG_GROUPPERM "groupperm"
@ MSG_ARG_NOGROUPPERM "nogroupperm"
@@ -1473,6 +1475,9 @@
@ MSG_ARG_T_OPAR "("
@ MSG_ARG_T_CPAR ")"
+@ MSG_ARG_ENABLED "enabled"
+@ MSG_ARG_DISABLED "disabled"
+
# -z guidance=item strings
@ MSG_ARG_GUIDE_DELIM ",: \t"
@ MSG_ARG_GUIDE_NO_ALL "noall"
diff --git a/usr/src/cmd/sgs/libld/common/sections.c b/usr/src/cmd/sgs/libld/common/sections.c
index 95cc830f6c..86d19a4120 100644
--- a/usr/src/cmd/sgs/libld/common/sections.c
+++ b/usr/src/cmd/sgs/libld/common/sections.c
@@ -424,7 +424,7 @@ ignore_section_processing(Ofl_desc *ofl)
*/
static uintptr_t
new_section(Ofl_desc *ofl, Word shtype, const char *shname, Xword entcnt,
- Is_desc **ret_isec, Shdr **ret_shdr, Elf_Data **ret_data)
+ Is_desc **ret_isec, Shdr **ret_shdr, Elf_Data **ret_data)
{
typedef struct sec_info {
Word d_type;
@@ -689,7 +689,7 @@ new_section(Ofl_desc *ofl, Word shtype, const char *shname, Xword entcnt,
*/
static uintptr_t
new_section_from_template(Ofl_desc *ofl, Is_desc *tmpl_isp, size_t size,
- Is_desc **ret_isec, Shdr **ret_shdr, Elf_Data **ret_data)
+ Is_desc **ret_isec, Shdr **ret_shdr, Elf_Data **ret_data)
{
Shdr *shdr;
Elf_Data *data;
@@ -1269,6 +1269,9 @@ make_dynamic(Ofl_desc *ofl)
if (flags & FLG_OF_SYMBOLIC)
cnt++; /* DT_SYMBOLIC */
+
+ if (ofl->ofl_aslr != 0) /* DT_SUNW_ASLR */
+ cnt++;
}
/*
diff --git a/usr/src/cmd/sgs/libld/common/update.c b/usr/src/cmd/sgs/libld/common/update.c
index fd2892f8ce..19352782d0 100644
--- a/usr/src/cmd/sgs/libld/common/update.c
+++ b/usr/src/cmd/sgs/libld/common/update.c
@@ -2532,6 +2532,13 @@ update_odynamic(Ofl_desc *ofl)
dyn->d_un.d_val = shdr->sh_entsize;
dyn++;
}
+
+ if (ofl->ofl_aslr != 0) {
+ dyn->d_tag = DT_SUNW_ASLR;
+ dyn->d_un.d_val = (ofl->ofl_aslr == 1);
+ dyn++;
+ }
+
if (flags & FLG_OF_SYMBOLIC) {
dyn->d_tag = DT_SYMBOLIC;
dyn->d_un.d_val = 0;
diff --git a/usr/src/cmd/svc/dtd/service_bundle.dtd.1 b/usr/src/cmd/svc/dtd/service_bundle.dtd.1
index e5c23803fc..b92b70c6c4 100644
--- a/usr/src/cmd/svc/dtd/service_bundle.dtd.1
+++ b/usr/src/cmd/svc/dtd/service_bundle.dtd.1
@@ -536,6 +536,7 @@
( (method_profile | method_credential)?, method_environment? ) >
<!ATTLIST method_context
+ security_flags CDATA #IMPLIED
working_directory CDATA #IMPLIED
project CDATA #IMPLIED
resource_pool CDATA #IMPLIED >
diff --git a/usr/src/cmd/svc/milestone/Makefile b/usr/src/cmd/svc/milestone/Makefile
index 52579a3af4..901727dc9f 100644
--- a/usr/src/cmd/svc/milestone/Makefile
+++ b/usr/src/cmd/svc/milestone/Makefile
@@ -75,6 +75,7 @@ SYSTEMSVCS= \
early-manifest-import.xml \
identity.xml \
manifest-import.xml \
+ process-security.xml \
rmtmpfiles.xml \
vtdaemon.xml
diff --git a/usr/src/cmd/svc/milestone/global.xml b/usr/src/cmd/svc/milestone/global.xml
index dd65d9fed2..0441e6ed97 100644
--- a/usr/src/cmd/svc/milestone/global.xml
+++ b/usr/src/cmd/svc/milestone/global.xml
@@ -545,6 +545,15 @@ the project attribute.
</description>
<cardinality min='1' max='1'/>
</prop_pattern>
+ <prop_pattern name='security_flags' type='astring'
+ required='false'>
+ <description>
+ <loctext xml:lang='C'>
+An optional string specifying the security flags as defined in security-flags(5).
+ </loctext>
+ </description>
+ <cardinality min='1' max='1'/>
+ </prop_pattern>
<!-- method_credential properties -->
<prop_pattern name='user' type='astring'
@@ -660,7 +669,7 @@ A boolean property where a "true" value indicates an RPC service, equivalent to
required='false'>
<common_name>
<loctext xml:lang='C'>
-Custom firewall script
+Custom firewall script
</loctext>
</common_name>
<description>
diff --git a/usr/src/cmd/svc/milestone/process-security.xml b/usr/src/cmd/svc/milestone/process-security.xml
new file mode 100644
index 0000000000..bd4b2ac6b7
--- /dev/null
+++ b/usr/src/cmd/svc/milestone/process-security.xml
@@ -0,0 +1,86 @@
+<?xml version='1.0'?>
+<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
+
+<!--
+ Copyright 2015, Richard Lowe.
+
+ CDDL HEADER START
+
+ 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.
+
+ CDDL HEADER END
+
+ NOTE: This service manifest is not editable; its contents will
+ be overwritten by package or patch operations, including
+ operating system upgrade. Make customizations in a different
+ file.
+-->
+
+<service_bundle type="manifest" name="process-security">
+ <service name="system/process-security" type="service" version="1">
+ <!-- Initial state of the service is disabled -->
+ <create_default_instance enabled="false" />
+
+ <single_instance />
+
+ <!-- We don't actually have any methods, but we create a
+ default instance so that we show up in svcs -a -->
+
+ <exec_method type="method" name="start" exec=":true" timeout_seconds="0"/>
+ <exec_method type="method" name="stop" exec=":true" timeout_seconds="30"/>
+
+ <property_group name='startd' type='framework'>
+ <propval name='duration' type='astring' value='transient' />
+ </property_group>
+
+ <property_group name='default' type='application'>
+ <property name='aslr' type='boolean' />
+ <property name='forbidnullmap' type='boolean' />
+ <property name='noexecstack' type='boolean' />
+
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.value.process-security' />
+ </property_group>
+
+ <property_group name='lower' type='application'>
+ <property name='aslr' type='boolean' />
+ <property name='forbidnullmap' type='boolean' />
+ <property name='noexecstack' type='boolean' />
+
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.value.process-security' />
+ </property_group>
+
+ <property_group name='upper' type='application'>
+ <property name='aslr' type='boolean' />
+ <property name='forbidnullmap' type='boolean' />
+ <property name='noexecstack' type='boolean' />
+
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.value.process-security' />
+ </property_group>
+
+
+
+ <stability value="Unstable" />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>Security Flag Configuration</loctext>
+ </common_name>
+ <documentation>
+ <manpage title='security-flags' section='5'
+ manpath='/usr/share/man' />
+ <manpage title='psecflags' section='1'
+ manpath='/usr/share/man' />
+ </documentation>
+ </template>
+ </service>
+</service_bundle>
diff --git a/usr/src/cmd/svc/milestone/restarter.xml b/usr/src/cmd/svc/milestone/restarter.xml
index 4d66ab3043..c867736d51 100644
--- a/usr/src/cmd/svc/milestone/restarter.xml
+++ b/usr/src/cmd/svc/milestone/restarter.xml
@@ -657,6 +657,22 @@ the project attribute.
<cardinality min='1' max='1'/>
</prop_pattern>
+ <prop_pattern name='security_flags' type='astring'
+ required='false'>
+ <common_name>
+ <loctext xml:lang='C'>
+method credential security flags
+ </loctext>
+ </common_name>
+ <description>
+ <loctext xml:lang='C'>
+An optional string specifying the security flags as defined in security-flags(5).
+ </loctext>
+ </description>
+ <cardinality min='1' max='1'/>
+ <internal_separators>,</internal_separators>
+ </prop_pattern>
+
<!-- method_credential properties -->
<prop_pattern name='user' type='astring'
required='false'>
@@ -749,7 +765,7 @@ user, group, privileges, and limit_privileges properties.
required='false'>
<common_name>
<loctext xml:lang='C'>
-method profile RBAC profile specification
+method profile RBAC profile specification
</loctext>
</common_name>
<description>
@@ -904,6 +920,22 @@ the project attribute.
<cardinality min='1' max='1'/>
</prop_pattern>
+ <prop_pattern name='security_flags' type='astring'
+ required='false'>
+ <common_name>
+ <loctext xml:lang='C'>
+method credential security flags
+ </loctext>
+ </common_name>
+ <description>
+ <loctext xml:lang='C'>
+An optional string specifying the security flags as defined in security-flags(5).
+ </loctext>
+ </description>
+ <cardinality min='1' max='1'/>
+ <internal_separators>,</internal_separators>
+ </prop_pattern>
+
<!-- method_credential properties -->
<prop_pattern name='user' type='astring'
required='false'>
@@ -996,7 +1028,7 @@ user, group, privileges, and limit_privileges properties.
required='false'>
<common_name>
<loctext xml:lang='C'>
-method profile RBAC profile specification
+method profile RBAC profile specification
</loctext>
</common_name>
<description>
@@ -1150,6 +1182,21 @@ the project attribute.
</description>
<cardinality min='1' max='1'/>
</prop_pattern>
+ <prop_pattern name='security_flags' type='astring'
+ required='false'>
+ <common_name>
+ <loctext xml:lang='C'>
+method security flags
+ </loctext>
+ </common_name>
+ <description>
+ <loctext xml:lang='C'>
+An optional string specifying the security flags as defined in security-flags(5).
+ </loctext>
+ </description>
+ <cardinality min='1' max='1'/>
+ <internal_separators>,</internal_separators>
+ </prop_pattern>
<!-- method_credential properties -->
<prop_pattern name='user' type='astring'
@@ -1243,7 +1290,7 @@ user, group, privileges, and limit_privileges properties.
required='false'>
<common_name>
<loctext xml:lang='C'>
-method profile RBAC profile specification
+method profile RBAC profile specification
</loctext>
</common_name>
<description>
diff --git a/usr/src/cmd/svc/svccfg/svccfg_libscf.c b/usr/src/cmd/svc/svccfg/svccfg_libscf.c
index 3866bc4bd0..bc3191ac88 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_libscf.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_libscf.c
@@ -9516,6 +9516,8 @@ export_method(scf_propertygroup_t *pg, struct entity_elts *eelts)
SCF_SUCCESS ||
scf_pg_get_property(pg, SCF_PROPERTY_RESOURCE_POOL, NULL) ==
SCF_SUCCESS ||
+ scf_pg_get_property(pg, SCF_PROPERTY_SECFLAGS, NULL) ==
+ SCF_SUCCESS ||
scf_pg_get_property(pg, SCF_PROPERTY_USE_PROFILE, NULL) ==
SCF_SUCCESS;
@@ -9540,6 +9542,12 @@ export_method(scf_propertygroup_t *pg, struct entity_elts *eelts)
set_attr_from_prop_default(exp_prop, ctxt,
"resource_pool", ":default") != 0)
err = 1;
+
+ if (pg_get_prop(pg, SCF_PROPERTY_SECFLAGS, exp_prop) == 0 &&
+ set_attr_from_prop_default(exp_prop, ctxt,
+ "security_flags", ":default") != 0)
+ err = 1;
+
/*
* We only want to complain about profile or credential
* properties if we will use them. To determine that we must
@@ -9662,7 +9670,8 @@ export_method(scf_propertygroup_t *pg, struct entity_elts *eelts)
strcmp(exp_str, SCF_PROPERTY_GROUP) == 0 ||
strcmp(exp_str, SCF_PROPERTY_SUPP_GROUPS) == 0 ||
strcmp(exp_str, SCF_PROPERTY_PRIVILEGES) == 0 ||
- strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) == 0) {
+ strcmp(exp_str, SCF_PROPERTY_LIMIT_PRIVILEGES) == 0 ||
+ strcmp(exp_str, SCF_PROPERTY_SECFLAGS) == 0) {
if (nonenv && !use_profile)
continue;
} else if (strcmp(exp_str, SCF_PROPERTY_PROFILE) == 0) {
@@ -9848,6 +9857,10 @@ export_method_context(scf_propertygroup_t *pg, struct entity_elts *elts)
if (set_attr_from_prop(exp_prop, n,
"resource_pool") != 0)
err = 1;
+ } else if (strcmp(exp_str, SCF_PROPERTY_SECFLAGS) == 0) {
+ if (set_attr_from_prop(exp_prop, n,
+ "security_flags") != 0)
+ err = 1;
} else if (strcmp(exp_str, SCF_PROPERTY_USE_PROFILE) == 0) {
/* EMPTY */
} else if (strcmp(exp_str, SCF_PROPERTY_USER) == 0) {
diff --git a/usr/src/cmd/svc/svccfg/svccfg_xml.c b/usr/src/cmd/svc/svccfg/svccfg_xml.c
index 66b1b3c042..0e0a455b07 100644
--- a/usr/src/cmd/svc/svccfg/svccfg_xml.c
+++ b/usr/src/cmd/svc/svccfg/svccfg_xml.c
@@ -1014,6 +1014,10 @@ lxml_get_method_context(pgroup_t *pg, xmlNodePtr ctx)
SCF_TYPE_ASTRING, ctx, "resource_pool", NULL) != 0)
return (-1);
+ if (new_opt_str_prop_from_attr(pg, SCF_PROPERTY_SECFLAGS,
+ SCF_TYPE_ASTRING, ctx, "security_flags", NULL) != 0)
+ return (-1);
+
for (cursor = ctx->xmlChildrenNode; cursor != NULL;
cursor = cursor->next) {
if (lxml_ignorable_block(cursor))
@@ -1100,7 +1104,8 @@ lxml_get_exec_method(entity_t *entity, xmlNodePtr emeth)
/*
* There is a possibility that a method context also exists, in which
* case the following attributes are defined: project, resource_pool,
- * working_directory, profile, user, group, privileges, limit_privileges
+ * working_directory, profile, user, group, privileges,
+ * limit_privileges, security_flags
*/
for (cursor = emeth->xmlChildrenNode; cursor != NULL;
cursor = cursor->next) {
@@ -3353,7 +3358,8 @@ lxml_get_single_instance(entity_t *entity, xmlNodePtr si)
* that are still located in the /var/svc manifests directory.
*/
static int
-lxml_check_upgrade(const char *service) {
+lxml_check_upgrade(const char *service)
+{
scf_handle_t *h = NULL;
scf_scope_t *sc = NULL;
scf_service_t *svc = NULL;
diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c
index 72876bfdb8..14472f22c3 100644
--- a/usr/src/cmd/truss/print.c
+++ b/usr/src/cmd/truss/print.c
@@ -67,6 +67,7 @@
#include <sys/rtpriocntl.h>
#include <sys/fsspriocntl.h>
#include <sys/fxpriocntl.h>
+#include <sys/proc.h>
#include <netdb.h>
#include <nss_dbdefs.h>
#include <sys/socketvar.h>
@@ -1600,6 +1601,98 @@ prt_pc5(private_t *pri, int raw, long val)
prt_dec(pri, 0, PC_KY_NULL);
}
+
+void
+prt_psflags(private_t *pri, secflagset_t val)
+{
+ char str[1024];
+
+ if (val == 0) {
+ outstring(pri, "0x0");
+ return;
+ }
+
+ *str = '\0';
+ if (secflag_isset(val, PROC_SEC_ASLR)) {
+ (void) strlcat(str, "|PROC_SEC_ASLR", sizeof (str));
+ secflag_clear(&val, PROC_SEC_ASLR);
+ }
+ if (secflag_isset(val, PROC_SEC_FORBIDNULLMAP)) {
+ (void) strlcat(str, "|PROC_SEC_FORBIDNULLMAP",
+ sizeof (str));
+ secflag_clear(&val, PROC_SEC_FORBIDNULLMAP);
+ }
+ if (secflag_isset(val, PROC_SEC_NOEXECSTACK)) {
+ (void) strlcat(str, "|PROC_SEC_NOEXECSTACK",
+ sizeof (str));
+ secflag_clear(&val, PROC_SEC_NOEXECSTACK);
+ }
+
+ if (val != 0)
+ (void) snprintf(str, sizeof (str), "%s|%#x", str, val);
+
+ outstring(pri, str + 1);
+}
+
+/*
+ * Print a psecflags(2) delta
+ */
+void
+prt_psdelta(private_t *pri, int raw, long value)
+{
+ secflagdelta_t psd;
+
+ if ((raw != 0) ||
+ (Pread(Proc, &psd, sizeof (psd), value) != sizeof (psd))) {
+ prt_hex(pri, 0, value);
+ return;
+ }
+ outstring(pri, "{ ");
+ prt_psflags(pri, psd.psd_add);
+ outstring(pri, ", ");
+ prt_psflags(pri, psd.psd_rem);
+ outstring(pri, ", ");
+ prt_psflags(pri, psd.psd_assign);
+ outstring(pri, ", ");
+ outstring(pri, psd.psd_ass_active ? "B_TRUE" : "B_FALSE");
+ outstring(pri, " }");
+}
+
+/*
+ * Print a psecflagswhich_t
+ */
+void
+prt_psfw(private_t *pri, int raw, long value)
+{
+ psecflagwhich_t which = (psecflagwhich_t)value;
+ char *s;
+
+ if (raw != 0) {
+ prt_dec(pri, 0, value);
+ return;
+ }
+
+ switch (which) {
+ case PSF_EFFECTIVE:
+ s = "PSF_EFFECTIVE";
+ break;
+ case PSF_INHERIT:
+ s = "PSF_INHERIT";
+ break;
+ case PSF_LOWER:
+ s = "PSF_LOWER";
+ break;
+ case PSF_UPPER:
+ s = "PSF_UPPER";
+ break;
+ }
+
+ if (s == NULL)
+ prt_dec(pri, 0, value);
+ else
+ outstring(pri, s);
+}
+
/*
* Print processor set id, including logical expansion of "special" ids.
*/
@@ -2874,5 +2967,7 @@ void (* const Print[])() = {
prt_acf, /* ACF -- print accept4 flags */
prt_pfd, /* PFD -- print pipe fds */
prt_grf, /* GRF -- print getrandom flags */
+ prt_psdelta, /* PSDLT -- print psecflags(2) delta */
+ prt_psfw, /* PSFW -- print psecflags(2) set */
prt_dec, /* HID -- hidden argument, make this the last one */
};
diff --git a/usr/src/cmd/truss/print.h b/usr/src/cmd/truss/print.h
index 8725d2ca85..501602819c 100644
--- a/usr/src/cmd/truss/print.h
+++ b/usr/src/cmd/truss/print.h
@@ -141,7 +141,9 @@ extern "C" {
#define ACF 99 /* accept4 flags */
#define PFD 100 /* pipe fds[2] */
#define GRF 101 /* getrandom flags */
-#define HID 102 /* hidden argument, don't print */
+#define PSDLT 102 /* secflagsdelta_t */
+#define PSFW 103 /* psecflagswhich_t */
+#define HID 104 /* hidden argument, don't print */
/* make sure HID is always the last member */
/*
diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c
index febd7d71f5..fb1d3f7a14 100644
--- a/usr/src/cmd/truss/systable.c
+++ b/usr/src/cmd/truss/systable.c
@@ -221,7 +221,7 @@ errname(int err) /* return the error code name (NULL if none) */
const struct systable systable[] = {
{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX},
{"_exit", 1, DEC, NOV, DEC}, /* 1 */
-{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX},
+{"psecflags", 3, DEC, NOV, HEX, PSFW, PSDLT}, /* 2 */
{"read", 3, DEC, NOV, DEC, IOB, UNS}, /* 3 */
{"write", 3, DEC, NOV, DEC, IOB, UNS}, /* 4 */
{"open", 3, DEC, NOV, STG, OPN, OCT}, /* 5 */
diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c
index 4105cae1cc..cb741397ca 100644
--- a/usr/src/cmd/zoneadmd/vplat.c
+++ b/usr/src/cmd/zoneadmd/vplat.c
@@ -77,6 +77,7 @@
#include <sys/stropts.h>
#include <sys/conf.h>
#include <sys/systeminfo.h>
+#include <sys/secflags.h>
#include <libdlpi.h>
#include <libdllink.h>
@@ -4591,6 +4592,96 @@ setup_zone_hostid(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
}
static int
+setup_zone_secflags(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
+{
+ psecflags_t secflags;
+ struct zone_secflagstab tab = {0};
+ secflagdelta_t delt;
+ int res;
+
+ res = zonecfg_lookup_secflags(handle, &tab);
+
+ if ((res != Z_OK) &&
+ /* The general defaulting code will handle this */
+ (res != Z_NO_ENTRY) && (res != Z_BAD_PROPERTY)) {
+ zerror(zlogp, B_FALSE, "security-flags property is "
+ "invalid: %d", res);
+ return (res);
+ }
+
+ if (strlen(tab.zone_secflags_lower) == 0)
+ (void) strlcpy(tab.zone_secflags_lower, "none",
+ sizeof (tab.zone_secflags_lower));
+ if (strlen(tab.zone_secflags_default) == 0)
+ (void) strlcpy(tab.zone_secflags_default,
+ tab.zone_secflags_lower,
+ sizeof (tab.zone_secflags_default));
+ if (strlen(tab.zone_secflags_upper) == 0)
+ (void) strlcpy(tab.zone_secflags_upper, "all",
+ sizeof (tab.zone_secflags_upper));
+
+ if (secflags_parse(NULL, tab.zone_secflags_default,
+ &delt) == -1) {
+ zerror(zlogp, B_FALSE, "default security-flags: '%s'"
+ "are invalid", tab.zone_secflags_default);
+ return (Z_BAD_PROPERTY);
+ } else if (delt.psd_ass_active != B_TRUE) {
+ zerror(zlogp, B_FALSE, "relative security-flags are not "
+ "allowed in zone configuration (default "
+ "security-flags: '%s')",
+ tab.zone_secflags_default);
+ return (Z_BAD_PROPERTY);
+ } else {
+ secflags_copy(&secflags.psf_inherit, &delt.psd_assign);
+ secflags_copy(&secflags.psf_effective, &delt.psd_assign);
+ }
+
+ if (secflags_parse(NULL, tab.zone_secflags_lower,
+ &delt) == -1) {
+ zerror(zlogp, B_FALSE, "lower security-flags: '%s'"
+ "are invalid", tab.zone_secflags_lower);
+ return (Z_BAD_PROPERTY);
+ } else if (delt.psd_ass_active != B_TRUE) {
+ zerror(zlogp, B_FALSE, "relative security-flags are not "
+ "allowed in zone configuration (lower "
+ "security-flags: '%s')",
+ tab.zone_secflags_lower);
+ return (Z_BAD_PROPERTY);
+ } else {
+ secflags_copy(&secflags.psf_lower, &delt.psd_assign);
+ }
+
+ if (secflags_parse(NULL, tab.zone_secflags_upper,
+ &delt) == -1) {
+ zerror(zlogp, B_FALSE, "upper security-flags: '%s'"
+ "are invalid", tab.zone_secflags_upper);
+ return (Z_BAD_PROPERTY);
+ } else if (delt.psd_ass_active != B_TRUE) {
+ zerror(zlogp, B_FALSE, "relative security-flags are not "
+ "allowed in zone configuration (upper "
+ "security-flags: '%s')",
+ tab.zone_secflags_upper);
+ return (Z_BAD_PROPERTY);
+ } else {
+ secflags_copy(&secflags.psf_upper, &delt.psd_assign);
+ }
+
+ if (!psecflags_validate(&secflags)) {
+ zerror(zlogp, B_TRUE, "security-flags violate invariants");
+ return (Z_BAD_PROPERTY);
+ }
+
+ if ((res = zone_setattr(zoneid, ZONE_ATTR_SECFLAGS, &secflags,
+ sizeof (secflags))) != 0) {
+ zerror(zlogp, B_TRUE,
+ "security-flags couldn't be set: %d", res);
+ return (Z_SYSTEM);
+ }
+
+ return (Z_OK);
+}
+
+static int
setup_zone_fs_allowed(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
{
char fsallowed[ZONE_FS_ALLOWED_MAX];
@@ -4607,7 +4698,7 @@ setup_zone_fs_allowed(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid)
report_prop_err(zlogp, "fs-allowed", fsallowed, res);
return (res);
} else if (fsallowed[0] == '-') {
- /* dropping default privs - use remaining list */
+ /* dropping default filesystems - use remaining list */
if (fsallowed[1] != ',')
return (Z_OK);
fsallowedp += 2;
@@ -4652,6 +4743,9 @@ setup_zone_attrs(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid)
if ((res = setup_zone_fs_allowed(handle, zlogp, zoneid)) != Z_OK)
goto out;
+ if ((res = setup_zone_secflags(handle, zlogp, zoneid)) != Z_OK)
+ goto out;
+
out:
zonecfg_fini_handle(handle);
return (res);
diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c
index 3dbec383bf..ab35860691 100644
--- a/usr/src/cmd/zonecfg/zonecfg.c
+++ b/usr/src/cmd/zonecfg/zonecfg.c
@@ -53,6 +53,7 @@
#include <sys/mntent.h>
#include <sys/varargs.h>
#include <sys/sysmacros.h>
+#include <sys/secflags.h>
#include <errno.h>
#include <fcntl.h>
@@ -187,6 +188,7 @@ char *res_types[] = {
"admin",
"fs-allowed",
ALIAS_MAXPROCS,
+ "security-flags",
NULL
};
@@ -234,6 +236,9 @@ char *prop_types[] = {
"fs-allowed",
ALIAS_MAXPROCS,
"allowed-address",
+ "default",
+ "lower",
+ "upper",
NULL
};
@@ -282,6 +287,7 @@ static const char *add_cmds[] = {
"add capped-cpu",
"add capped-memory",
"add admin",
+ "add security-flags",
NULL
};
@@ -313,6 +319,7 @@ static const char *remove_cmds[] = {
"remove capped-cpu ",
"remove capped-memory ",
"remove admin ",
+ "remove security-flags",
NULL
};
@@ -327,6 +334,7 @@ static const char *select_cmds[] = {
"select capped-cpu",
"select capped-memory",
"select admin",
+ "select security-flags",
NULL
};
@@ -362,6 +370,7 @@ static const char *info_cmds[] = {
"info capped-memory",
"info dedicated-cpu",
"info capped-cpu",
+ "info security-flags",
"info zonename",
"info zonepath",
"info autoboot",
@@ -504,6 +513,16 @@ static const char *admin_res_scope_cmds[] = {
NULL
};
+static const char *secflags_res_scope_cmds[] = {
+ "cancel",
+ "end",
+ "exit",
+ "set default=",
+ "set lower=",
+ "set upper=",
+ NULL
+};
+
struct xif {
struct xif *xif_next;
char xif_name[LIFNAMSIZ];
@@ -581,6 +600,7 @@ static struct zone_dstab old_dstab, in_progress_dstab;
static struct zone_psettab old_psettab, in_progress_psettab;
static struct zone_mcaptab old_mcaptab, in_progress_mcaptab;
static struct zone_admintab old_admintab, in_progress_admintab;
+static struct zone_secflagstab old_secflagstab, in_progress_secflagstab;
static GetLine *gl; /* The gl_get_line() resource object */
@@ -658,6 +678,10 @@ CPL_MATCH_FN(cmd_cpl_fn)
return (add_stuff(cpl, line, mcap_res_scope_cmds, word_end));
case RT_ADMIN:
return (add_stuff(cpl, line, admin_res_scope_cmds, word_end));
+ case RT_SECFLAGS:
+ return (add_stuff(cpl, line, secflags_res_scope_cmds,
+ word_end));
+
}
return (0);
}
@@ -973,7 +997,8 @@ path_find(const char *name)
}
static FILE *
-pager_open(void) {
+pager_open(void)
+{
FILE *newfp;
char *pager, *space;
@@ -999,7 +1024,8 @@ pager_open(void) {
}
static void
-pager_close(FILE *fp) {
+pager_close(FILE *fp)
+{
int status;
status = pclose(fp);
@@ -1227,6 +1253,21 @@ usage(boolean_t verbose, uint_t flags)
pt_to_str(PT_AUTHS),
gettext("<comma separated list>"));
break;
+ case RT_SECFLAGS:
+ (void) fprintf(fp, gettext("The '%s' resource scope is "
+ "used to specify the default security-flags\n"
+ "of this zone, and their upper and lower bound.\n"),
+ rt_to_str(resource_scope));
+ (void) fprintf(fp, "\t%s %s=%s\n",
+ cmd_to_str(CMD_SET), pt_to_str(PT_DEFAULT),
+ gettext("<security flags>"));
+ (void) fprintf(fp, "\t%s %s=%s\n",
+ cmd_to_str(CMD_SET), pt_to_str(PT_LOWER),
+ gettext("<security flags>"));
+ (void) fprintf(fp, "\t%s %s=%s\n",
+ cmd_to_str(CMD_SET), pt_to_str(PT_UPPER),
+ gettext("<security flags>"));
+ break;
}
(void) fprintf(fp, gettext("And from any resource scope, you "
"can:\n"));
@@ -1291,7 +1332,7 @@ usage(boolean_t verbose, uint_t flags)
rt_to_str(RT_RCTL), rt_to_str(RT_ATTR),
rt_to_str(RT_DATASET), rt_to_str(RT_DCPU),
rt_to_str(RT_PCAP), rt_to_str(RT_MCAP),
- rt_to_str(RT_ADMIN));
+ rt_to_str(RT_ADMIN), rt_to_str(RT_SECFLAGS));
}
if (flags & HELP_PROPS) {
(void) fprintf(fp, gettext("For resource type ... there are "
@@ -1357,6 +1398,9 @@ usage(boolean_t verbose, uint_t flags)
pt_to_str(PT_LOCKED));
(void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_ADMIN),
pt_to_str(PT_USER), pt_to_str(PT_AUTHS));
+ (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n",
+ rt_to_str(RT_SECFLAGS), pt_to_str(PT_DEFAULT),
+ pt_to_str(PT_LOWER), pt_to_str(PT_UPPER));
}
if (need_to_close)
(void) pager_close(fp);
@@ -1800,6 +1844,7 @@ export_func(cmd_t *cmd)
struct zone_mcaptab mcaptab;
struct zone_rctlvaltab *valptr;
struct zone_admintab admintab;
+ struct zone_secflagstab secflagstab;
int err, arg;
char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
char bootargs[BOOTARGS_MAX];
@@ -2069,8 +2114,18 @@ export_func(cmd_t *cmd)
export_prop(of, PT_AUTHS, admintab.zone_admin_auths);
(void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
}
+
(void) zonecfg_endadminent(handle);
+ if (zonecfg_getsecflagsent(handle, &secflagstab) == Z_OK) {
+ (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
+ rt_to_str(RT_SECFLAGS));
+ export_prop(of, PT_DEFAULT, secflagstab.zone_secflags_default);
+ export_prop(of, PT_LOWER, secflagstab.zone_secflags_lower);
+ export_prop(of, PT_UPPER, secflagstab.zone_secflags_upper);
+ (void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
+ }
+
/*
* There is nothing to export for pcap since this resource is just
* a container for an rctl alias.
@@ -2150,6 +2205,7 @@ add_resource(cmd_t *cmd)
int type;
struct zone_psettab tmp_psettab;
struct zone_mcaptab tmp_mcaptab;
+ struct zone_secflagstab tmp_secflagstab;
uint64_t tmp;
uint64_t tmp_mcap;
char pool[MAXNAMELEN];
@@ -2261,6 +2317,14 @@ add_resource(cmd_t *cmd)
case RT_ADMIN:
bzero(&in_progress_admintab, sizeof (in_progress_admintab));
return;
+ case RT_SECFLAGS:
+ /* Make sure we haven't already set this */
+ if (zonecfg_lookup_secflags(handle, &tmp_secflagstab) == Z_OK)
+ zerr(gettext("The %s resource already exists."),
+ rt_to_str(RT_SECFLAGS));
+ bzero(&in_progress_secflagstab,
+ sizeof (in_progress_secflagstab));
+ return;
default:
zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
long_usage(CMD_ADD, B_TRUE);
@@ -2930,6 +2994,54 @@ fill_in_admintab(cmd_t *cmd, struct zone_admintab *admintab,
return (err);
}
+static int
+fill_in_secflagstab(cmd_t *cmd, struct zone_secflagstab *secflagstab,
+ boolean_t fill_in_only)
+{
+ int err, i;
+ property_value_ptr_t pp;
+
+ if ((err = initialize(B_TRUE)) != Z_OK)
+ return (err);
+
+ bzero(secflagstab, sizeof (*secflagstab));
+ for (i = 0; i < cmd->cmd_prop_nv_pairs; i++) {
+ pp = cmd->cmd_property_ptr[i];
+ if (pp->pv_type != PROP_VAL_SIMPLE || pp->pv_simple == NULL) {
+ zerr(gettext("A simple value was expected here."));
+ saw_error = B_TRUE;
+ return (Z_INSUFFICIENT_SPEC);
+ }
+ switch (cmd->cmd_prop_name[i]) {
+ case PT_DEFAULT:
+ (void) strlcpy(secflagstab->zone_secflags_default,
+ pp->pv_simple,
+ sizeof (secflagstab->zone_secflags_default));
+ break;
+ case PT_LOWER:
+ (void) strlcpy(secflagstab->zone_secflags_lower,
+ pp->pv_simple,
+ sizeof (secflagstab->zone_secflags_lower));
+ break;
+ case PT_UPPER:
+ (void) strlcpy(secflagstab->zone_secflags_upper,
+ pp->pv_simple,
+ sizeof (secflagstab->zone_secflags_upper));
+ break;
+ default:
+ zone_perror(pt_to_str(cmd->cmd_prop_name[i]),
+ Z_NO_PROPERTY_TYPE, B_TRUE);
+ return (Z_INSUFFICIENT_SPEC);
+ }
+ }
+ if (fill_in_only)
+ return (Z_OK);
+
+ err = zonecfg_lookup_secflags(handle, secflagstab);
+
+ return (err);
+}
+
static void
remove_aliased_rctl(int type, char *name)
{
@@ -3332,6 +3444,27 @@ remove_admin(cmd_t *cmd)
}
static void
+remove_secflags()
+{
+ int err;
+ struct zone_secflagstab sectab = { 0 };
+
+ if (zonecfg_lookup_secflags(handle, &sectab) != Z_OK) {
+ zerr("%s %s: %s", cmd_to_str(CMD_REMOVE),
+ rt_to_str(RT_SECFLAGS),
+ zonecfg_strerror(Z_NO_RESOURCE_TYPE));
+ return;
+ }
+
+ if ((err = zonecfg_delete_secflags(handle, &sectab)) != Z_OK) {
+ z_cmd_rt_perror(CMD_REMOVE, RT_SECFLAGS, err, B_TRUE);
+ return;
+ }
+
+ need_to_commit = B_TRUE;
+}
+
+static void
remove_resource(cmd_t *cmd)
{
int type;
@@ -3395,6 +3528,9 @@ remove_resource(cmd_t *cmd)
case RT_ADMIN:
remove_admin(cmd);
return;
+ case RT_SECFLAGS:
+ remove_secflags();
+ return;
default:
zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
long_usage(CMD_REMOVE, B_TRUE);
@@ -3607,6 +3743,22 @@ clear_property(cmd_t *cmd)
return;
}
break;
+ case RT_SECFLAGS:
+ switch (prop_type) {
+ case PT_LOWER:
+ in_progress_secflagstab.zone_secflags_lower[0] = '\0';
+ need_to_commit = B_TRUE;
+ return;
+ case PT_DEFAULT:
+ in_progress_secflagstab.zone_secflags_default[0] = '\0';
+ need_to_commit = B_TRUE;
+ return;
+ case PT_UPPER:
+ in_progress_secflagstab.zone_secflags_upper[0] = '\0';
+ need_to_commit = B_TRUE;
+ return;
+ }
+ break;
default:
break;
}
@@ -3860,6 +4012,16 @@ select_func(cmd_t *cmd)
bcopy(&old_admintab, &in_progress_admintab,
sizeof (struct zone_admintab));
return;
+ case RT_SECFLAGS:
+ if ((err = fill_in_secflagstab(cmd, &old_secflagstab, B_FALSE))
+ != Z_OK) {
+ z_cmd_rt_perror(CMD_SELECT, RT_SECFLAGS, err,
+ B_TRUE);
+ global_scope = B_TRUE;
+ }
+ bcopy(&old_secflagstab, &in_progress_secflagstab,
+ sizeof (struct zone_secflagstab));
+ return;
default:
zone_perror(rt_to_str(type), Z_NO_RESOURCE_TYPE, B_TRUE);
long_usage(CMD_SELECT, B_TRUE);
@@ -4776,6 +4938,29 @@ set_func(cmd_t *cmd)
usage(B_FALSE, HELP_PROPS);
return;
}
+ case RT_SECFLAGS: {
+ char *propstr;
+
+ switch (prop_type) {
+ case PT_DEFAULT:
+ propstr = in_progress_secflagstab.zone_secflags_default;
+ break;
+ case PT_UPPER:
+ propstr = in_progress_secflagstab.zone_secflags_upper;
+ break;
+ case PT_LOWER:
+ propstr = in_progress_secflagstab.zone_secflags_lower;
+ break;
+ default:
+ zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
+ B_TRUE);
+ long_usage(CMD_SET, B_TRUE);
+ usage(B_FALSE, HELP_PROPS);
+ return;
+ }
+ (void) strlcpy(propstr, prop_id, ZONECFG_SECFLAGS_MAX);
+ return;
+ }
default:
zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
long_usage(CMD_SET, B_TRUE);
@@ -5390,6 +5575,15 @@ output_auth(FILE *fp, struct zone_admintab *admintab)
}
static void
+output_secflags(FILE *fp, struct zone_secflagstab *sftab)
+{
+ (void) fprintf(fp, "%s:\n", rt_to_str(RT_SECFLAGS));
+ output_prop(fp, PT_DEFAULT, sftab->zone_secflags_default, B_TRUE);
+ output_prop(fp, PT_LOWER, sftab->zone_secflags_lower, B_TRUE);
+ output_prop(fp, PT_UPPER, sftab->zone_secflags_upper, B_TRUE);
+}
+
+static void
info_auth(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
{
struct zone_admintab lookup, user;
@@ -5423,6 +5617,16 @@ info_auth(zone_dochandle_t handle, FILE *fp, cmd_t *cmd)
rt_to_str(RT_ADMIN));
}
+static void
+info_secflags(zone_dochandle_t handle, FILE *fp)
+{
+ struct zone_secflagstab sftab;
+
+ if (zonecfg_lookup_secflags(handle, &sftab) == Z_OK) {
+ output_secflags(fp, &sftab);
+ }
+}
+
void
info_func(cmd_t *cmd)
{
@@ -5485,6 +5689,9 @@ info_func(cmd_t *cmd)
case RT_ADMIN:
output_auth(fp, &in_progress_admintab);
break;
+ case RT_SECFLAGS:
+ output_secflags(fp, &in_progress_secflagstab);
+ break;
}
goto cleanup;
}
@@ -5541,6 +5748,7 @@ info_func(cmd_t *cmd)
info_auth(handle, fp, cmd);
}
info_rctl(handle, fp, cmd);
+ info_secflags(handle, fp);
break;
case RT_ZONENAME:
info_zonename(handle, fp);
@@ -5626,6 +5834,9 @@ info_func(cmd_t *cmd)
case RT_FS_ALLOWED:
info_fs_allowed(handle, fp);
break;
+ case RT_SECFLAGS:
+ info_secflags(handle, fp);
+ break;
default:
zone_perror(rt_to_str(cmd->cmd_res_type), Z_NO_RESOURCE_TYPE,
B_TRUE);
@@ -5777,6 +5988,88 @@ add_nwif(struct zone_nwiftab *nwif)
return (B_TRUE);
}
+boolean_t
+verify_secflags(struct zone_secflagstab *tab)
+{
+ secflagdelta_t def = {0};
+ secflagdelta_t upper = {0};
+ secflagdelta_t lower = {0};
+ boolean_t def_set = B_FALSE;
+ boolean_t upper_set = B_FALSE;
+ boolean_t lower_set = B_FALSE;
+ boolean_t ret = B_TRUE;
+
+ if (strlen(tab->zone_secflags_default) > 0) {
+ def_set = B_TRUE;
+ if (secflags_parse(NULL, tab->zone_secflags_default,
+ &def) == -1) {
+ zerr(gettext("default security flags '%s' are invalid"),
+ tab->zone_secflags_default);
+ ret = B_FALSE;
+ }
+ } else {
+ secflags_zero(&def.psd_assign);
+ def.psd_ass_active = B_TRUE;
+ }
+
+ if (strlen(tab->zone_secflags_upper) > 0) {
+ upper_set = B_TRUE;
+ if (secflags_parse(NULL, tab->zone_secflags_upper,
+ &upper) == -1) {
+ zerr(gettext("upper security flags '%s' are invalid"),
+ tab->zone_secflags_upper);
+ ret = B_FALSE;
+ }
+ } else {
+ secflags_fullset(&upper.psd_assign);
+ upper.psd_ass_active = B_TRUE;
+ }
+
+ if (strlen(tab->zone_secflags_lower) > 0) {
+ lower_set = B_TRUE;
+ if (secflags_parse(NULL, tab->zone_secflags_lower,
+ &lower) == -1) {
+ zerr(gettext("lower security flags '%s' are invalid"),
+ tab->zone_secflags_lower);
+ ret = B_FALSE;
+ }
+ } else {
+ secflags_zero(&lower.psd_assign);
+ lower.psd_ass_active = B_TRUE;
+ }
+
+ if (def_set && !def.psd_ass_active) {
+ zerr(gettext("only assignment of security flags is "
+ "allowed (default: %s)"), tab->zone_secflags_default);
+ }
+
+ if (lower_set && !lower.psd_ass_active) {
+ zerr(gettext("only assignment of security flags is "
+ "allowed (lower: %s)"), tab->zone_secflags_lower);
+ }
+
+ if (upper_set && !upper.psd_ass_active) {
+ zerr(gettext("only assignment of security flags is "
+ "allowed (upper: %s)"), tab->zone_secflags_upper);
+ }
+
+ if (def.psd_assign & ~upper.psd_assign) { /* In default but not upper */
+ zerr(gettext("default secflags must be within the "
+ "upper limit"));
+ ret = B_FALSE;
+ }
+ if (lower.psd_assign & ~def.psd_assign) { /* In lower but not default */
+ zerr(gettext("default secflags must be above the lower limit"));
+ ret = B_FALSE;
+ }
+ if (lower.psd_assign & ~upper.psd_assign) { /* In lower but not upper */
+ zerr(gettext("lower secflags must be within the upper limit"));
+ ret = B_FALSE;
+ }
+
+ return (ret);
+}
+
/*
* See the DTD for which attributes are required for which resources.
*
@@ -5796,6 +6089,7 @@ verify_func(cmd_t *cmd)
struct zone_dstab dstab;
struct zone_psettab psettab;
struct zone_admintab admintab;
+ struct zone_secflagstab secflagstab;
char zonepath[MAXPATHLEN];
char sched[MAXNAMELEN];
char brand[MAXNAMELEN];
@@ -6092,6 +6386,17 @@ verify_func(cmd_t *cmd)
}
(void) zonecfg_endadminent(handle);
+ if (zonecfg_getsecflagsent(handle, &secflagstab) == Z_OK) {
+ /*
+ * No properties are required, but any specified should be
+ * valid
+ */
+ if (verify_secflags(&secflagstab) != B_TRUE) {
+ /* Error is reported from verify_secflags */
+ ret_val = Z_BAD_PROPERTY;
+ }
+ }
+
if (!global_scope) {
zerr(gettext("resource specification incomplete"));
saw_error = B_TRUE;
@@ -6681,6 +6986,20 @@ end_func(cmd_t *cmd)
zone);
}
break;
+ case RT_SECFLAGS:
+ if (verify_secflags(&in_progress_secflagstab) != B_TRUE) {
+ saw_error = B_TRUE;
+ return;
+ }
+
+ if (end_op == CMD_ADD) {
+ err = zonecfg_add_secflags(handle,
+ &in_progress_secflagstab);
+ } else {
+ err = zonecfg_modify_secflags(handle,
+ &old_secflagstab, &in_progress_secflagstab);
+ }
+ break;
default:
zone_perror(rt_to_str(resource_scope), Z_NO_RESOURCE_TYPE,
B_TRUE);
diff --git a/usr/src/cmd/zonecfg/zonecfg.h b/usr/src/cmd/zonecfg/zonecfg.h
index d8f8b14ce8..108d0ce507 100644
--- a/usr/src/cmd/zonecfg/zonecfg.h
+++ b/usr/src/cmd/zonecfg/zonecfg.h
@@ -90,9 +90,10 @@ extern "C" {
#define RT_ADMIN 26
#define RT_FS_ALLOWED 27
#define RT_MAXPROCS 28 /* really a rctl alias property, but for info */
+#define RT_SECFLAGS 29
#define RT_MIN RT_UNKNOWN
-#define RT_MAX RT_MAXPROCS
+#define RT_MAX RT_SECFLAGS
/* property types: increment PT_MAX when expanding this list */
#define PT_UNKNOWN 0
@@ -137,9 +138,12 @@ extern "C" {
#define PT_FS_ALLOWED 39
#define PT_MAXPROCS 40
#define PT_ALLOWED_ADDRESS 41
+#define PT_DEFAULT 42
+#define PT_LOWER 43
+#define PT_UPPER 44
#define PT_MIN PT_UNKNOWN
-#define PT_MAX PT_ALLOWED_ADDRESS
+#define PT_MAX PT_UPPER
#define MAX_EQ_PROP_PAIRS 3
diff --git a/usr/src/cmd/zonecfg/zonecfg_grammar.y b/usr/src/cmd/zonecfg/zonecfg_grammar.y
index d7f11b6a46..2e950512ec 100644
--- a/usr/src/cmd/zonecfg/zonecfg_grammar.y
+++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y
@@ -135,17 +135,18 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next)
%token NAME MATCH PRIV LIMIT ACTION VALUE EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET
%token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS BRAND PSET PCAP
%token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS
-%token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN USER AUTHS MAXPROCS
+%token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN SECFLAGS USER AUTHS MAXPROCS
+%token DEFAULT UPPER LOWER
%type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET
property_value OPEN_PAREN CLOSE_PAREN COMMA simple_prop_val
%type <complex> complex_piece complex_prop_val
%type <ival> resource_type NET FS DEVICE RCTL ATTR DATASET PSET PCAP MCAP
- ADMIN
+ ADMIN SECFLAGS
%type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME
MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT
ACTION BRAND SCHED IPTYPE DEFROUTER HOSTID USER AUTHS FS_ALLOWED
- ALLOWED_ADDRESS
+ ALLOWED_ADDRESS DEFAULT UPPER LOWER
%type <cmd> command
%type <cmd> add_command ADD
%type <cmd> cancel_command CANCEL
@@ -959,6 +960,7 @@ resource_type: NET { $$ = RT_NET; }
| PCAP { $$ = RT_PCAP; }
| MCAP { $$ = RT_MCAP; }
| ADMIN { $$ = RT_ADMIN; }
+ | SECFLAGS { $$ = RT_SECFLAGS; }
property_name: SPECIAL { $$ = PT_SPECIAL; }
| RAW { $$ = PT_RAW; }
@@ -999,6 +1001,9 @@ property_name: SPECIAL { $$ = PT_SPECIAL; }
| USER { $$ = PT_USER; }
| AUTHS { $$ = PT_AUTHS; }
| FS_ALLOWED { $$ = PT_FS_ALLOWED; }
+ | DEFAULT { $$ = PT_DEFAULT; }
+ | UPPER { $$ = PT_UPPER; }
+ | LOWER { $$ = PT_LOWER; }
/*
* The grammar builds data structures from the bottom up. Thus various
@@ -1111,20 +1116,20 @@ complex_piece: property_name EQUAL TOKEN
if (($$ = complex_piece_func($1, prop_types[$3], NULL)) == NULL)
YYERROR;
}
- | property_name EQUAL TOKEN COMMA complex_piece
+ | property_name EQUAL TOKEN COMMA complex_piece
{
$$ = complex_piece_func($1, $3, complex);
free(claim_token($3));
if ($$ == NULL)
YYERROR;
}
- | property_name EQUAL resource_type COMMA complex_piece
+ | property_name EQUAL resource_type COMMA complex_piece
{
if (($$ = complex_piece_func($1, res_types[$3], complex)) ==
NULL)
YYERROR;
}
- | property_name EQUAL property_name COMMA complex_piece
+ | property_name EQUAL property_name COMMA complex_piece
{
if (($$ = complex_piece_func($1, prop_types[$3], complex)) ==
NULL)
diff --git a/usr/src/cmd/zonecfg/zonecfg_lex.l b/usr/src/cmd/zonecfg/zonecfg_lex.l
index 6a0b577b75..8714c55499 100644
--- a/usr/src/cmd/zonecfg/zonecfg_lex.l
+++ b/usr/src/cmd/zonecfg/zonecfg_lex.l
@@ -183,6 +183,8 @@ static char *create_token(char *s);
<TSTATE>admin { return ADMIN; }
+<TSTATE>security-flags { return SECFLAGS; }
+
<TSTATE>zonename { return ZONENAME; }
<CSTATE>zonename { return ZONENAME; }
@@ -308,6 +310,15 @@ static char *create_token(char *s);
<TSTATE>fs-allowed { return FS_ALLOWED; }
<CSTATE>fs-allowed { return FS_ALLOWED; }
+<TSTATE>default { return DEFAULT; }
+<CSTATE>default { return DEFAULT; }
+
+<TSTATE>lower { return LOWER; }
+<CSTATE>lower { return LOWER; }
+
+<TSTATE>upper { return UPPER; }
+<CSTATE>upper { return UPPER; }
+
<TSTATE>= { return EQUAL; }
<LSTATE>= { return EQUAL; }
<CSTATE>= { return EQUAL; }