Mercurial > illumos > fmac
changeset 7840:a2e814385870
First FMAC System Calls
line wrap: on
line diff
--- a/usr/src/cmd/fmac/Makefile Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/cmd/fmac/Makefile Fri Jun 20 08:29:57 2008 -0700 @@ -27,10 +27,15 @@ include ../Makefile.cmd -SUBDIRS = checkpolicy \ +SUBDIR_CMD = checkpolicy \ setfiles \ + loadpolicy + +SUBDIR_POLICY = \ policy +SUBDIRS = $(SUBDIR_CMD) $(SUBDIR_POLICY) + all := TARGET = all install := TARGET = install clean := TARGET = clean @@ -44,3 +49,5 @@ $(SUBDIRS): @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET) + +_msg: $(SUBDIR_CMD)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/fmac/loadpolicy/Makefile Fri Jun 20 08:29:57 2008 -0700 @@ -0,0 +1,44 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= loadpolicy + +include ../../Makefile.cmd + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTSBINPROG) + +clean: + +lint: lint_PROG + +include ../../Makefile.targ
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/fmac/loadpolicy/loadpolicy.c Fri Jun 20 08:29:57 2008 -0700 @@ -0,0 +1,76 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Load security policy from the specified file. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <locale.h> +#include <libintl.h> +#include <fmac/fmac.h> + +int +main(int argc, char *argv[]) +{ + char *path; + int errflg = 0; + int c; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + (void) textdomain(TEXT_DOMAIN); + + while ((c = getopt(argc, argv, "")) != EOF) { + switch (c) { + case '?': + errflg++; + break; + } + } + + if (errflg || argc != 2) { + (void) fprintf(stderr, gettext("usage: loadpolicy file\n")); + return (1); + } + + path = *++argv; + + if (security_load_policy(path)) { + (void) fprintf(stderr, + gettext("loadpolicy: policy load of %s failed: %s\n"), + path, strerror(errno)); + return (1); + } + + return (0); +}
--- a/usr/src/cmd/truss/systable.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/cmd/truss/systable.c Fri Jun 20 08:29:57 2008 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -349,7 +349,7 @@ {"lxstat", 3, DEC, NOV, DEC, STG, HEX}, /* 124 */ {"fxstat", 3, DEC, NOV, DEC, DEC, HEX}, /* 125 */ {"xmknod", 4, DEC, NOV, DEC, STG, OCT, HEX}, /* 126 */ -{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX}, +{"fmacsys", 6, UNS, UNS, DEC, HEX, HEX, HEX, HEX, HEX}, /* 127 */ {"setrlimit", 2, DEC, NOV, RLM, HEX}, /* 128 */ {"getrlimit", 2, DEC, NOV, RLM, HEX}, /* 129 */ {"lchown", 3, DEC, NOV, STG, DEC, DEC}, /* 130 */ @@ -839,6 +839,16 @@ }; #define NSIDSYSCODE (sizeof (sidsystable) / sizeof (struct systable)) +const struct systable fmacsystable[] = { +{"security_get_enforce", 1, DEC, NOV, HID}, /* 0 */ +{"security_set_enforce", 2, DEC, NOV, HID, DEC}, /* 1 */ +{"security_load_policy", 2, UNS, UNS, HID, STG}, /* 2 */ +{"is_fmac_enabled", 1, DEC, NOV, HID}, /* 3 */ +{"security_compute_av", 6, DEC, NOV, HID, STG, STG, DEC, DEC, HEX}, /* 4 */ +{"security_check_context", 2, DEC, NOV, HID, STG}, /* 5 */ +}; +#define NFMACSYSCODE (sizeof (fmacsystable) / sizeof (struct systable)) + const struct sysalias sysalias[] = { { "exit", SYS_exit }, { "fork", SYS_forksys }, @@ -996,6 +1006,12 @@ { "rctlsys_lst", SYS_rctlsys }, { "rctlsys_ctl", SYS_rctlsys }, { "allocids", SYS_sidsys }, + { "security_getenforce", SYS_fmacsys }, + { "security_setenforce", SYS_fmacsys }, + { "security_load_policy", SYS_fmacsys }, + { "is_fmac_enabled ", SYS_fmacsys }, + { "security_compute_av", SYS_fmacsys }, + { "security_check_context", SYS_fmacsys }, { NULL, 0 } /* end-of-list */ }; @@ -1145,6 +1161,10 @@ if ((unsigned)subcode < NSIDSYSCODE) stp = &sidsystable[subcode]; break; + case SYS_fmacsys: /* FMAC family */ + if ((unsigned)subcode < NFMACSYSCODE) + stp = &fmacsystable[subcode]; + break; } } @@ -1305,6 +1325,7 @@ case SYS_labelsys: /* labelsys */ case SYS_rctlsys: /* rctlsys */ case SYS_sidsys: /* sidsys */ + case SYS_fmacsys: /* fmacsys */ subcode = arg0; break; case SYS_fcntl: /* fcntl() */ @@ -1446,6 +1467,8 @@ return (NFORKCODE); case SYS_sidsys: return (NSIDSYSCODE); + case SYS_fmacsys: + return (NFMACSYSCODE); default: return (1); }
--- a/usr/src/common/fmac/ss/services.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/common/fmac/ss/services.c Fri Jun 20 08:29:57 2008 -0700 @@ -611,7 +611,7 @@ context_struct_t *tcontext, security_class_t tclass, context_struct_t *newcontext) { - if (flask_enforcing) { + if (fmac_enforcing) { return (EACCES); } else { security_context_t s, t, n; @@ -912,7 +912,7 @@ static inline int convert_context_handle_invalid_context(context_struct_t *context) { - if (flask_enforcing) { + if (fmac_enforcing) { return (EINVAL); } else { security_context_t s;
--- a/usr/src/head/Makefile Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/head/Makefile Fri Jun 20 08:29:57 2008 -0700 @@ -279,6 +279,8 @@ LVMRPCHDRS = \ mhdx.h mdiox.h meta_basic.h metad.h metamed.h metamhd.h metacl.h +FMACHDRS = fmac.h + SYMHDRASSERT = $(ROOT)/usr/include/iso/assert_iso.h SYMHDRERRNO = $(ROOT)/usr/include/iso/errno_iso.h SYMHDRFLOAT = $(ROOT)/usr/include/iso/float_iso.h @@ -324,9 +326,10 @@ $(RPCSVCHDRS:%=$(ROOT)/usr/include/rpcsvc/%) \ $(RPCSVCPROTS:%=$(ROOT)/usr/include/rpcsvc/%) \ $(LVMRPCHDRS:%=$(ROOT)/usr/include/%) \ - $(PROTOHDRS:%=$(ROOT)/usr/include/protocols/%) + $(PROTOHDRS:%=$(ROOT)/usr/include/protocols/%) \ + $(FMACHDRS:%=$(ROOT)/usr/include/fmac/%) -DIRS= iso arpa audio rpcsvc protocols security uuid kerberosv5 +DIRS= iso arpa audio rpcsvc protocols security uuid kerberosv5 fmac ROOTDIRS= $(DIRS:%=$(ROOT)/usr/include/%) SED= sed @@ -359,6 +362,9 @@ uuid/%.check: uuid/%.h $(DOT_H_CHECK) +fmac/%.check: fmac/%.h + $(DOT_H_CHECK) + # Note that the derived headers (rpcgen) are not checked at this time. These # need work at the source level and rpcgen itself has a bug which causes a # cstyle violation. Furthermore, there seems to be good reasons for the @@ -374,7 +380,9 @@ $(AUDIOHDRS:%.h=audio/%.check) \ $(UUIDHDRS:%.h=uuid/%.check) \ $(RPCSVC_SRC_HDRS:%.h=rpcsvc/%.check) \ - $(PROTOHDRS:%.h=protocols/%.check) + $(PROTOHDRS:%.h=protocols/%.check) \ + $(FMACHDRS:%.h=fmac/%.check) + # headers which won't quite meet the standards... # @@ -410,6 +418,9 @@ $(ROOT)/usr/include/uuid/%: uuid/% $(INS.file) +$(ROOT)/usr/include/fmac/%: fmac/% + $(INS.file) + $(ROOT)/usr/include/%: % $(INS.file)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/head/fmac/fmac.h Fri Jun 20 08:29:57 2008 -0700 @@ -0,0 +1,56 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FMAC_H +#define _FMAC_H + +/* + * Flexible Mandatory Access Control (FMAC) + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/fmac/fmac.h> +#include <sys/fmac/flask_types.h> + +int security_load_policy(char *path); + +int security_compute_av(security_context_t scontext, + security_context_t tcontext, security_class_t tclass, + access_vector_t request, struct av_decision *avd); + +int security_check_context(security_context_t scontext); +int security_getenforce(void); +int security_setenforce(int mode); +int is_fmac_enabled(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _FMAC_H */
--- a/usr/src/lib/libc/amd64/Makefile Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libc/amd64/Makefile Fri Jun 20 08:29:57 2008 -0700 @@ -792,6 +792,7 @@ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \
--- a/usr/src/lib/libc/i386/Makefile.com Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libc/i386/Makefile.com Fri Jun 20 08:29:57 2008 -0700 @@ -832,6 +832,7 @@ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \
--- a/usr/src/lib/libc/inc/synonyms.h Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libc/inc/synonyms.h Fri Jun 20 08:29:57 2008 -0700 @@ -492,6 +492,7 @@ #define isastream _isastream #define isatty _isatty #define isenglish _isenglish +#define is_fmac_enabled _is_fmac_enabled #define isideogram _isideogram #define isnumber _isnumber #define isphonogram _isphonogram @@ -880,6 +881,11 @@ #define schedctl_lookup _schedctl_lookup #define scrwidth _scrwidth #define seconvert _seconvert +#define security_check_context _security_check_context +#define security_compute_av _security_compute_av +#define security_getenforce _security_getenforce +#define security_load_policy _security_load_policy +#define security_setenforce _security_setenforce #define seed48 _seed48 #define seekdir _seekdir #define select _select
--- a/usr/src/lib/libc/port/mapfile-vers Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libc/port/mapfile-vers Fri Jun 20 08:29:57 2008 -0700 @@ -74,6 +74,7 @@ _getpagesizes2; htonl; htons; + is_fmac_enabled; lio_listio; mkdtemp; _mkdtemp; @@ -106,6 +107,11 @@ sched_setparam; sched_setscheduler; sched_yield; + security_check_context; + security_compute_av; + security_getenforce; + security_load_policy; + security_setenforce; sem_close; sem_destroy; sem_getvalue;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/lib/libc/port/sys/fmacsys.c Fri Jun 20 08:29:57 2008 -0700 @@ -0,0 +1,75 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak security_load_policy = _security_load_policy +#pragma weak security_compute_av = _security_compute_av +#pragma weak security_check_context = _security_check_context +#pragma weak security_getenforce = _security_getenforce +#pragma weak security_setenforce = _security_setenforce +#pragma weak is_fmac_enabled = _is_fmac_enabled + +#include "synonyms.h" +#include <fmac/fmac.h> +#include <sys/fmac/flask_types.h> +#include <sys/syscall.h> + +int +security_load_policy(char *path) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYLOADPOLICY, path)); +} + +int +security_compute_av(security_context_t scontext, security_context_t tcontext, + security_class_t tclass, access_vector_t request, struct av_decision *avd) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYCOMPUTEAV, scontext, + tcontext, tclass, request, avd)); +} + +int +security_check_context(security_context_t scontext) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYCHECKCONTEXT, scontext)); +} + +int +security_getenforce() +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYGETENFORCE)); +} + +int +security_setenforce(int mode) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYSETENFORCE, mode)); +} + +int +is_fmac_enabled() +{ + return (syscall(SYS_fmacsys, FMACSYS_ISFMACENABLED)); +}
--- a/usr/src/lib/libc/sparc/Makefile Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libc/sparc/Makefile Fri Jun 20 08:29:57 2008 -0700 @@ -857,6 +857,7 @@ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \
--- a/usr/src/lib/libc/sparcv9/Makefile Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libc/sparcv9/Makefile Fri Jun 20 08:29:57 2008 -0700 @@ -801,6 +801,7 @@ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \
--- a/usr/src/lib/libproc/common/proc_names.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/lib/libproc/common/proc_names.c Fri Jun 20 08:29:57 2008 -0700 @@ -245,7 +245,7 @@ "lxstat", /* 124 */ "fxstat", /* 125 */ "xmknod", /* 126 */ - "NULL", /* 127 */ + "fmacsys", /* 127 */ "setrlimit", /* 128 */ "getrlimit", /* 129 */ "lchown", /* 130 */
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/pkgdefs/SUNWcsr/prototype_com Fri Jun 20 08:29:57 2008 -0700 @@ -406,6 +406,7 @@ f none sbin/ifconfig 555 root bin f none sbin/ifparse 555 root bin s none sbin/in.mpathd=../usr/lib/inet/in.mpathd +f none sbin/loadpolicy 555 root bin f none sbin/soconfig 555 root bin f none sbin/init 555 root sys s none sbin/jsh=sh
--- a/usr/src/pkgdefs/SUNWhea/prototype_com Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/pkgdefs/SUNWhea/prototype_com Fri Jun 20 08:29:57 2008 -0700 @@ -218,6 +218,8 @@ f none usr/include/fatal.h 644 root bin f none usr/include/fcntl.h 644 root bin f none usr/include/float.h 644 root bin +d none usr/include/fmac 755 root bin +f none usr/include/fmac/fmac.h 644 root bin f none usr/include/fmtmsg.h 644 root bin f none usr/include/fnmatch.h 644 root bin f none usr/include/form.h 644 root bin
--- a/usr/src/uts/common/Makefile.files Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/Makefile.files Fri Jun 20 08:29:57 2008 -0700 @@ -164,6 +164,7 @@ flock.o \ fm.o \ fmac.o \ + fmacsys.o \ $(FMAC_MLS_OBJS) \ fork.o \ vpm.o \
--- a/usr/src/uts/common/fmac/avc.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/fmac/avc.c Fri Jun 20 08:29:57 2008 -0700 @@ -922,7 +922,7 @@ if (!requested || (denied & ae->avd.auditdeny)) avc_audit(ssid, tsid, tclass, denied, ae, AVC_AUDITDENY, auditdata); - if (flask_enforcing) { + if (fmac_enforcing) { mutex_exit(&avc_lock); return (EACCES); } else {
--- a/usr/src/uts/common/fmac/fmac.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/fmac/fmac.c Fri Jun 20 08:29:57 2008 -0700 @@ -32,21 +32,69 @@ #include <sys/cmn_err.h> #include <sys/ddi.h> #include <sys/sunddi.h> +#include <sys/param.h> #include <sys/kobj.h> #include <sys/fmac/security.h> #include <sys/fmac/fmac.h> +/* Tunables */ +int fmac_enabled = 1; /* policy enabled */ +int fmac_enforcing = 0; /* permissive or enforcing */ + char *fmac_default_policy_file = FMAC_POLICY_FILE; +/* + * Parse boot arguments. Boot arguments take priority over + * defaults and /etc/system specifications. + */ +static void +fmac_parse_bootargs(const char *cp) +{ + const char *ncp; -#ifdef DEBUG -int flask_enforcing = 1; -#endif /* DEBUG */ + while (*cp != '\0') { + + /* Skip white spaces */ + while (*cp == ' ') + cp++; + + if (strncmp(cp, "enabled", sizeof ("enabled") -1) == 0) { + fmac_enabled = 1; + cp += sizeof ("enabled") - 1; + } else if (strncmp(cp, "disabled", + sizeof ("disabled")-1) == 0) { + fmac_enabled = 0; + cp += sizeof ("disabled") - 1; + } else if (strncmp(cp, "enforcing", + sizeof ("enforcing")-1) == 0) { + fmac_enabled = 1; + fmac_enforcing = 1; + cp += sizeof ("enforcing") - 1; + } else if (strncmp(cp, "permissive", + sizeof ("permissive")-1) == 0) { + fmac_enabled = 1; + fmac_enforcing = 0; + cp += sizeof ("permissive") - 1; + } + + /* Check for additional arguments */ + if (*cp != '\0' && (ncp = strchr(cp, ',')) != '\0') { + cp = ncp + 1; + } else + break; + } +} void fmac_init() { - (void) fmac_load_policy(fmac_default_policy_file); + fmac_parse_bootargs(policyargs); + + if (fmac_enabled) + if (fmac_load_policy(fmac_default_policy_file)) + if (fmac_enforcing) + cmn_err(CE_PANIC, + "security: Policy load failed"); } int @@ -63,7 +111,7 @@ return (ENOENT); } - if ((ret = security_load_policy(policy_handle, 0)) < 0) { + if ((ret = security_load_policy(policy_handle, 0))) { cmn_err(CE_WARN, "security: Policy load failed %s\n", file); kobj_close_file(policy_handle); return (ret); @@ -72,6 +120,8 @@ kobj_close_file(policy_handle); cmn_err(CE_CONT, "security: Policy loaded from %s\n", file); + cmn_err(CE_CONT, "security: mode is %s\n", + fmac_enforcing == 0 ? "permissive" : "enforcing"); return (0); }
--- a/usr/src/uts/common/krtld/kobj_bootflags.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/krtld/kobj_bootflags.c Fri Jun 20 08:29:57 2008 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -78,9 +78,9 @@ #if defined(_OBP) /* skip bootblk args */ - params.gos_opts = "abcdDF:gGHhi:km:o:O:rsvVwx"; + params.gos_opts = "abcdDF:gGHhi:km:o:O:p:rsvVwx"; #else - params.gos_opts = "abcdgGhi:km:O:rsvwx"; + params.gos_opts = "abcdgGhi:km:O:p:rsvwx"; #endif params.gos_strp = cp; getoptstr_init(¶ms); @@ -169,6 +169,23 @@ (*str)[params.gos_optarglen] = '\0'; break; } + case 'p': { + if (strlen(policyargs) + params.gos_optarglen + 1 > + sizeof (policyargs)) { + _kobj_printf(ops, + "unix: init options too long. " + "Ignoring -p.\n"); + break; + } + /* gos_optargp is not null terminated */ + (void) strncpy(scratch, params.gos_optargp, + params.gos_optarglen); + scratch[params.gos_optarglen] = '\0'; + (void) strlcat(policyargs, scratch, + sizeof (policyargs)); + (void) strlcat(policyargs, " ", sizeof (policyargs)); + break; + } case 'r': if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { _kobj_printf(ops, "unix: init options too "
--- a/usr/src/uts/common/os/main.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/os/main.c Fri Jun 20 08:29:57 2008 -0700 @@ -96,6 +96,8 @@ kmem_cache_t *process_cache; /* kmem cache for proc structures */ +char policyargs[BOOTARGS_MAX] = ""; + /* * Process 0's lwp directory and lwpid hash table. */
--- a/usr/src/uts/common/os/sysent.c Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/os/sysent.c Fri Jun 20 08:29:57 2008 -0700 @@ -64,6 +64,7 @@ int exec(); int exece(); int fcntl(); +int fmacsys(); int64_t forkall(); int64_t vfork(); int64_t forksys(); @@ -601,7 +602,7 @@ IF_i386( SYSENT_CI("xmknod", xmknod, 4), SYSENT_NOSYS())), - /* 127 */ SYSENT_LOADABLE(), /* was clocal */ + /* 127 */ SYSENT_CI("fmacsys", fmacsys, 6), /* 128 */ IF_LP64( SYSENT_CI("setrlimit", setrlimit64, 2), SYSENT_CI("setrlimit", setrlimit32, 2)), @@ -988,7 +989,7 @@ /* 126 */ IF_386_ABI( SYSENT_CI("xmknod", xmknod, 4), SYSENT_NOSYS()), - /* 127 */ SYSENT_LOADABLE32(), /* was clocal */ + /* 127 */ SYSENT_CI("fmacsys", fmacsys, 6), /* 128 */ SYSENT_CI("setrlimit", setrlimit32, 2), /* 129 */ SYSENT_CI("getrlimit", getrlimit32, 2), /* 130 */ SYSENT_CI("lchown", lchown, 3),
--- a/usr/src/uts/common/sys/fmac/fmac.h Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/sys/fmac/fmac.h Fri Jun 20 08:29:57 2008 -0700 @@ -31,28 +31,61 @@ extern "C" { #endif -#ifdef __cplusplus -} -#endif +#if defined(_KERNEL) +#include <sys/inttypes.h> +#else +#include <inttypes.h> +#endif /* _KERNEL */ + +#include <sys/fmac/flask_types.h> #define FMAC_MAX_CONTEXT_LEN 4096 #define FMAC_POLICY_FILE "/etc/security/fmac/ss_policy" #define FMAC_CONTEXT_ATTR "SUNW.fmac.security" +/* + * FMAC system calls subcodes + */ +#define FMACSYS_SECURITYGETENFORCE 0 +#define FMACSYS_SECURITYSETENFORCE 1 +#define FMACSYS_SECURITYLOADPOLICY 2 +#define FMACSYS_ISFMACENABLED 3 +#define FMACSYS_SECURITYCOMPUTEAV 4 +#define FMACSYS_SECURITYCHECKCONTEXT 5 +#define FMACSYS_GETCON 6 +#define FMACSYS_GETPIDCON 7 +#define FMACSYS_GETEXECCON 8 +#define FMACSYS_SETEXECCON 9 +#define FMACSYS_GETFILECON 10 +#define FMACSYS_SETFILECON 11 +#define FMACSYS_LGETFILECON 12 +#define FMACSYS_LSETFILECON 13 +#define FMACSYS_FGETFILECON 14 +#define FMACSYS_FSETFILECON 15 + #if defined(_KERNEL) -#if defined(DEBUG) -extern int flask_enforcing; +extern int fmac_enabled; +extern int fmac_enforcing; #else -#define flask_enforcing 1 -#endif /* DEBUG */ -#else -#define flask_enforcing 1 +#define fmac_enforcing 1 #endif /* _KERNEL */ +struct av_decision { + access_vector_t allowed; + access_vector_t decided; + access_vector_t auditallow; + access_vector_t auditdeny; + uint32_t seqno; +}; + #if defined(_KERNEL) extern char *fmac_default_policy_file; void fmac_init(void); int fmac_load_policy(char *file); +#endif /* _KERNEL */ + +#ifdef __cplusplus +} #endif #endif /* _SYS_FMAC_FMAC_H */
--- a/usr/src/uts/common/sys/fmac/security.h Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/sys/fmac/security.h Fri Jun 20 08:29:57 2008 -0700 @@ -39,6 +39,7 @@ * Security server interface. */ +#include <sys/fmac/fmac.h> #include <sys/fmac/flask_types.h> #include <sys/fmac/flask.h> #include <sys/types.h> @@ -53,13 +54,6 @@ * Compute access vectors based on a SID pair for * the permissions in a particular class. */ -struct av_decision { - access_vector_t allowed; - access_vector_t decided; - access_vector_t auditallow; - access_vector_t auditdeny; - uint32_t seqno; -}; int security_compute_av( security_id_t ssid, /* IN */ security_id_t tsid, /* IN */
--- a/usr/src/uts/common/sys/syscall.h Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/sys/syscall.h Fri Jun 20 08:29:57 2008 -0700 @@ -319,6 +319,7 @@ #define SYS_lxstat 124 #define SYS_fxstat 125 #define SYS_xmknod 126 +#define SYS_fmacsys 127 #define SYS_setrlimit 128 #define SYS_getrlimit 129 #define SYS_lchown 130
--- a/usr/src/uts/common/sys/systm.h Mon Jun 09 11:18:52 2008 -0700 +++ b/usr/src/uts/common/sys/systm.h Fri Jun 20 08:29:57 2008 -0700 @@ -23,7 +23,7 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -394,6 +394,11 @@ extern int exec_init(const char *, const char *); extern int start_init_common(void); +/* + * policyargs contains security policy related boot arguments. + */ +extern char policyargs[BOOTARGS_MAX]; + #endif /* _KERNEL */ #if defined(_KERNEL) || defined(_BOOT)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/syscall/fmacsys.c Fri Jun 20 08:29:57 2008 -0700 @@ -0,0 +1,332 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/types.h> +#include <sys/kmem.h> +#include <sys/systm.h> +#include <sys/param.h> +#include <sys/vnode.h> +#include <sys/pathname.h> +#include <sys/zone.h> +#include <sys/note.h> +#include <sys/policy.h> +#include <sys/priv.h> +#include <sys/fmac/fmac.h> +#include <sys/fmac/flask.h> +#include <sys/fmac/flask_types.h> +#include <sys/fmac/security.h> + +static int +fmacsys_getenforce() +{ + if (fmac_enforcing) + return (1); + else + return (0); +} + +static int +fmacsys_setenforce(int mode) +{ + int err = 0; + + if (!INGLOBALZONE(curproc)) { + err = EINVAL; + goto done; + } + + /* Until avc_has_perm() can be used, we'll use privilege for access */ + if (err = PRIV_POLICY(CRED(), PRIV_ALL, B_FALSE, EPERM, NULL)) + goto done; + + switch (mode) { + + case 0: + case 1: + fmac_enforcing = mode; + break; + default: + err = EINVAL; + break; + } + +done: + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_security_load_policy(char *path) +{ + char *kpath = 0; + int err; + + if (!INGLOBALZONE(curproc)) { + err = EINVAL; + goto done; + } + + if (!fmac_enabled) { + err = ENOSYS; + goto done; + } + + /* + * fmac_load_policy() calls kobj_open_file() which opens the file + * with kcred, so a privilege check is done here first. + */ + if (err = PRIV_POLICY(CRED(), PRIV_ALL, B_FALSE, EPERM, NULL)) + goto done; + + kpath = kmem_alloc(MAXPATHLEN, KM_SLEEP); + + if ((err = copyinstr(path, kpath, MAXPATHLEN, NULL)) != 0) + goto done; + + + err = fmac_load_policy(kpath); +done: + if (kpath) + kmem_free(kpath, MAXPATHLEN); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_is_fmac_enabled() +{ + if (fmac_enabled) + return (1); + else + return (0); +} + + +static int +fmacsys_security_compute_av( + security_context_t scontext, + security_context_t tcontext, + security_class_t tclass, + access_vector_t request, + struct av_decision *avd) +{ + security_context_t kscontext; + security_context_t ktcontext; + security_id_t ssid; + security_id_t tsid; + struct av_decision kavd; + size_t slen; + size_t tlen; + int err; + + kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + ktcontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + + if ((err = copyinstr(scontext, kscontext, FMAC_MAX_CONTEXT_LEN, + &slen)) != 0) + goto done; + + if ((err = copyinstr(tcontext, ktcontext, FMAC_MAX_CONTEXT_LEN, + &tlen)) != 0) + goto done; + + if ((err = security_context_to_sid(kscontext, slen, &ssid))) + goto done; + + if ((err = security_context_to_sid(ktcontext, tlen, &tsid))) + goto done; + + if ((err = security_compute_av(ssid, tsid, tclass, request, &kavd))) + goto done; + + if (copyout(&kavd, avd, sizeof (struct av_decision))) { + err = EFAULT; + goto done; + } + +done: + kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); + kmem_free(ktcontext, FMAC_MAX_CONTEXT_LEN); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_security_check_context(security_context_t scontext) +{ + security_context_t kscontext; + security_id_t ssid; + size_t slen; + int err; + + kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + + if ((err = copyinstr(scontext, kscontext, FMAC_MAX_CONTEXT_LEN, + &slen)) != 0) + goto done; + + if ((err = security_context_to_sid(kscontext, slen, &ssid))) + goto done; + +done: + kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_getcon(pid_t pid, security_context_t scontext) +{ + _NOTE(ARGUNUSED(pid, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_getexeccon(security_context_t scontext) +{ + _NOTE(ARGUNUSED(scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_setexeccon(security_context_t scontext) +{ + _NOTE(ARGUNUSED(scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_getfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_setfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_lgetfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_lsetfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_fgetfilecon(int fd, security_context_t scontext) +{ + _NOTE(ARGUNUSED(fd, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_fsetfilecon(int fd, security_context_t scontext) +{ + _NOTE(ARGUNUSED(fd, scontext)); + + return (set_errno(ENOSYS)); +} + +int +fmacsys(int op, void *a1, void *a2, void *a3, void *a4, void *a5) +{ + switch (op) { + case FMACSYS_SECURITYGETENFORCE: + return (fmacsys_getenforce()); + case FMACSYS_SECURITYSETENFORCE: + return (fmacsys_setenforce((int)(uintptr_t)a1)); + case FMACSYS_SECURITYLOADPOLICY: + return (fmacsys_security_load_policy((char *)a1)); + case FMACSYS_ISFMACENABLED: + return (fmacsys_is_fmac_enabled()); + case FMACSYS_SECURITYCOMPUTEAV: + return (fmacsys_security_compute_av((security_context_t)a1, + (security_context_t)a2, + (security_class_t)(uintptr_t)a3, + (access_vector_t)(unsigned long)a4, + (struct av_decision *)a5)); + case FMACSYS_SECURITYCHECKCONTEXT: + return (fmacsys_security_check_context((security_context_t)a1)); + case FMACSYS_GETCON: + return (fmacsys_getcon(curproc->p_pid, (security_context_t)a1)); + case FMACSYS_GETPIDCON: + return (fmacsys_getcon((pid_t)(uintptr_t)a1, + (security_context_t)a2)); + case FMACSYS_GETEXECCON: + return (fmacsys_getexeccon((security_context_t)a1)); + case FMACSYS_SETEXECCON: + return (fmacsys_setexeccon((security_context_t)a1)); + case FMACSYS_GETFILECON: + return (fmacsys_getfilecon((char *)a1, (security_context_t)a2)); + case FMACSYS_SETFILECON: + return (fmacsys_setfilecon((char *)a1, (security_context_t)a2)); + case FMACSYS_LGETFILECON: + return (fmacsys_lgetfilecon((char *)a1, + (security_context_t)a2)); + case FMACSYS_LSETFILECON: + return (fmacsys_lsetfilecon((char *)a1, + (security_context_t)a2)); + case FMACSYS_FGETFILECON: + return (fmacsys_fgetfilecon((int)(uintptr_t)a1, + (security_context_t)a2)); + case FMACSYS_FSETFILECON: + return (fmacsys_fsetfilecon((int)(uintptr_t)a1, + (security_context_t)a2)); + default: + return (ENOSYS); + } + /* NOTREACHED */ +}