From sds at tycho.nsa.gov Tue Jul 1 05:00:48 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 01 Jul 2008 08:00:48 -0400 Subject: [fmac-discuss] [PATCH] Take fmac_enabled checks to fmacsys() entrypoint Message-ID: <1214913648.22447.158.camel@moss-spartans.epoch.ncsc.mil> This patch takes the fmac_enabled checks to the fmacsys() entrypoint so that we don't need to test for it in each FMAC syscall. Note that we handle is_fmac_enabled first as that call is supported even when FMAC is disabled. Also cast avc_ss_reset return to void to fix a lint warning. diff --git a/usr/src/uts/common/syscall/fmacsys.c b/usr/src/uts/common/syscall/fmacsys.c --- a/usr/src/uts/common/syscall/fmacsys.c +++ b/usr/src/uts/common/syscall/fmacsys.c @@ -44,9 +44,7 @@ static int static int fmacsys_getenforce() { - if (!fmac_enabled) - return (set_errno(ENOSYS)); - else if (fmac_enforcing) + if (fmac_enforcing) return (1); else return (0); @@ -56,11 +54,6 @@ fmacsys_setenforce(int mode) fmacsys_setenforce(int mode) { int err = 0; - - if (!fmac_enabled) { - err = ENOSYS; - goto done; - } if (!INGLOBALZONE(curproc)) { err = EINVAL; @@ -77,7 +70,7 @@ fmacsys_setenforce(int mode) case 1: fmac_enforcing = mode; if (fmac_enforcing) - avc_ss_reset(0); + (void) avc_ss_reset(0); break; default: err = EINVAL; @@ -102,11 +95,6 @@ fmacsys_security_load_policy(char *path) 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. @@ -157,9 +145,6 @@ fmacsys_security_compute_av( size_t slen; size_t tlen; int err; - - if (!fmac_enabled) - return (set_errno(ENOSYS)); kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); ktcontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); @@ -203,9 +188,6 @@ fmacsys_security_check_context(security_ security_id_t ssid; size_t slen; int err; - - if (!fmac_enabled) - return (set_errno(ENOSYS)); kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); @@ -300,6 +282,12 @@ int int fmacsys(int op, void *a1, void *a2, void *a3, void *a4, void *a5) { + if (op == FMACSYS_ISFMACENABLED) + return (fmacsys_is_fmac_enabled()); + + if (!fmac_enabled) + return (set_errno(ENOSYS)); + switch (op) { case FMACSYS_SECURITYGETENFORCE: return (fmacsys_getenforce()); @@ -307,8 +295,6 @@ fmacsys(int op, void *a1, void *a2, void 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, -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Tue Jul 1 07:10:26 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 01 Jul 2008 10:10:26 -0400 Subject: [fmac-discuss] [PATCH] Rework avc_audit Message-ID: <1214921426.22447.204.camel@moss-spartans.epoch.ncsc.mil> This patch reworks the avc_audit code so that each avc message is output as a single log message, which is necessary due to the behavior of Solaris kernel printf. avc_audit_buffer is presently protected under the avc_lock but the locking scheme will change later in order to be more scalable. This is a temporary fix until we have a chance to explore using Solaris audit for avc messages. With this patch, a call to avc_has_perm for a permission check produces output such as: avc: denied { load_policy } for scontext=system_u:system_r:init_t:unclassified tcontext=system_u:object_r:security_t:unclassified tclass=security which is consistent with SELinux and can be processed by tools such as audit2allow. scontext= is the source (typically subject/process) context; tcontext= is the target (typically object) context; tclass= is the target object class. Other supplemental audit data will be added later. The patch also adds fmac_enabled tests to avc_init and avc_has_perm so that the AVC allocation and permission checking is skipped if FMAC is disabled. diff --git a/usr/src/uts/common/fmac/avc.c b/usr/src/uts/common/fmac/avc.c --- a/usr/src/uts/common/fmac/avc.c +++ b/usr/src/uts/common/fmac/avc.c @@ -116,6 +116,28 @@ avc_dump_stats(char *tag) avc_cache_stats[AVC_CAV_HITS]); } +static void avc_audit_start(void) +{ + memset(avc_audit_buffer, 0, PAGESIZE); +} + +/*PRINTFLIKE1*/ +static void avc_audit_append(const char *fmt, ...) +{ + va_list ap; + size_t len; + + len = strlen(avc_audit_buffer); + va_start(ap, fmt); + (void) vsnprintf(avc_audit_buffer + len, PAGESIZE - len, fmt, ap); + va_end(ap); +} + +static void avc_audit_end(void) +{ + (void) printf("%s\n", avc_audit_buffer); +} + /* * Display an access vector in human-readable form. */ @@ -128,8 +150,8 @@ avc_dump_av(security_class_t tclass, acc int i2; int perm; - if (av == 0) { - printf(" null"); + if (av == 0) { + avc_audit_append(" null"); return; } @@ -141,12 +163,12 @@ avc_dump_av(security_class_t tclass, acc } } - printf(" {"); + avc_audit_append(" {"); i = 0; perm = 1; while (perm < common_base) { if (perm & av) - printf(" %s", common_pts[i]); + avc_audit_append(" %s", common_pts[i]); i++; perm <<= 1; } @@ -159,13 +181,14 @@ avc_dump_av(security_class_t tclass, acc break; } if (i2 < AV_PERM_TO_STRING_SIZE) - printf(" %s", av_perm_to_string[i2].name); + avc_audit_append(" %s", + av_perm_to_string[i2].name); } i++; perm <<= 1; } - printf(" }"); + avc_audit_append(" }"); } /* @@ -183,20 +206,20 @@ avc_dump_query( rc = security_sid_to_context(ssid, &scontext, &scontext_len); if (rc) - printf("ssid=%d", ssid); + avc_audit_append("ssid=%d", ssid); else { - printf("scontext=%s", scontext); + avc_audit_append("scontext=%s", scontext); security_context_free(scontext); } rc = security_sid_to_context(tsid, &scontext, &scontext_len); if (rc) - printf(" tsid=%d", tsid); + avc_audit_append(" tsid=%d", tsid); else { - printf(" tcontext=%s", scontext); + avc_audit_append(" tcontext=%s", scontext); security_context_free(scontext); } - printf(" tclass=%s", class_to_string[tclass]); + avc_audit_append(" tclass=%s", class_to_string[tclass]); } /* @@ -207,6 +230,9 @@ avc_init(void) { avc_node_t *new; int i; + + if (!fmac_enabled) + return; for (i = 0; i < AVC_NSTATS; i++) avc_cache_stats[i] = 0; @@ -230,7 +256,7 @@ avc_init(void) avc_audit_buffer = (char *)kmem_zalloc(PAGESIZE, KM_SLEEP); if (!avc_audit_buffer) - cmn_err(CE_WARN, "AVC: unable to allocate audit buffer\n"); + panic("AVC: unable to allocate audit buffer\n"); cmn_err(CE_CONT, "AVC: Initialized\n"); } @@ -297,12 +323,13 @@ avc_dump_cache(char *tag) slots_used++; chain_len = 0; while (node) { + avc_audit_start(); avc_dump_query(node->ae.ssid, node->ae.tsid, node->ae.tclass); - printf(" allowed"); + avc_audit_append(" allowed"); avc_dump_av(node->ae.tclass, node->ae.avd.allowed); - printf("\n"); + avc_audit_end(); chain_len++; node = node->next; @@ -526,11 +553,12 @@ avc_audit( if (a && a->type == AVC_AUDIT_DATA_DONTAUDIT) return; - printf("\navc: %s ", denied ? "denied" : "granted"); + avc_audit_start(); + avc_audit_append("avc: %s ", denied ? "denied" : "granted"); avc_dump_av(tclass, audited); - printf(" for "); + avc_audit_append(" for "); avc_dump_query(ssid, tsid, tclass); - printf("\n"); + avc_audit_end(); } typedef struct avc_callback_node @@ -881,6 +909,9 @@ avc_has_perm_ref_audit( struct avc_entry entry; access_vector_t denied; + if (!fmac_enabled) + return (0); + mutex_enter(&avc_lock); avc_cache_stats_incr(AVC_ENTRY_LOOKUPS); ae = aeref->ae; -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Tue Jul 1 07:23:44 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 01 Jul 2008 10:23:44 -0400 Subject: [fmac-discuss] [PATCH] getenforce lint and gettext cleanup Message-ID: <1214922224.22447.208.camel@moss-spartans.epoch.ncsc.mil> This patch cleans up some lint warnings and wraps the output strings with gettext calls in the getenforce utility program. diff --git a/usr/src/cmd/fmac/getenforce/getenforce.c b/usr/src/cmd/fmac/getenforce/getenforce.c --- a/usr/src/cmd/fmac/getenforce/getenforce.c +++ b/usr/src/cmd/fmac/getenforce/getenforce.c @@ -66,12 +66,12 @@ main(int argc, char *argv[]) mode = security_getenforce(); if (mode == 1) - printf("enforcing\n"); + (void) printf(gettext("enforcing\n")); else if (mode == 0) - printf("permissive\n"); + (void) printf(gettext("permissive\n")); else if (mode < 0 && errno == ENOSYS) - printf("disabled\n"); + (void) printf(gettext("disabled\n")); else { (void) fprintf(stderr, gettext("getenforce: getting status failed: %s\n"), -- Stephen Smalley National Security Agency From john.weeks at sun.com Tue Jul 1 07:41:03 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 01 Jul 2008 07:41:03 -0700 Subject: [fmac-discuss] [PATCH] Take fmac_enabled checks to fmacsys() entrypoint In-Reply-To: <1214913648.22447.158.camel@moss-spartans.epoch.ncsc.mil> References: <1214913648.22447.158.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486A41FF.9070003@sun.com> Stephen Smalley wrote: > This patch takes the fmac_enabled checks to the fmacsys() entrypoint so > that we don't need to test for it in each FMAC syscall. Note that we > handle is_fmac_enabled first as that call is supported even when FMAC is > disabled. Also cast avc_ss_reset return to void to fix a lint warning. Acked-by: John Weeks > > diff --git a/usr/src/uts/common/syscall/fmacsys.c b/usr/src/uts/common/syscall/fmacsys.c > --- a/usr/src/uts/common/syscall/fmacsys.c > +++ b/usr/src/uts/common/syscall/fmacsys.c > @@ -44,9 +44,7 @@ static int > static int > fmacsys_getenforce() > { > - if (!fmac_enabled) > - return (set_errno(ENOSYS)); > - else if (fmac_enforcing) > + if (fmac_enforcing) > return (1); > else > return (0); > @@ -56,11 +54,6 @@ fmacsys_setenforce(int mode) > fmacsys_setenforce(int mode) > { > int err = 0; > - > - if (!fmac_enabled) { > - err = ENOSYS; > - goto done; > - } > > if (!INGLOBALZONE(curproc)) { > err = EINVAL; > @@ -77,7 +70,7 @@ fmacsys_setenforce(int mode) > case 1: > fmac_enforcing = mode; > if (fmac_enforcing) > - avc_ss_reset(0); > + (void) avc_ss_reset(0); > break; > default: > err = EINVAL; > @@ -102,11 +95,6 @@ fmacsys_security_load_policy(char *path) > 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. > @@ -157,9 +145,6 @@ fmacsys_security_compute_av( > size_t slen; > size_t tlen; > int err; > - > - if (!fmac_enabled) > - return (set_errno(ENOSYS)); > > kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); > ktcontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); > @@ -203,9 +188,6 @@ fmacsys_security_check_context(security_ > security_id_t ssid; > size_t slen; > int err; > - > - if (!fmac_enabled) > - return (set_errno(ENOSYS)); > > kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); > > @@ -300,6 +282,12 @@ int > int > fmacsys(int op, void *a1, void *a2, void *a3, void *a4, void *a5) > { > + if (op == FMACSYS_ISFMACENABLED) > + return (fmacsys_is_fmac_enabled()); > + > + if (!fmac_enabled) > + return (set_errno(ENOSYS)); > + > switch (op) { > case FMACSYS_SECURITYGETENFORCE: > return (fmacsys_getenforce()); > @@ -307,8 +295,6 @@ fmacsys(int op, void *a1, void *a2, void > 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, > From john.weeks at sun.com Tue Jul 1 07:44:11 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 01 Jul 2008 07:44:11 -0700 Subject: [fmac-discuss] [PATCH] Rework avc_audit In-Reply-To: <1214921426.22447.204.camel@moss-spartans.epoch.ncsc.mil> References: <1214921426.22447.204.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486A42BB.8040208@sun.com> Stephen Smalley wrote: > This patch reworks the avc_audit code so that each avc message is output > as a single log message, which is necessary due to the behavior of > Solaris kernel printf. avc_audit_buffer is presently protected under the > avc_lock but the locking scheme will change later in order to be more > scalable. This is a temporary fix until we have a chance to explore > using Solaris audit for avc messages. With this patch, a call to > avc_has_perm for a permission check produces output such as: > avc: denied { load_policy } for scontext=system_u:system_r:init_t:unclassified tcontext=system_u:object_r:security_t:unclassified tclass=security > which is consistent with SELinux and can be processed by tools such as > audit2allow. scontext= is the source (typically subject/process) > context; tcontext= is the target (typically object) context; tclass= is > the target object class. Other supplemental audit data will be added > later. > > The patch also adds fmac_enabled tests to avc_init and avc_has_perm so > that the AVC allocation and permission checking is skipped if FMAC is > disabled. Acked-by: John Weeks > > diff --git a/usr/src/uts/common/fmac/avc.c b/usr/src/uts/common/fmac/avc.c > --- a/usr/src/uts/common/fmac/avc.c > +++ b/usr/src/uts/common/fmac/avc.c > @@ -116,6 +116,28 @@ avc_dump_stats(char *tag) > avc_cache_stats[AVC_CAV_HITS]); > } > > +static void avc_audit_start(void) > +{ > + memset(avc_audit_buffer, 0, PAGESIZE); > +} > + > +/*PRINTFLIKE1*/ > +static void avc_audit_append(const char *fmt, ...) > +{ > + va_list ap; > + size_t len; > + > + len = strlen(avc_audit_buffer); > + va_start(ap, fmt); > + (void) vsnprintf(avc_audit_buffer + len, PAGESIZE - len, fmt, ap); > + va_end(ap); > +} > + > +static void avc_audit_end(void) > +{ > + (void) printf("%s\n", avc_audit_buffer); > +} > + > /* > * Display an access vector in human-readable form. > */ > @@ -128,8 +150,8 @@ avc_dump_av(security_class_t tclass, acc > int i2; > int perm; > > - if (av == 0) { > - printf(" null"); > + if (av == 0) { > + avc_audit_append(" null"); > return; > } > > @@ -141,12 +163,12 @@ avc_dump_av(security_class_t tclass, acc > } > } > > - printf(" {"); > + avc_audit_append(" {"); > i = 0; > perm = 1; > while (perm < common_base) { > if (perm & av) > - printf(" %s", common_pts[i]); > + avc_audit_append(" %s", common_pts[i]); > i++; > perm <<= 1; > } > @@ -159,13 +181,14 @@ avc_dump_av(security_class_t tclass, acc > break; > } > if (i2 < AV_PERM_TO_STRING_SIZE) > - printf(" %s", av_perm_to_string[i2].name); > + avc_audit_append(" %s", > + av_perm_to_string[i2].name); > } > i++; > perm <<= 1; > } > > - printf(" }"); > + avc_audit_append(" }"); > } > > /* > @@ -183,20 +206,20 @@ avc_dump_query( > > rc = security_sid_to_context(ssid, &scontext, &scontext_len); > if (rc) > - printf("ssid=%d", ssid); > + avc_audit_append("ssid=%d", ssid); > else { > - printf("scontext=%s", scontext); > + avc_audit_append("scontext=%s", scontext); > security_context_free(scontext); > } > > rc = security_sid_to_context(tsid, &scontext, &scontext_len); > if (rc) > - printf(" tsid=%d", tsid); > + avc_audit_append(" tsid=%d", tsid); > else { > - printf(" tcontext=%s", scontext); > + avc_audit_append(" tcontext=%s", scontext); > security_context_free(scontext); > } > - printf(" tclass=%s", class_to_string[tclass]); > + avc_audit_append(" tclass=%s", class_to_string[tclass]); > } > > /* > @@ -207,6 +230,9 @@ avc_init(void) > { > avc_node_t *new; > int i; > + > + if (!fmac_enabled) > + return; > > for (i = 0; i < AVC_NSTATS; i++) > avc_cache_stats[i] = 0; > @@ -230,7 +256,7 @@ avc_init(void) > > avc_audit_buffer = (char *)kmem_zalloc(PAGESIZE, KM_SLEEP); > if (!avc_audit_buffer) > - cmn_err(CE_WARN, "AVC: unable to allocate audit buffer\n"); > + panic("AVC: unable to allocate audit buffer\n"); > > cmn_err(CE_CONT, "AVC: Initialized\n"); > } > @@ -297,12 +323,13 @@ avc_dump_cache(char *tag) > slots_used++; > chain_len = 0; > while (node) { > + avc_audit_start(); > avc_dump_query(node->ae.ssid, node->ae.tsid, > node->ae.tclass); > - printf(" allowed"); > + avc_audit_append(" allowed"); > avc_dump_av(node->ae.tclass, > node->ae.avd.allowed); > - printf("\n"); > + avc_audit_end(); > > chain_len++; > node = node->next; > @@ -526,11 +553,12 @@ avc_audit( > if (a && a->type == AVC_AUDIT_DATA_DONTAUDIT) > return; > > - printf("\navc: %s ", denied ? "denied" : "granted"); > + avc_audit_start(); > + avc_audit_append("avc: %s ", denied ? "denied" : "granted"); > avc_dump_av(tclass, audited); > - printf(" for "); > + avc_audit_append(" for "); > avc_dump_query(ssid, tsid, tclass); > - printf("\n"); > + avc_audit_end(); > } > > typedef struct avc_callback_node > @@ -881,6 +909,9 @@ avc_has_perm_ref_audit( > struct avc_entry entry; > access_vector_t denied; > > + if (!fmac_enabled) > + return (0); > + > mutex_enter(&avc_lock); > avc_cache_stats_incr(AVC_ENTRY_LOOKUPS); > ae = aeref->ae; > > From john.weeks at sun.com Tue Jul 1 07:45:04 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 01 Jul 2008 07:45:04 -0700 Subject: [fmac-discuss] [PATCH] getenforce lint and gettext cleanup In-Reply-To: <1214922224.22447.208.camel@moss-spartans.epoch.ncsc.mil> References: <1214922224.22447.208.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486A42F0.8020508@sun.com> Stephen Smalley wrote: > This patch cleans up some lint warnings and wraps the output strings > with gettext calls in the getenforce utility program. Acked-by: John Weeks > > diff --git a/usr/src/cmd/fmac/getenforce/getenforce.c b/usr/src/cmd/fmac/getenforce/getenforce.c > --- a/usr/src/cmd/fmac/getenforce/getenforce.c > +++ b/usr/src/cmd/fmac/getenforce/getenforce.c > @@ -66,12 +66,12 @@ main(int argc, char *argv[]) > > mode = security_getenforce(); > if (mode == 1) > - printf("enforcing\n"); > + (void) printf(gettext("enforcing\n")); > else if (mode == 0) > - printf("permissive\n"); > + (void) printf(gettext("permissive\n")); > else if (mode < 0 && errno == ENOSYS) > - printf("disabled\n"); > + (void) printf(gettext("disabled\n")); > else { > (void) fprintf(stderr, > gettext("getenforce: getting status failed: %s\n"), > From sds at tycho.nsa.gov Tue Jul 1 08:06:54 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 01 Jul 2008 11:06:54 -0400 Subject: [fmac-discuss] [PATCH] Synchronize security class with FMAC syscalls Message-ID: <1214924814.22447.217.camel@moss-spartans.epoch.ncsc.mil> Synchronize the security class permission definitions with the FMAC syscalls, and update the example policy configuration accordingly. diff --git a/usr/src/cmd/fmac/policy/domains/admin/sysadm.te b/usr/src/cmd/fmac/policy/domains/admin/sysadm.te --- a/usr/src/cmd/fmac/policy/domains/admin/sysadm.te +++ b/usr/src/cmd/fmac/policy/domains/admin/sysadm.te @@ -118,7 +118,7 @@ allow rmmod_t $1_gph_t:fd inherit_fd_per allow rmmod_t $1_gph_t:fd inherit_fd_perms; # Reload the policy configuration. -allow $1_t policy_config_t:security load_policy; +allow $1_t security_t:security load_policy; # Execute setfiles. can_exec($1_t, policy_src_t) diff --git a/usr/src/cmd/fmac/policy/domains/every.te b/usr/src/cmd/fmac/policy/domains/every.te --- a/usr/src/cmd/fmac/policy/domains/every.te +++ b/usr/src/cmd/fmac/policy/domains/every.te @@ -41,13 +41,6 @@ allow domain self:{ tcp_socket unix_stre # Use the system shared libraries. uses_shlib(domain) - -# Obtain the context of any SID. -allow domain *:security sid_to_context; - -# Obtains SIDs for contexts and obtain the -# list of active SIDs. -allow domain security_t:security { context_to_sid get_sids }; # Read/search default file type. allow domain file_t:dir r_dir_perms; diff --git a/usr/src/cmd/fmac/policy/domains/program/newrole.te b/usr/src/cmd/fmac/policy/domains/program/newrole.te --- a/usr/src/cmd/fmac/policy/domains/program/newrole.te +++ b/usr/src/cmd/fmac/policy/domains/program/newrole.te @@ -66,8 +66,6 @@ allow user_t sysadm_t:process { sigchld # # Allow newrole to relabel TTY's # -allow newrole_t security_t:security { change_sid }; - allow newrole_t user_tty_device_t:chr_file { relabelfrom relabelto }; allow newrole_t sysadm_tty_device_t:chr_file { relabelfrom relabelto }; diff --git a/usr/src/cmd/fmac/policy/domains/system/login.te b/usr/src/cmd/fmac/policy/domains/system/login.te --- a/usr/src/cmd/fmac/policy/domains/system/login.te +++ b/usr/src/cmd/fmac/policy/domains/system/login.te @@ -83,9 +83,6 @@ allow local_login_t mail_spool_t:dir r_d allow local_login_t mail_spool_t:dir r_dir_perms; allow local_login_t mail_spool_t:file getattr; -# Obtain the SID to use for relabeling terminals. -allow local_login_t security_t:security change_sid; - # Read and write ttys. allow local_login_t tty_device_t:chr_file rw_file_perms; @@ -134,8 +131,5 @@ allow remote_login_t mail_spool_t:dir r_ allow remote_login_t mail_spool_t:dir r_dir_perms; allow remote_login_t mail_spool_t:file getattr; -# Obtain the SID to use for relabeling ptys. -allow remote_login_t security_t:security change_sid; - # Relabel ptys created by rlogind. allow remote_login_t rlogind_devpts_t:chr_file { relabelfrom relabelto }; diff --git a/usr/src/cmd/fmac/policy/domains/system/sshd.te b/usr/src/cmd/fmac/policy/domains/system/sshd.te --- a/usr/src/cmd/fmac/policy/domains/system/sshd.te +++ b/usr/src/cmd/fmac/policy/domains/system/sshd.te @@ -109,9 +109,6 @@ allow sshd_login_t mail_spool_t:dir r_di allow sshd_login_t mail_spool_t:dir r_dir_perms; allow sshd_login_t mail_spool_t:file getattr; -# Obtain the SID to use for relabeling ptys -allow sshd_login_t security_t:security change_sid; - # Relabel ptys created by sshd allow sshd_login_t sshd_devpts_t:chr_file { relabelfrom relabelto }; allow sshd_login_t user_devpts_t:chr_file { relabelto relabelfrom getattr }; diff --git a/usr/src/cmd/fmac/policy/init.te b/usr/src/cmd/fmac/policy/init.te --- a/usr/src/cmd/fmac/policy/init.te +++ b/usr/src/cmd/fmac/policy/init.te @@ -86,9 +86,6 @@ can_udp_send(sysadm_t, initial_boot_t) # Rules for the initial_boot_t domain. # -# Use security server calls. -allow initial_boot_t security_t:security { compute_av change_sid }; - # Perform any privileged operation. allow initial_boot_t kernel_t:system *; allow initial_boot_t self:capability *; diff --git a/usr/src/cmd/fmac/policy/mls b/usr/src/cmd/fmac/policy/mls --- a/usr/src/cmd/fmac/policy/mls +++ b/usr/src/cmd/fmac/policy/mls @@ -249,15 +249,10 @@ class shm class security { + setenforce : none + load_policy : none compute_av : none - notify_perm : none - transition_sid : none - member_sid : none - sid_to_context : none - context_to_sid : none - load_policy : none - register_avc : none - change_sid : none + check_context : none } class system diff --git a/usr/src/common/fmac/policy/flask/access_vectors b/usr/src/common/fmac/policy/flask/access_vectors --- a/usr/src/common/fmac/policy/flask/access_vectors +++ b/usr/src/common/fmac/policy/flask/access_vectors @@ -292,17 +292,10 @@ inherits ipc class security { + setenforce + load_policy compute_av - notify_perm - transition_sid - member_sid - sid_to_context - context_to_sid - load_policy - get_sids - register_avc - change_sid - get_user_sids + check_context } -- Stephen Smalley National Security Agency From john.weeks at sun.com Tue Jul 1 12:55:23 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 01 Jul 2008 12:55:23 -0700 Subject: [fmac-discuss] [PATCH] Synchronize security class with FMAC syscalls In-Reply-To: <1214924814.22447.217.camel@moss-spartans.epoch.ncsc.mil> References: <1214924814.22447.217.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486A8BAB.5060500@sun.com> Stephen Smalley wrote: > Synchronize the security class permission definitions with the FMAC > syscalls, and update the example policy configuration accordingly. Acked-by: John Weeks > > diff --git a/usr/src/cmd/fmac/policy/domains/admin/sysadm.te b/usr/src/cmd/fmac/policy/domains/admin/sysadm.te > --- a/usr/src/cmd/fmac/policy/domains/admin/sysadm.te > +++ b/usr/src/cmd/fmac/policy/domains/admin/sysadm.te > @@ -118,7 +118,7 @@ allow rmmod_t $1_gph_t:fd inherit_fd_per > allow rmmod_t $1_gph_t:fd inherit_fd_perms; > > # Reload the policy configuration. > -allow $1_t policy_config_t:security load_policy; > +allow $1_t security_t:security load_policy; > > # Execute setfiles. > can_exec($1_t, policy_src_t) > diff --git a/usr/src/cmd/fmac/policy/domains/every.te b/usr/src/cmd/fmac/policy/domains/every.te > --- a/usr/src/cmd/fmac/policy/domains/every.te > +++ b/usr/src/cmd/fmac/policy/domains/every.te > @@ -41,13 +41,6 @@ allow domain self:{ tcp_socket unix_stre > > # Use the system shared libraries. > uses_shlib(domain) > - > -# Obtain the context of any SID. > -allow domain *:security sid_to_context; > - > -# Obtains SIDs for contexts and obtain the > -# list of active SIDs. > -allow domain security_t:security { context_to_sid get_sids }; > > # Read/search default file type. > allow domain file_t:dir r_dir_perms; > diff --git a/usr/src/cmd/fmac/policy/domains/program/newrole.te b/usr/src/cmd/fmac/policy/domains/program/newrole.te > --- a/usr/src/cmd/fmac/policy/domains/program/newrole.te > +++ b/usr/src/cmd/fmac/policy/domains/program/newrole.te > @@ -66,8 +66,6 @@ allow user_t sysadm_t:process { sigchld > # > # Allow newrole to relabel TTY's > # > -allow newrole_t security_t:security { change_sid }; > - > allow newrole_t user_tty_device_t:chr_file { relabelfrom relabelto }; > allow newrole_t sysadm_tty_device_t:chr_file { relabelfrom relabelto }; > > diff --git a/usr/src/cmd/fmac/policy/domains/system/login.te b/usr/src/cmd/fmac/policy/domains/system/login.te > --- a/usr/src/cmd/fmac/policy/domains/system/login.te > +++ b/usr/src/cmd/fmac/policy/domains/system/login.te > @@ -83,9 +83,6 @@ allow local_login_t mail_spool_t:dir r_d > allow local_login_t mail_spool_t:dir r_dir_perms; > allow local_login_t mail_spool_t:file getattr; > > -# Obtain the SID to use for relabeling terminals. > -allow local_login_t security_t:security change_sid; > - > # Read and write ttys. > allow local_login_t tty_device_t:chr_file rw_file_perms; > > @@ -134,8 +131,5 @@ allow remote_login_t mail_spool_t:dir r_ > allow remote_login_t mail_spool_t:dir r_dir_perms; > allow remote_login_t mail_spool_t:file getattr; > > -# Obtain the SID to use for relabeling ptys. > -allow remote_login_t security_t:security change_sid; > - > # Relabel ptys created by rlogind. > allow remote_login_t rlogind_devpts_t:chr_file { relabelfrom relabelto }; > diff --git a/usr/src/cmd/fmac/policy/domains/system/sshd.te b/usr/src/cmd/fmac/policy/domains/system/sshd.te > --- a/usr/src/cmd/fmac/policy/domains/system/sshd.te > +++ b/usr/src/cmd/fmac/policy/domains/system/sshd.te > @@ -109,9 +109,6 @@ allow sshd_login_t mail_spool_t:dir r_di > allow sshd_login_t mail_spool_t:dir r_dir_perms; > allow sshd_login_t mail_spool_t:file getattr; > > -# Obtain the SID to use for relabeling ptys > -allow sshd_login_t security_t:security change_sid; > - > # Relabel ptys created by sshd > allow sshd_login_t sshd_devpts_t:chr_file { relabelfrom relabelto }; > allow sshd_login_t user_devpts_t:chr_file { relabelto relabelfrom getattr }; > diff --git a/usr/src/cmd/fmac/policy/init.te b/usr/src/cmd/fmac/policy/init.te > --- a/usr/src/cmd/fmac/policy/init.te > +++ b/usr/src/cmd/fmac/policy/init.te > @@ -86,9 +86,6 @@ can_udp_send(sysadm_t, initial_boot_t) > # Rules for the initial_boot_t domain. > # > > -# Use security server calls. > -allow initial_boot_t security_t:security { compute_av change_sid }; > - > # Perform any privileged operation. > allow initial_boot_t kernel_t:system *; > allow initial_boot_t self:capability *; > diff --git a/usr/src/cmd/fmac/policy/mls b/usr/src/cmd/fmac/policy/mls > --- a/usr/src/cmd/fmac/policy/mls > +++ b/usr/src/cmd/fmac/policy/mls > @@ -249,15 +249,10 @@ class shm > > class security > { > + setenforce : none > + load_policy : none > compute_av : none > - notify_perm : none > - transition_sid : none > - member_sid : none > - sid_to_context : none > - context_to_sid : none > - load_policy : none > - register_avc : none > - change_sid : none > + check_context : none > } > > class system > diff --git a/usr/src/common/fmac/policy/flask/access_vectors b/usr/src/common/fmac/policy/flask/access_vectors > --- a/usr/src/common/fmac/policy/flask/access_vectors > +++ b/usr/src/common/fmac/policy/flask/access_vectors > @@ -292,17 +292,10 @@ inherits ipc > > class security > { > + setenforce > + load_policy > compute_av > - notify_perm > - transition_sid > - member_sid > - sid_to_context > - context_to_sid > - load_policy > - get_sids > - register_avc > - change_sid > - get_user_sids > + check_context > } > > > > From Glenn.Faden at Sun.COM Tue Jul 1 14:09:30 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Tue, 01 Jul 2008 14:09:30 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214837118.22447.98.camel@moss-spartans.epoch.ncsc.mil> References: <485AA1F6.3080005@sun.com> <1213967337.32066.347.camel@moss-spartans.epoch.ncsc.mil> <485BF782.9050802@sun.com> <1213992054.32066.464.camel@moss-spartans.epoch.ncsc.mil> <485C3DC8.2060502@sun.com> <48602CC5.3090107@sun.com> <1214309446.32762.162.camel@moss-spartans.epoch.ncsc.mil> <4860F615.5030302@Sun.COM> <1214314297.32762.201.camel@moss-spartans.epoch.ncsc.mil> <48637B6B.7050103@Sun.COM> <48687DDC.1050203@sun.com> <1214837118.22447.98.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486A9D0A.1040605@sun.com> Stephen Smalley wrote:. > > Is there a particular namespace we should be using for the security > contexts? In Linux, there is a "system" namespace for system > interpreted/used attributes that gets used by ACLs, but we nonetheless > introduced a separate "security" namespace devoted to security modules, > where each module could use its own attribute within that namespace, > e.g. "security.selinux" for SELinux. > > Not sure what is involved in creating an extended attribute namespace in > Solaris yet; in Linux, it was fairly straightforward to create one > modeled after the existing hierarchical "user" and "trusted" namespaces. > As part of the CIFS project, a new set of interfaces were introduced to provide a namespace for system attributes. This is described in PSARC /2007/315 Extended Attribute Interfaces The approved text for the case is included in this link: http://www.opensolaris.org/jive/thread.jspa?messageID=129154🡈 --Glenn From sds at tycho.nsa.gov Wed Jul 2 11:25:11 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Wed, 02 Jul 2008 14:25:11 -0400 Subject: [fmac-discuss] [PATCH] Rework file and process access vectors Message-ID: <1215023111.22447.324.camel@moss-spartans.epoch.ncsc.mil> This patch reworks the file and process access vector definitions in preparation for adding permission checks. Some of the changes are to bring the definitions more into alignment with the permissions in modern SELinux (in particular for checks on domain transitions), while other changes are to reorganize the definitions and prune unnecessary ones. The "initpolicy" is also removed as it is unnecessary. Future revisions to the definitions are likely. diff --git a/usr/src/cmd/fmac/policy/Makefile b/usr/src/cmd/fmac/policy/Makefile --- a/usr/src/cmd/fmac/policy/Makefile +++ b/usr/src/cmd/fmac/policy/Makefile @@ -38,8 +38,6 @@ # install - compile and install the policy configuration. # load - compile, install, and load the policy configuration. # relabel - relabel the file system based on file_contexts. -# initpolicy - compile the initial policy configuration. -# initinstall - compile and install the initial policy configuration. # # The default target is 'policy'. # @@ -196,16 +194,6 @@ relabel: $(FILECONTEXT_FILE) $(SETFILES) -v $(FILECONTEXT_FILE) `mount -p | awk '/ufs/{print $$3}; /zfs/{print $$3}'` $(TOUCH) relabel -initpolicy: initpolicy.conf $(CHECKPOLICY) - $(CHECKPOLICY) -o $@ initpolicy.conf - $(CHECKPOLICY) -b $@ - -initpolicy.conf: $(INITPOLICYFILES) all.te - $(M4) $(M4FLAGS) -s $(INITPOLICYFILES) > initpolicy.conf - -initinstall: initpolicy - install -m 644 -o root -g root initpolicy /ss_policy - all.te: macros.te attrib.te all_types.te all_domains.te assert.te $(CAT) $^ > $@ @@ -229,6 +217,5 @@ admin_domains.te: $(ADMIN_DOMAINS) clean: $(RM) -f policy ss_policy policy.conf - $(RM) -f initpolicy initpolicy.conf include ../../Makefile.targ diff --git a/usr/src/cmd/fmac/policy/assert.te b/usr/src/cmd/fmac/policy/assert.te --- a/usr/src/cmd/fmac/policy/assert.te +++ b/usr/src/cmd/fmac/policy/assert.te @@ -129,24 +129,17 @@ define(`assert_execute', ` define(`assert_execute', ` ifelse($#, 0, , $#, 1, - ``neverallow $1_t ~{ $1_exec_t ld_so_t shlib_t }:process execute;'', + ``neverallow $1_t ~$1_exec_t:file entrypoint; + neverallow $1_t ~{ $1_exec_t ld_so_t }:file execute_no_trans;'', `assert_execute($1) assert_execute(shift($@))')') assert_execute(getty, klogd, atd, inetd, tcpd, rlogind, ypbind, portmap, syslogd, rpcd, gpm, xfs, fsadm) -neverallow local_login_t ~{ login_exec_t ld_so_t shlib_t }:process execute; -neverallow remote_login_t ~{ login_exec_t ld_so_t shlib_t }:process execute; +neverallow { local_login_t remote_login_t } ~login_exec_t:file entrypoint; +neverallow { local_login_t remote_login_t } ~ld_so_t:file execute_no_trans; # -# Verify that the passwd domain can only execute code from -# its entrypoint executable, the ordinary passwd program, -# the dynamic loader, or the shared libraries. +# Verify that only the admin domains and initrc_t have setenforce. # -neverallow passwd_t ~{ passwd_exec_t bin_t ld_so_t shlib_t }:process execute; - - -# -# Verify that only the admin domains and initrc_t have avc_toggle. -# -neverallow ~{ admin initrc_t } kernel_t:system avc_toggle; +neverallow ~{ admin initrc_t } security_t:security setenforce; diff --git a/usr/src/cmd/fmac/policy/domains/every.te b/usr/src/cmd/fmac/policy/domains/every.te --- a/usr/src/cmd/fmac/policy/domains/every.te +++ b/usr/src/cmd/fmac/policy/domains/every.te @@ -30,7 +30,7 @@ # # Access other processes in the same domain. -allow domain self:process ~{ execute entrypoint }; +allow domain self:process *; # Access file descriptions, pipes, and sockets # created by processes in the same domain. diff --git a/usr/src/cmd/fmac/policy/domains/program/netscape.te b/usr/src/cmd/fmac/policy/domains/program/netscape.te --- a/usr/src/cmd/fmac/policy/domains/program/netscape.te +++ b/usr/src/cmd/fmac/policy/domains/program/netscape.te @@ -55,7 +55,6 @@ allow $1_t $1_netscape_t:notdevfile_clas # Allow use of /dev/zero by ld.so. allow $1_netscape_t zero_device_t:chr_file rw_file_perms; -allow $1_netscape_t zero_device_t:process execute; # Create temporary files file_type_auto_trans($1_netscape_t, tmp_t, $1_netscape_rw_t) diff --git a/usr/src/cmd/fmac/policy/domains/program/passwd.te b/usr/src/cmd/fmac/policy/domains/program/passwd.te --- a/usr/src/cmd/fmac/policy/domains/program/passwd.te +++ b/usr/src/cmd/fmac/policy/domains/program/passwd.te @@ -47,9 +47,6 @@ allow passwd_t remote_login_t:fd inherit # Execute /usr/bin/{passwd,chfn,chsh}. can_exec(passwd_t, bin_t) -# Test for the existence of a shell. -allow passwd_t shell_exec_t:file access; - # Update /etc/passwd. allow passwd_t etc_t:dir rw_dir_perms; allow passwd_t etc_t:file create_file_perms; diff --git a/usr/src/cmd/fmac/policy/domains/program/utempter.te b/usr/src/cmd/fmac/policy/domains/program/utempter.te --- a/usr/src/cmd/fmac/policy/domains/program/utempter.te +++ b/usr/src/cmd/fmac/policy/domains/program/utempter.te @@ -43,7 +43,7 @@ allow utempter_t wtmp_t:file rw_file_per allow utempter_t wtmp_t:file rw_file_perms; # Allow ioctl and getattr /dev/ptmx. -allow utempter_t ptmx_t:chr_file { ioctl getattr }; +allow utempter_t ptmx_t:chr_file { read getattr }; # Inherit and use descriptors from login. allow utempter_t local_login_t:fd inherit_fd_perms; diff --git a/usr/src/cmd/fmac/policy/domains/system/crond.te b/usr/src/cmd/fmac/policy/domains/system/crond.te --- a/usr/src/cmd/fmac/policy/domains/system/crond.te +++ b/usr/src/cmd/fmac/policy/domains/system/crond.te @@ -119,7 +119,7 @@ allow system_crond_t system_crond_script # the system cron job. It performs an entrypoint # permission check for this purpose. # -allow system_crond_t system_crond_script_t:process entrypoint; +allow system_crond_t system_crond_script_t:file entrypoint; # Run helper programs in the system_crond_t domain. can_exec_any(system_crond_t) @@ -160,9 +160,9 @@ file_type_auto_trans(system_crond_t, tmp file_type_auto_trans(system_crond_t, tmp_t, system_crond_tmp_t) # Used for /sbin/tmpwatch -allow system_crond_t tmpfile:dir { read getattr setattr access lock search remove_name rmdir }; +allow system_crond_t tmpfile:dir { read getattr setattr lock search remove_name rmdir }; allow system_crond_t tmpfile:notdevfile_class_set link_file_perms; -allow system_crond_t catman_t:dir { read getattr setattr access lock search remove_name rmdir }; +allow system_crond_t catman_t:dir { read getattr setattr lock search remove_name rmdir }; allow system_crond_t catman_t:notdevfile_class_set link_file_perms; @@ -196,7 +196,7 @@ domain_trans(crond_t, shell_exec_t, $1_c # the user cron job. It performs an entrypoint # permission check for this purpose. # -allow $1_crond_t $1_cron_spool_t:process entrypoint; +allow $1_crond_t $1_cron_spool_t:file entrypoint; # Use pipe from crond_t. allow $1_crond_t crond_t:pipe rw_file_perms; diff --git a/usr/src/cmd/fmac/policy/domains/system/initrc.te b/usr/src/cmd/fmac/policy/domains/system/initrc.te --- a/usr/src/cmd/fmac/policy/domains/system/initrc.te +++ b/usr/src/cmd/fmac/policy/domains/system/initrc.te @@ -121,8 +121,8 @@ file_type_auto_trans(initrc_t, boot_t, b file_type_auto_trans(initrc_t, boot_t, boot_runtime_t) # Unlink the xfs socket. -allow initrc_t xfs_tmp_t:dir { read search getattr access remove_name rmdir }; -allow initrc_t xfs_tmp_t:sock_file { read getattr access unlink }; +allow initrc_t xfs_tmp_t:dir { read search getattr remove_name rmdir }; +allow initrc_t xfs_tmp_t:sock_file { read getattr unlink }; # Update /var/log/wtmp and /var/log/dmesg. allow initrc_t wtmp_t:file rw_file_perms; diff --git a/usr/src/cmd/fmac/policy/init.te b/usr/src/cmd/fmac/policy/init.te deleted file mode 100644 --- a/usr/src/cmd/fmac/policy/init.te +++ /dev/null @@ -1,137 +0,0 @@ -# -# 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 -# - -# -# Original files contributed to OpenSolaris.org under license by the -# United States Government (NSA) to Sun Microsystems, Inc. -# - -# -# Extensions to the Type Enforcement configuration -# for the initial boot and relabeling of the system. -# - - -# -# Define a new domain for all descendants of init. -# -type initial_boot_t, domain, privuser, privrole, privowner; - -# -# Include the normal policy configuration so -# that all types will be defined for the relabeling -# and so that all rules that apply to all domains -# will be applied. -# -include(all.te) - -# -# Extend the kernel_t domain. -# -allow kernel_t file_t:dir_file_class_set *; - -# -# Extend the init_t domain. -# -allow init_t file_t:dir_file_class_set *; -allow init_t file_t:process { entrypoint execute }; -domain_auto_trans(init_t, file_t, initial_boot_t) -can_unix_connect(init_t, initial_boot_t) - -# -# Extend the initrc_t domain (for reboot after relabel). -# -can_unix_send(initrc_t, initial_boot_t) -allow initrc_t file_t:file unlink; - -# -# Extend the kmod_t domain. -# -allow kmod_t file_t:dir_file_class_set *; -allow kmod_t file_t:process execute; -can_unix_connect(kmod_t, initial_boot_t) - -# -# Extend the sysadm_t domain. -# -allow sysadm_t file_t:dir_file_class_set *; -allow sysadm_t file_t:process execute; -can_exec(sysadm_t, user_home_t) -allow sysadm_t tty_device_t:chr_file rw_file_perms; -allow sysadm_t file_t:unix_stream_socket name_bind; -allow sysadm_t file_t:unix_dgram_socket name_bind; -can_unix_send(sysadm_t, initial_boot_t) -can_unix_connect(sysadm_t, initial_boot_t) -can_udp_send(sysadm_t, initial_boot_t) - -# -# Rules for the initial_boot_t domain. -# - -# Perform any privileged operation. -allow initial_boot_t kernel_t:system *; -allow initial_boot_t self:capability *; - -# Change sysctl variables. -can_sysctl(initial_boot_t) - -# Read /proc/kmsg (for klogd). -allow initial_boot_t proc_kmsg_t:file r_file_perms; - -# Use the network and configure network interfaces. -can_network(initial_boot_t) -allow initial_boot_t netif_type:netif { getattr setattr }; - -# Bind to any network port. -allow initial_boot_t port_type:tcp_socket name_bind; -allow initial_boot_t port_type:udp_socket name_bind; - -# Perform any operation on any process. -allow initial_boot_t domain:process ~{ entrypoint execute }; -allow initial_boot_t domain:dir_file_class_set *; - -# Execute code from any program. -allow initial_boot_t file_type:process { entrypoint execute }; - -# Perform any operation on any file system. -allow initial_boot_t fs_type:filesystem *; - -# Perform any operation on any file. -allow initial_boot_t file_type:dir_file_class_set *; - -# Bind to a file_t Unix domain socket file. -allow initial_boot_t file_t:unix_stream_socket name_bind; -allow initial_boot_t file_t:unix_dgram_socket name_bind; - -# Send to sysadm_t. -can_udp_send(initial_boot_t, sysadm_t) - -# Can transition to sysadm_t for login. -domain_trans(initial_boot_t, file_t, sysadm_t) - -# Transition to proper domain when executing module programs after relabel. -domain_auto_trans(initial_boot_t, modprobe_exec_t, modprobe_t) -domain_auto_trans(initial_boot_t, insmod_exec_t, insmod_t) -domain_auto_trans(initial_boot_t, rmmod_exec_t, rmmod_t) - -# Add initial_boot_t to the system_r role. -role system_r types initial_boot_t; - diff --git a/usr/src/cmd/fmac/policy/macros.te b/usr/src/cmd/fmac/policy/macros.te --- a/usr/src/cmd/fmac/policy/macros.te +++ b/usr/src/cmd/fmac/policy/macros.te @@ -68,63 +68,63 @@ define(`socket_class_set', `{ tcp_socket # # Permissions for getting file attributes. # -define(`stat_file_perms', `{ getattr access }') +define(`stat_file_perms', `{ getattr }') # # Permissions for executing files. # -define(`x_file_perms', `{ getattr access execute }') +define(`x_file_perms', `{ getattr execute }') # # Permissions for reading files and their attributes. # -define(`r_file_perms', `{ read getattr access lock poll }') +define(`r_file_perms', `{ read getattr lock }') # # Permissions for reading and executing files. # -define(`rx_file_perms', `{ read getattr access lock poll execute }') +define(`rx_file_perms', `{ read getattr lock execute }') # # Permissions for reading and writing files and their attributes. # -define(`rw_file_perms', `{ ioctl read getattr access lock poll write setattr append }') +define(`rw_file_perms', `{ read getattr lock write setattr append }') # # Permissions for reading and appending to files. # -define(`ra_file_perms', `{ ioctl read getattr access lock poll append }') +define(`ra_file_perms', `{ read getattr lock append }') # # Permissions for linking, unlinking and renaming files. # -define(`link_file_perms', `{ getattr access link unlink rename }') +define(`link_file_perms', `{ getattr link unlink rename }') # # Permissions for creating and using files. # -define(`create_file_perms', `{ create ioctl read getattr access lock poll write setattr append link unlink rename }') +define(`create_file_perms', `{ create read getattr lock write setattr append link unlink rename }') # # Permissions for reading directories and their attributes. # -define(`r_dir_perms', `{ read getattr access lock poll search }') +define(`r_dir_perms', `{ read getattr lock search }') # # Permissions for reading and writing directories and their attributes. # -define(`rw_dir_perms', `{ read getattr access lock poll setattr search add_name remove_name }') +define(`rw_dir_perms', `{ read getattr lock setattr search add_name remove_name }') # # Permissions for reading and adding names to directories. # -define(`ra_dir_perms', `{ read getattr access lock poll setattr search add_name }') +define(`ra_dir_perms', `{ read getattr lock setattr search add_name }') # # Permissions for creating and using directories. # -define(`create_dir_perms', `{ create read getattr access poll setattr link unlink rename search add_name remove_name reparent rmdir }') +define(`create_dir_perms', `{ create read getattr setattr link unlink rename search add_name remove_name reparent rmdir }') # # Permissions to inherit and use file descriptions. @@ -144,22 +144,22 @@ define(`mount_fs_perms', `{ mount remoun # # Permissions for using sockets. # -define(`rw_socket_perms', `{ ioctl read getattr poll write setattr append bind connect getopt setopt shutdown }') +define(`rw_socket_perms', `{ read getattr write setattr append bind connect getopt setopt shutdown }') # # Permissions for creating and using sockets. # -define(`create_socket_perms', `{ create ioctl read getattr poll write setattr append bind connect getopt setopt shutdown }') +define(`create_socket_perms', `{ create read getattr write setattr append bind connect getopt setopt shutdown }') # # Permissions for using stream sockets. # -define(`rw_stream_socket_perms', `{ ioctl read getattr poll write setattr append bind connect getopt setopt shutdown listen accept }') +define(`rw_stream_socket_perms', `{ read getattr write setattr append bind connect getopt setopt shutdown listen accept }') # # Permissions for creating and using stream sockets. # -define(`create_stream_socket_perms', `{ create ioctl read getattr poll write setattr append bind connect getopt setopt shutdown listen accept }') +define(`create_stream_socket_perms', `{ create read getattr write setattr append bind connect getopt setopt shutdown listen accept }') # @@ -224,14 +224,9 @@ allow $3 $2:file r_file_perms; allow $3 $2:file r_file_perms; # -# Allow the new domain to execute from the program. -# -allow $3 $2:process execute; - -# # Allow the new domain to be entered by the program. # -allow $3 $2:process entrypoint; +allow $3 $2:file entrypoint; ') ################################# @@ -254,9 +249,8 @@ type_transition $1 $2:process $3; # define(`uses_shlib',` allow $1 ld_so_t:file rx_file_perms; -allow $1 ld_so_t:process execute; -allow $1 shlib_t:file r_file_perms; -allow $1 shlib_t:process execute; +allow $1 ld_so_t:file execute_no_trans; +allow $1 shlib_t:file rx_file_perms; ') ################################# @@ -268,7 +262,7 @@ allow $1 shlib_t:process execute; # define(`can_exec',` allow $1 $2:file rx_file_perms; -allow $1 $2:process execute; +allow $1 $2:file execute_no_trans; ') ################################# diff --git a/usr/src/cmd/fmac/policy/mls b/usr/src/cmd/fmac/policy/mls --- a/usr/src/cmd/fmac/policy/mls +++ b/usr/src/cmd/fmac/policy/mls @@ -62,23 +62,21 @@ level ts:nocon, noforn, nato, usuk; common file { - poll : none - ioctl : none + execute : read + write : write read : read - write : write + append : write + open : read create : write + link : write + unlink : write + rename : write getattr : read setattr : write lock : none relabelfrom : { read write } relabelto : write transition : write - append : write - access : none - unlink : write - link : write - rename : write - execute : read } common socket @@ -142,6 +140,11 @@ class dir } class file +{ + execute_no_trans : read + entrypoint : read +} + class lnk_file class chr_file class blk_file @@ -211,7 +214,6 @@ class unix_stream_socket class process { - execute : read fork : none transition : write sigchld : readby @@ -224,9 +226,9 @@ class process getsession : read getpgid : read setpgid : write - getcap : read - setcap : write - entrypoint : read + setexec : write + setfscreate : write + execsetid : none } class sem @@ -262,7 +264,6 @@ class system arp_control : none rarp_control : none ipc_info : read - avc_toggle : none } class capability diff --git a/usr/src/common/fmac/policy/flask/access_vectors b/usr/src/common/fmac/policy/flask/access_vectors --- a/usr/src/common/fmac/policy/flask/access_vectors +++ b/usr/src/common/fmac/policy/flask/access_vectors @@ -36,23 +36,21 @@ common file { - poll - ioctl + execute + write read - write + append + open create + link + unlink + rename getattr setattr lock relabelfrom relabelto transition - append - access - unlink - link - rename - execute } @@ -139,6 +137,10 @@ inherits file class file inherits file +{ + execute_no_trans + entrypoint +} class lnk_file inherits file @@ -241,7 +243,6 @@ inherits socket class process { - execute fork transition sigchld @@ -254,9 +255,9 @@ class process getsession getpgid setpgid - getcap - setcap - entrypoint + setexec + setfscreate + execsetid } @@ -310,7 +311,6 @@ class system arp_control rarp_control ipc_info - avc_toggle } # -- Stephen Smalley National Security Agency From john.weeks at sun.com Wed Jul 2 11:46:37 2008 From: john.weeks at sun.com (John Weeks) Date: Wed, 02 Jul 2008 11:46:37 -0700 Subject: [fmac-discuss] [PATCH] Rework file and process access vectors In-Reply-To: <1215023111.22447.324.camel@moss-spartans.epoch.ncsc.mil> References: <1215023111.22447.324.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486BCD0D.3080805@sun.com> Stephen Smalley wrote: > This patch reworks the file and process access vector definitions in > preparation for adding permission checks. Some of the changes are to > bring the definitions more into alignment with the permissions in modern > SELinux (in particular for checks on domain transitions), while other > changes are to reorganize the definitions and prune unnecessary ones. > The "initpolicy" is also removed as it is unnecessary. Future revisions > to the definitions are likely. Acked-by: John Weeks Thanks for making the updates. > > > diff --git a/usr/src/cmd/fmac/policy/Makefile b/usr/src/cmd/fmac/policy/Makefile > --- a/usr/src/cmd/fmac/policy/Makefile > +++ b/usr/src/cmd/fmac/policy/Makefile > @@ -38,8 +38,6 @@ > # install - compile and install the policy configuration. > # load - compile, install, and load the policy configuration. > # relabel - relabel the file system based on file_contexts. > -# initpolicy - compile the initial policy configuration. > -# initinstall - compile and install the initial policy configuration. > # > # The default target is 'policy'. > # > @@ -196,16 +194,6 @@ relabel: $(FILECONTEXT_FILE) > $(SETFILES) -v $(FILECONTEXT_FILE) `mount -p | awk '/ufs/{print $$3}; /zfs/{print $$3}'` > $(TOUCH) relabel > > -initpolicy: initpolicy.conf $(CHECKPOLICY) > - $(CHECKPOLICY) -o $@ initpolicy.conf > - $(CHECKPOLICY) -b $@ > - > -initpolicy.conf: $(INITPOLICYFILES) all.te > - $(M4) $(M4FLAGS) -s $(INITPOLICYFILES) > initpolicy.conf > - > -initinstall: initpolicy > - install -m 644 -o root -g root initpolicy /ss_policy > - > all.te: macros.te attrib.te all_types.te all_domains.te assert.te > $(CAT) $^ > $@ > > @@ -229,6 +217,5 @@ admin_domains.te: $(ADMIN_DOMAINS) > > clean: > $(RM) -f policy ss_policy policy.conf > - $(RM) -f initpolicy initpolicy.conf > > include ../../Makefile.targ > diff --git a/usr/src/cmd/fmac/policy/assert.te b/usr/src/cmd/fmac/policy/assert.te > --- a/usr/src/cmd/fmac/policy/assert.te > +++ b/usr/src/cmd/fmac/policy/assert.te > @@ -129,24 +129,17 @@ define(`assert_execute', ` > define(`assert_execute', ` > ifelse($#, 0, , > $#, 1, > - ``neverallow $1_t ~{ $1_exec_t ld_so_t shlib_t }:process execute;'', > + ``neverallow $1_t ~$1_exec_t:file entrypoint; > + neverallow $1_t ~{ $1_exec_t ld_so_t }:file execute_no_trans;'', > `assert_execute($1) assert_execute(shift($@))')') > > assert_execute(getty, klogd, atd, inetd, tcpd, rlogind, > ypbind, portmap, syslogd, rpcd, gpm, xfs, fsadm) > > -neverallow local_login_t ~{ login_exec_t ld_so_t shlib_t }:process execute; > -neverallow remote_login_t ~{ login_exec_t ld_so_t shlib_t }:process execute; > +neverallow { local_login_t remote_login_t } ~login_exec_t:file entrypoint; > +neverallow { local_login_t remote_login_t } ~ld_so_t:file execute_no_trans; > > # > -# Verify that the passwd domain can only execute code from > -# its entrypoint executable, the ordinary passwd program, > -# the dynamic loader, or the shared libraries. > +# Verify that only the admin domains and initrc_t have setenforce. > # > -neverallow passwd_t ~{ passwd_exec_t bin_t ld_so_t shlib_t }:process execute; > - > - > -# > -# Verify that only the admin domains and initrc_t have avc_toggle. > -# > -neverallow ~{ admin initrc_t } kernel_t:system avc_toggle; > +neverallow ~{ admin initrc_t } security_t:security setenforce; > diff --git a/usr/src/cmd/fmac/policy/domains/every.te b/usr/src/cmd/fmac/policy/domains/every.te > --- a/usr/src/cmd/fmac/policy/domains/every.te > +++ b/usr/src/cmd/fmac/policy/domains/every.te > @@ -30,7 +30,7 @@ > # > > # Access other processes in the same domain. > -allow domain self:process ~{ execute entrypoint }; > +allow domain self:process *; > > # Access file descriptions, pipes, and sockets > # created by processes in the same domain. > diff --git a/usr/src/cmd/fmac/policy/domains/program/netscape.te b/usr/src/cmd/fmac/policy/domains/program/netscape.te > --- a/usr/src/cmd/fmac/policy/domains/program/netscape.te > +++ b/usr/src/cmd/fmac/policy/domains/program/netscape.te > @@ -55,7 +55,6 @@ allow $1_t $1_netscape_t:notdevfile_clas > > # Allow use of /dev/zero by ld.so. > allow $1_netscape_t zero_device_t:chr_file rw_file_perms; > -allow $1_netscape_t zero_device_t:process execute; > > # Create temporary files > file_type_auto_trans($1_netscape_t, tmp_t, $1_netscape_rw_t) > diff --git a/usr/src/cmd/fmac/policy/domains/program/passwd.te b/usr/src/cmd/fmac/policy/domains/program/passwd.te > --- a/usr/src/cmd/fmac/policy/domains/program/passwd.te > +++ b/usr/src/cmd/fmac/policy/domains/program/passwd.te > @@ -47,9 +47,6 @@ allow passwd_t remote_login_t:fd inherit > # Execute /usr/bin/{passwd,chfn,chsh}. > can_exec(passwd_t, bin_t) > > -# Test for the existence of a shell. > -allow passwd_t shell_exec_t:file access; > - > # Update /etc/passwd. > allow passwd_t etc_t:dir rw_dir_perms; > allow passwd_t etc_t:file create_file_perms; > diff --git a/usr/src/cmd/fmac/policy/domains/program/utempter.te b/usr/src/cmd/fmac/policy/domains/program/utempter.te > --- a/usr/src/cmd/fmac/policy/domains/program/utempter.te > +++ b/usr/src/cmd/fmac/policy/domains/program/utempter.te > @@ -43,7 +43,7 @@ allow utempter_t wtmp_t:file rw_file_per > allow utempter_t wtmp_t:file rw_file_perms; > > # Allow ioctl and getattr /dev/ptmx. > -allow utempter_t ptmx_t:chr_file { ioctl getattr }; > +allow utempter_t ptmx_t:chr_file { read getattr }; > > # Inherit and use descriptors from login. > allow utempter_t local_login_t:fd inherit_fd_perms; > diff --git a/usr/src/cmd/fmac/policy/domains/system/crond.te b/usr/src/cmd/fmac/policy/domains/system/crond.te > --- a/usr/src/cmd/fmac/policy/domains/system/crond.te > +++ b/usr/src/cmd/fmac/policy/domains/system/crond.te > @@ -119,7 +119,7 @@ allow system_crond_t system_crond_script > # the system cron job. It performs an entrypoint > # permission check for this purpose. > # > -allow system_crond_t system_crond_script_t:process entrypoint; > +allow system_crond_t system_crond_script_t:file entrypoint; > > # Run helper programs in the system_crond_t domain. > can_exec_any(system_crond_t) > @@ -160,9 +160,9 @@ file_type_auto_trans(system_crond_t, tmp > file_type_auto_trans(system_crond_t, tmp_t, system_crond_tmp_t) > > # Used for /sbin/tmpwatch > -allow system_crond_t tmpfile:dir { read getattr setattr access lock search remove_name rmdir }; > +allow system_crond_t tmpfile:dir { read getattr setattr lock search remove_name rmdir }; > allow system_crond_t tmpfile:notdevfile_class_set link_file_perms; > -allow system_crond_t catman_t:dir { read getattr setattr access lock search remove_name rmdir }; > +allow system_crond_t catman_t:dir { read getattr setattr lock search remove_name rmdir }; > allow system_crond_t catman_t:notdevfile_class_set link_file_perms; > > > @@ -196,7 +196,7 @@ domain_trans(crond_t, shell_exec_t, $1_c > # the user cron job. It performs an entrypoint > # permission check for this purpose. > # > -allow $1_crond_t $1_cron_spool_t:process entrypoint; > +allow $1_crond_t $1_cron_spool_t:file entrypoint; > > # Use pipe from crond_t. > allow $1_crond_t crond_t:pipe rw_file_perms; > diff --git a/usr/src/cmd/fmac/policy/domains/system/initrc.te b/usr/src/cmd/fmac/policy/domains/system/initrc.te > --- a/usr/src/cmd/fmac/policy/domains/system/initrc.te > +++ b/usr/src/cmd/fmac/policy/domains/system/initrc.te > @@ -121,8 +121,8 @@ file_type_auto_trans(initrc_t, boot_t, b > file_type_auto_trans(initrc_t, boot_t, boot_runtime_t) > > # Unlink the xfs socket. > -allow initrc_t xfs_tmp_t:dir { read search getattr access remove_name rmdir }; > -allow initrc_t xfs_tmp_t:sock_file { read getattr access unlink }; > +allow initrc_t xfs_tmp_t:dir { read search getattr remove_name rmdir }; > +allow initrc_t xfs_tmp_t:sock_file { read getattr unlink }; > > # Update /var/log/wtmp and /var/log/dmesg. > allow initrc_t wtmp_t:file rw_file_perms; > diff --git a/usr/src/cmd/fmac/policy/init.te b/usr/src/cmd/fmac/policy/init.te > deleted file mode 100644 > --- a/usr/src/cmd/fmac/policy/init.te > +++ /dev/null > @@ -1,137 +0,0 @@ > -# > -# 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 > -# > - > -# > -# Original files contributed to OpenSolaris.org under license by the > -# United States Government (NSA) to Sun Microsystems, Inc. > -# > - > -# > -# Extensions to the Type Enforcement configuration > -# for the initial boot and relabeling of the system. > -# > - > - > -# > -# Define a new domain for all descendants of init. > -# > -type initial_boot_t, domain, privuser, privrole, privowner; > - > -# > -# Include the normal policy configuration so > -# that all types will be defined for the relabeling > -# and so that all rules that apply to all domains > -# will be applied. > -# > -include(all.te) > - > -# > -# Extend the kernel_t domain. > -# > -allow kernel_t file_t:dir_file_class_set *; > - > -# > -# Extend the init_t domain. > -# > -allow init_t file_t:dir_file_class_set *; > -allow init_t file_t:process { entrypoint execute }; > -domain_auto_trans(init_t, file_t, initial_boot_t) > -can_unix_connect(init_t, initial_boot_t) > - > -# > -# Extend the initrc_t domain (for reboot after relabel). > -# > -can_unix_send(initrc_t, initial_boot_t) > -allow initrc_t file_t:file unlink; > - > -# > -# Extend the kmod_t domain. > -# > -allow kmod_t file_t:dir_file_class_set *; > -allow kmod_t file_t:process execute; > -can_unix_connect(kmod_t, initial_boot_t) > - > -# > -# Extend the sysadm_t domain. > -# > -allow sysadm_t file_t:dir_file_class_set *; > -allow sysadm_t file_t:process execute; > -can_exec(sysadm_t, user_home_t) > -allow sysadm_t tty_device_t:chr_file rw_file_perms; > -allow sysadm_t file_t:unix_stream_socket name_bind; > -allow sysadm_t file_t:unix_dgram_socket name_bind; > -can_unix_send(sysadm_t, initial_boot_t) > -can_unix_connect(sysadm_t, initial_boot_t) > -can_udp_send(sysadm_t, initial_boot_t) > - > -# > -# Rules for the initial_boot_t domain. > -# > - > -# Perform any privileged operation. > -allow initial_boot_t kernel_t:system *; > -allow initial_boot_t self:capability *; > - > -# Change sysctl variables. > -can_sysctl(initial_boot_t) > - > -# Read /proc/kmsg (for klogd). > -allow initial_boot_t proc_kmsg_t:file r_file_perms; > - > -# Use the network and configure network interfaces. > -can_network(initial_boot_t) > -allow initial_boot_t netif_type:netif { getattr setattr }; > - > -# Bind to any network port. > -allow initial_boot_t port_type:tcp_socket name_bind; > -allow initial_boot_t port_type:udp_socket name_bind; > - > -# Perform any operation on any process. > -allow initial_boot_t domain:process ~{ entrypoint execute }; > -allow initial_boot_t domain:dir_file_class_set *; > - > -# Execute code from any program. > -allow initial_boot_t file_type:process { entrypoint execute }; > - > -# Perform any operation on any file system. > -allow initial_boot_t fs_type:filesystem *; > - > -# Perform any operation on any file. > -allow initial_boot_t file_type:dir_file_class_set *; > - > -# Bind to a file_t Unix domain socket file. > -allow initial_boot_t file_t:unix_stream_socket name_bind; > -allow initial_boot_t file_t:unix_dgram_socket name_bind; > - > -# Send to sysadm_t. > -can_udp_send(initial_boot_t, sysadm_t) > - > -# Can transition to sysadm_t for login. > -domain_trans(initial_boot_t, file_t, sysadm_t) > - > -# Transition to proper domain when executing module programs after relabel. > -domain_auto_trans(initial_boot_t, modprobe_exec_t, modprobe_t) > -domain_auto_trans(initial_boot_t, insmod_exec_t, insmod_t) > -domain_auto_trans(initial_boot_t, rmmod_exec_t, rmmod_t) > - > -# Add initial_boot_t to the system_r role. > -role system_r types initial_boot_t; > - > diff --git a/usr/src/cmd/fmac/policy/macros.te b/usr/src/cmd/fmac/policy/macros.te > --- a/usr/src/cmd/fmac/policy/macros.te > +++ b/usr/src/cmd/fmac/policy/macros.te > @@ -68,63 +68,63 @@ define(`socket_class_set', `{ tcp_socket > # > # Permissions for getting file attributes. > # > -define(`stat_file_perms', `{ getattr access }') > +define(`stat_file_perms', `{ getattr }') > > # > # Permissions for executing files. > # > -define(`x_file_perms', `{ getattr access execute }') > +define(`x_file_perms', `{ getattr execute }') > > # > # Permissions for reading files and their attributes. > # > -define(`r_file_perms', `{ read getattr access lock poll }') > +define(`r_file_perms', `{ read getattr lock }') > > # > # Permissions for reading and executing files. > # > -define(`rx_file_perms', `{ read getattr access lock poll execute }') > +define(`rx_file_perms', `{ read getattr lock execute }') > > # > # Permissions for reading and writing files and their attributes. > # > -define(`rw_file_perms', `{ ioctl read getattr access lock poll write setattr append }') > +define(`rw_file_perms', `{ read getattr lock write setattr append }') > > # > # Permissions for reading and appending to files. > # > -define(`ra_file_perms', `{ ioctl read getattr access lock poll append }') > +define(`ra_file_perms', `{ read getattr lock append }') > > # > # Permissions for linking, unlinking and renaming files. > # > -define(`link_file_perms', `{ getattr access link unlink rename }') > +define(`link_file_perms', `{ getattr link unlink rename }') > > # > # Permissions for creating and using files. > # > -define(`create_file_perms', `{ create ioctl read getattr access lock poll write setattr append link unlink rename }') > +define(`create_file_perms', `{ create read getattr lock write setattr append link unlink rename }') > > # > # Permissions for reading directories and their attributes. > # > -define(`r_dir_perms', `{ read getattr access lock poll search }') > +define(`r_dir_perms', `{ read getattr lock search }') > > # > # Permissions for reading and writing directories and their attributes. > # > -define(`rw_dir_perms', `{ read getattr access lock poll setattr search add_name remove_name }') > +define(`rw_dir_perms', `{ read getattr lock setattr search add_name remove_name }') > > # > # Permissions for reading and adding names to directories. > # > -define(`ra_dir_perms', `{ read getattr access lock poll setattr search add_name }') > +define(`ra_dir_perms', `{ read getattr lock setattr search add_name }') > > > # > # Permissions for creating and using directories. > # > -define(`create_dir_perms', `{ create read getattr access poll setattr link unlink rename search add_name remove_name reparent rmdir }') > +define(`create_dir_perms', `{ create read getattr setattr link unlink rename search add_name remove_name reparent rmdir }') > > # > # Permissions to inherit and use file descriptions. > @@ -144,22 +144,22 @@ define(`mount_fs_perms', `{ mount remoun > # > # Permissions for using sockets. > # > -define(`rw_socket_perms', `{ ioctl read getattr poll write setattr append bind connect getopt setopt shutdown }') > +define(`rw_socket_perms', `{ read getattr write setattr append bind connect getopt setopt shutdown }') > > # > # Permissions for creating and using sockets. > # > -define(`create_socket_perms', `{ create ioctl read getattr poll write setattr append bind connect getopt setopt shutdown }') > +define(`create_socket_perms', `{ create read getattr write setattr append bind connect getopt setopt shutdown }') > > # > # Permissions for using stream sockets. > # > -define(`rw_stream_socket_perms', `{ ioctl read getattr poll write setattr append bind connect getopt setopt shutdown listen accept }') > +define(`rw_stream_socket_perms', `{ read getattr write setattr append bind connect getopt setopt shutdown listen accept }') > > # > # Permissions for creating and using stream sockets. > # > -define(`create_stream_socket_perms', `{ create ioctl read getattr poll write setattr append bind connect getopt setopt shutdown listen accept }') > +define(`create_stream_socket_perms', `{ create read getattr write setattr append bind connect getopt setopt shutdown listen accept }') > > > # > @@ -224,14 +224,9 @@ allow $3 $2:file r_file_perms; > allow $3 $2:file r_file_perms; > > # > -# Allow the new domain to execute from the program. > -# > -allow $3 $2:process execute; > - > -# > # Allow the new domain to be entered by the program. > # > -allow $3 $2:process entrypoint; > +allow $3 $2:file entrypoint; > ') > > ################################# > @@ -254,9 +249,8 @@ type_transition $1 $2:process $3; > # > define(`uses_shlib',` > allow $1 ld_so_t:file rx_file_perms; > -allow $1 ld_so_t:process execute; > -allow $1 shlib_t:file r_file_perms; > -allow $1 shlib_t:process execute; > +allow $1 ld_so_t:file execute_no_trans; > +allow $1 shlib_t:file rx_file_perms; > ') > > ################################# > @@ -268,7 +262,7 @@ allow $1 shlib_t:process execute; > # > define(`can_exec',` > allow $1 $2:file rx_file_perms; > -allow $1 $2:process execute; > +allow $1 $2:file execute_no_trans; > ') > > ################################# > diff --git a/usr/src/cmd/fmac/policy/mls b/usr/src/cmd/fmac/policy/mls > --- a/usr/src/cmd/fmac/policy/mls > +++ b/usr/src/cmd/fmac/policy/mls > @@ -62,23 +62,21 @@ level ts:nocon, noforn, nato, usuk; > > common file > { > - poll : none > - ioctl : none > + execute : read > + write : write > read : read > - write : write > + append : write > + open : read > create : write > + link : write > + unlink : write > + rename : write > getattr : read > setattr : write > lock : none > relabelfrom : { read write } > relabelto : write > transition : write > - append : write > - access : none > - unlink : write > - link : write > - rename : write > - execute : read > } > > common socket > @@ -142,6 +140,11 @@ class dir > } > > class file > +{ > + execute_no_trans : read > + entrypoint : read > +} > + > class lnk_file > class chr_file > class blk_file > @@ -211,7 +214,6 @@ class unix_stream_socket > > class process > { > - execute : read > fork : none > transition : write > sigchld : readby > @@ -224,9 +226,9 @@ class process > getsession : read > getpgid : read > setpgid : write > - getcap : read > - setcap : write > - entrypoint : read > + setexec : write > + setfscreate : write > + execsetid : none > } > > class sem > @@ -262,7 +264,6 @@ class system > arp_control : none > rarp_control : none > ipc_info : read > - avc_toggle : none > } > > class capability > diff --git a/usr/src/common/fmac/policy/flask/access_vectors b/usr/src/common/fmac/policy/flask/access_vectors > --- a/usr/src/common/fmac/policy/flask/access_vectors > +++ b/usr/src/common/fmac/policy/flask/access_vectors > @@ -36,23 +36,21 @@ > > common file > { > - poll > - ioctl > + execute > + write > read > - write > + append > + open > create > + link > + unlink > + rename > getattr > setattr > lock > relabelfrom > relabelto > transition > - append > - access > - unlink > - link > - rename > - execute > } > > > @@ -139,6 +137,10 @@ inherits file > > class file > inherits file > +{ > + execute_no_trans > + entrypoint > +} > > class lnk_file > inherits file > @@ -241,7 +243,6 @@ inherits socket > > class process > { > - execute > fork > transition > sigchld > @@ -254,9 +255,9 @@ class process > getsession > getpgid > setpgid > - getcap > - setcap > - entrypoint > + setexec > + setfscreate > + execsetid > } > > > @@ -310,7 +311,6 @@ class system > arp_control > rarp_control > ipc_info > - avc_toggle > } > > # > From Glenn.Faden at Sun.COM Thu Jul 3 13:57:37 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Thu, 03 Jul 2008 13:57:37 -0700 Subject: [fmac-discuss] RBAC and FMAC Message-ID: <486D3D41.9020305@sun.com> I have some suggestions for combining the existing Solaris RBAC architecture with the role attribute in the Flask security context. For those on this alias who are not familiar with the implementation of RBAC in SELinux, I recommend the online book Gettting Started with SELinux, http://www.linuxtopia.org/online_books/getting_started_with_SELinux/index.html . When comparing roles in Solaris and SELinux, the first difference is that roles have unique uids in Solaris, and don't in SELinux. This distinction is fundamental and particularly confusing if you are trying to work in both environments. Here are some implications of the differences. In Solaris, you can assume a role foo, using su - foo, but only if you have role foo assigned to your username. Your real and effective uids are changed to foo, and your audit ID is retained for attribution, but the audit mask is merged with that of the role. Your home directory, default privilege set, authorizations, and rights profiles are all switched to those of the role. Your label range, and network credentials are also updated. Although root can be a role, the purpose of roles is to avoid running as root. In SELinux, the su command doesn't change your role, just your uid. And the command for assuming roles, newrole(1), doesn't change your uid, just your security context. Since your uid is unchanged, your DAC attributes and privileges (or capabilties) remain the same as before assuming a role. Your new role isn't exempt from "legacy" UNIX restrictions that still require superuser. From what I've read, SELinux roles aren't particularly useful for system administration unless the user is already root before assuming the role. One way this is done is create multiple accounts with the real uid=0, and then associate the name of each such account with a unique security context. I don't see how this approach meets the requirements of audit attribution, since the identity of the real human being is not recorded. Nor is it supported, at least in Solaris, to use multiple usernames for a single uid. The primary deficiency of the current Solaris RBAC implementation is that it isn't granular enough. For example, we don't have a generic mechanism for enumerating the set of files to which a privilege like file_dac_write applies. Fixing that is one of the goals of the FGAP project, http://opensolaris.org/os/project/fgap/ , but it can also be addressed by combining the salient features of Solaris RBAC, FGAP, and SELinux roles. Here is my proposal: 1. Each defined role has both a unique uid and a unique security context. The name of the role in /etc/passwd and its name in the security context should match. 2. When assuming the role via the newrole command, all of the behavior described in the SELinux man page still occurs. See: http://linux.die.net/man/1/newrole 3. In addition, a PAM session is invoked which does essentially what the su to a role does today. The audit context, default privileges, home directory, authorizations, and rights profiles are updated. 4. A new process attribute (borrowed from the FGAP project) is set on the process credential which forces all execution to go be interpreted by the logical equivalent of pfexec. That means that privileges associated with commands defined the role's set of rights profiles are automatically applied without explicitly invoking pfexec. The details of this behavior are described in the FGAP project proposal. This is done so that roles don't need to have an effective uid of root as they do in SELinux. 5 The Flask policy for the current process security context is enforced to limit the privileges picked up by the role via the rights profile. For example, binding to specific port numbers or explicit files can be enumerated in the policy. There are a few more details to consider. The current newrole command in SELinux includes a --level option by which the sensitivity level of the role can be changed. Assuming we preserve the current implementation of labeled zones, this option will require a Trusted Path daemon to transition the process into the proper zone. Today in Trusted Extensions, this is done via tsoltjds-stripe in GNOME, but we lack a CLI equivalent. A prototype of a CLI, and an underlying door service in the global zone which handles the zone_enter (2) details, has been developed. I will encourage the developer to post this to opensolaris.org. The administrative confusion of having role attributes defined in two places should also be addressed, as well, but I'll save that for later. --Glenn From Glenn.Faden at Sun.COM Thu Jul 3 17:33:55 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Thu, 03 Jul 2008 17:33:55 -0700 Subject: [fmac-discuss] MLS and FMAC Message-ID: <486D6FF3.1040807@sun.com> I have some suggestions for combining the existing Solaris MLS architecture with the MLS attribute in the Flask security context. I want to make it clear that the MLS implementation in Solaris Trusted Extensions and FMAC can complement each other if same basic assumptions are made. First of all there is the specification of the sensitivity label. The representations for sensitivity labels differ between SELinux and Solaris. The former uses the letter s and a decimal integer to represent the sensitivity level or hierarchical classification, a colon, and one or more instances of the letter c followed by a decimal integer or a range of dot-separated integers. For example: s4:c1.c2,c4 In Trusted Extensions this would represented in configuration files as a hexadecimal string: 0x0004-08-68 Using the default label encoding file, this translates to human-readable label: CONFIDENTIAL : NEED TO KNOW We could decide to support both formats, but with appropriate GUI interfaces, this difference can be hidden from the end-user. The maximum number of compartments is configurable in both implementations. In Solaris, the current value is 256, but can be changed without breaking backward compatibility since the structure is opaque outside of the kernel. Another issue is the support for polyinstantiated directories. Solaris currently relies on zones to polyinstantiate directories like /tmp, /var/tmp, and /export. SELinux relies on a new system call, unshare(2), which creates a new namespace for a process and its descendants. For more details, see: http://marc2.theaimsgroup.com/?l=linux-kernel&m=112350785026703&w=2 The zones implementation is more generic than the unshare(2) implementation, so we don't need to implement the Linux solution in Solaris. Trusted Extensions does not currently store any labels in the underlying filesystem. FMAC requires that each file is labeled with a security context. The obvious solution is to store the current implicit MLS label that Trusted Extensions computes based on the mountpoint label into each file's security context. This would provide an added level of assurance, without introducing any incompatibility. On the other hand it doesn't provide much additional flexibility unless the mount policy restrictions currently enforced by Trusted Extensions are themselves hooked into Flask. For example, the kernel prevents any mounts that would permit writing down or reading up. It automatically converts read-write mounts to read-only if the label of the zone requesting access dominates the label of the owner of the filesystem. Flask cannot grant access to anything that is denied by the existing MAC policy. Similarly, some of the inflexible cross-zone MAC policies enforced in the trusted networking code may need to be replaced with calls into Flask. This also applies to doorfs, fifofs, and UNIX domain sockets. This leads to the question of whether the existing MAC policy enforced by Trusted Extensions should itself be disabled when Flask is disabled or running in permissive mode. In other words, should Trusted Extensions require the use of Flask? Thus far I've considered such flexibility in MLS as a weakness, but I'll leave that question open for discussion. From sds at tycho.nsa.gov Mon Jul 7 07:01:19 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 07 Jul 2008 10:01:19 -0400 Subject: [fmac-discuss] RBAC and FMAC In-Reply-To: <486D3D41.9020305@sun.com> References: <486D3D41.9020305@sun.com> Message-ID: <1215439280.27975.47.camel@moss-spartans.epoch.ncsc.mil> On Thu, 2008-07-03 at 13:57 -0700, Glenn Faden wrote: > I have some suggestions for combining the existing Solaris RBAC > architecture with the role attribute in the Flask security context. For > those on this alias who are not familiar with the implementation of RBAC > in SELinux, I recommend the online book > Gettting Started with SELinux, > http://www.linuxtopia.org/online_books/getting_started_with_SELinux/index.html Also see: http://www.nsa.gov/selinux/papers/ottawa01/index.html http://www.nsa.gov/selinux/papers/policy/policy.html http://www.nsa.gov/selinux/papers/policy2/t1.html > When comparing roles in Solaris and SELinux, the first difference is > that roles have unique uids in Solaris, and don't in SELinux. This > distinction is fundamental and particularly confusing if you are trying > to work in both environments. Here are some implications of the differences. Correct - user identity and role are separate attributes in SELinux. Users are authorized for specific roles. Further, there are actually two user identity attributes: the normal Unix uid, which continues to follow its usual behavior (e.g. changes upon su), and the SELinux user identity attribute in the security context, which is typically immutable for an entire session (depending on your policy configuration, of course) and serves to bound the set of roles that can be entered. Login-style programs perform a lookup at login time to map the Unix username to a SELinux user identity based on a "seusers" mapping, and then set the initial security context in which to execute the login shell accordingly. > In Solaris, you can assume a role foo, using su - foo, but only if you > have role foo assigned to your username. Your real and effective uids > are changed to foo, and your audit ID is retained for attribution, but > the audit mask is merged with that of the role. Your home directory, > default privilege set, authorizations, and rights profiles are all > switched to those of the role. Your label range, and network credentials > are also updated. Although root can be a role, the purpose of roles is > to avoid running as root. > > In SELinux, the su command doesn't change your role, just your uid. And > the command for assuming roles, newrole(1), doesn't change your uid, > just your security context. Since your uid is unchanged, your DAC > attributes and privileges (or capabilties) remain the same as before > assuming a role. Your new role isn't exempt from "legacy" UNIX > restrictions that still require superuser. While the role change won't elevate the effective capability set, it does alter the set of capabilities (privileges) authorized by SELinux policy (based on the domain associated with the role), which acts as a cap on the privileges of the process and its children. In terms of actually elevating privileges, we chose to make SELinux "restrictive only" in order to ensure that we didn't unwittingly make the system less secure, particularly given that we knew it would take time to bring the policy and the userland/applications up to the point where it would be safe to grant privileges directly via SELinux. > From what I've read, SELinux roles aren't particularly useful for > system administration unless the user is already root before assuming > the role. Actually, we usually do the reverse - first we assume a given role (e.g. sysadm_r) via newrole, then we invoke su or sudo in order to assume DAC privileges. If we aren't in an authorized role, then we won't even be able to execute su or sudo in the first place, or even if we can execute the binary, the privileges are bounded by what is authorized to the role's associated domain, and thus they will fail when they try to elevate privileges. > One way this is done is create multiple accounts with the real > uid=0, and then associate the name of each such account with a unique > security context. I don't see how this approach meets the requirements > of audit attribution, since the identity of the real human being is not > recorded. Nor is it supported, at least in Solaris, to use multiple > usernames for a single uid. I haven't actually seen that (creating multiple uid 0 accounts for roles) done typically - we don't create accounts for roles at all; we just map Unix users to SELinux users and then authorize SELinux users for roles in the policy. With regard to accountability/attribution, our original approach was to make the SELinux user identity an immutable form of the user identity set at login time only. Later Linux introduced a separate audit uid / loginuid specifically for audit purposes. Maintaining SELinux user identities in the kernel policy for every Unix user proved somewhat problematic given the use of network databases for users, which motivated the introduction of the seusers mapping so that we could support a many-to-one mapping from Unix users to abstract SELinux user identities defined in the policy, with one SELinux user identity per authorized role set. > The primary deficiency of the current Solaris RBAC implementation is > that it isn't granular enough. For example, we don't have a generic > mechanism for enumerating the set of files to which a privilege like > file_dac_write applies. Fixing that is one of the goals of the FGAP > project, http://opensolaris.org/os/project/fgap/ , > but it can also be addressed by combining the salient features of > Solaris RBAC, FGAP, and SELinux roles. In addition to granularity, the SELinux role/domain mechanism provides a way to directly represent and enforce privilege restrictions in the kernel policy and mechanism w/o placing as much trust in userspace programs. > Here is my proposal: > > 1. Each defined role has both a unique uid and a unique security > context. The name of the role in /etc/passwd and its name in the > security context should match. I'm not certain a unique uid is strictly required, but we can certainly start there. > 2. When assuming the role via the newrole command, all of the behavior > described in the SELinux man page still occurs. See: > http://linux.die.net/man/1/newrole > > 3. In addition, a PAM session is invoked which does essentially what > the su to a role does today. The audit context, default privileges, home > directory, authorizations, and rights profiles are updated. > > 4. A new process attribute (borrowed from the FGAP project) is set on > the process credential which forces all execution to go be interpreted > by the logical equivalent of pfexec. That means that privileges > associated with commands defined the role's set of rights profiles are > automatically applied without explicitly invoking pfexec. The details of > this behavior are described in the FGAP project proposal. This is done > so that roles don't need to have an effective uid of root as they do in > SELinux. Just to clarify, in SELinux, one simply uses whatever native Linux mechanism you would normally use in order to elevate privileges, whether setuid, file capabilities, sudo, etc. SELinux though allows one to bound the privileges based on the context and further to specifically bind specific privileges to specific programs based on domain and type. > 5 The Flask policy for the current process security context is enforced > to limit the privileges picked up by the role via the rights profile. > For example, binding to specific port numbers or explicit files can be > enumerated in the policy. This sounds consistent with what we do in SELinux. > There are a few more details to consider. The current newrole command in > SELinux includes a --level option by which the sensitivity level of the > role can be changed. Assuming we preserve the current implementation of > labeled zones, this option will require a Trusted Path daemon to > transition the process into the proper zone. Today in Trusted > Extensions, this is done via tsoltjds-stripe in GNOME, but we lack a CLI > equivalent. A prototype of a CLI, and an underlying door service in the > global zone which handles the zone_enter (2) details, has been > developed. I will encourage the developer to post this to opensolaris.org. > > The administrative confusion of having role attributes defined in two > places should also be addressed, as well, but I'll save that for later. Ok, thanks for starting this discussion. -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Mon Jul 7 07:29:43 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 07 Jul 2008 10:29:43 -0400 Subject: [fmac-discuss] MLS and FMAC In-Reply-To: <486D6FF3.1040807@sun.com> References: <486D6FF3.1040807@sun.com> Message-ID: <1215440983.27975.75.camel@moss-spartans.epoch.ncsc.mil> On Thu, 2008-07-03 at 17:33 -0700, Glenn Faden wrote: > I have some suggestions for combining the existing Solaris MLS > architecture with the MLS attribute in the Flask security context. I want to make it clear that the MLS implementation in Solaris Trusted Extensions and FMAC can complement each other if same basic assumptions are made. > > First of all there is the specification of the sensitivity label. The representations for sensitivity labels differ between SELinux and Solaris. The former uses the letter s and a decimal integer to represent the sensitivity level or hierarchical classification, a colon, and one or more instances of the letter c followed by a decimal integer or a range of dot-separated integers. For example: > > > s4:c1.c2,c4 Just to clarify, the representation above is characteristic of the modern SELinux MLS implementation and policy configuration, but is not quite characteristic of the contributed FMAC code base and example policy. The modern SELinux MLS implementation and policy configuration was contributed to SELinux as an enhancement by TCS. The contributed FMAC code base predates those changes by TCS. In both cases however, the MLS label portion of the context does take the form of: lowsensitivity[:lowcategory,...][-highsensitivity[:highcategory,...]] where the sensitivity and category names are defined in the policy configuration, and where the high level is omitted if identical to the low. In the original SELinux and FMAC example policies, the sensitivity and category names were directly specified as meaningful strings, e.g. "unclassified", "secret", "nato", etc. In the modern SELinux policy configuration, they are specified using the compact notation you mention above (e.g. "s0", "s2", "c2") and libselinux interacts with a labeling daemon in order to map to the meaningful form as well as to support the more complex label encoding schemes. > In Trusted Extensions this would represented in configuration files as a hexadecimal string: > > > 0x0004-08-68 > > Using the default label encoding file, this translates to human-readable label: > > CONFIDENTIAL : NEED TO KNOW > > > We could decide to support both formats, but with appropriate GUI > interfaces, this difference can be hidden from the end-user. The > maximum number of compartments is configurable in both > implementations. In Solaris, the current value is 256, but can be > changed without breaking backward compatibility since the structure is > opaque outside of the kernel. In the SELinux and FMAC security servers, we use an extensible bitmap structure to represent the category sets and there is no bound in the implementation on the number of categories; it is only limited by the definitions in the configuration files themselves. > Another issue is the support for polyinstantiated directories. Solaris > currently relies on zones to polyinstantiate directories > like /tmp, /var/tmp, and /export. SELinux relies on a new system call, > unshare(2), which creates a new namespace for a process and its > descendants. For more details, see: > > > http://marc2.theaimsgroup.com/?l=linux-kernel&m=112350785026703&w=2 > > The zones implementation is more generic than the unshare(2) > implementation, so we don't need to implement the Linux solution in > Solaris. FWIW, the polyinstantiated directory mechanism is not entirely satisfying, as it requires a priori set up, is relatively static, and constrains sharing more than is strictly required. So if we can improve matters there that would be a good thing I think. For example, handling of user home directories and dotfiles seems generally problematic. > Trusted Extensions does not currently store any labels in the > underlying filesystem. FMAC requires that each file is labeled with a > security context. The obvious solution is to store the current > implicit MLS label that Trusted Extensions computes based on the > mountpoint label into each file's security context. This would provide > an added level of assurance, without introducing any incompatibility. This seems overly limiting to me; we would like to be able to maintain distinct file security contexts within a single filesystem owned by a single zone, including the MLS label as well as the TE label. In SELinux, we do perform an 'associate' check between each file security context and a security context associated with the filesystem as a whole in order to bound the contexts that can exist within a given filesystem. Applying that same check between the FMAC file context and a context derived from the TX label would make sense as a way of achieving such control. > On the other hand it doesn't provide much additional flexibility > unless the mount policy restrictions currently enforced by Trusted > Extensions are themselves hooked into Flask. For example, the kernel > prevents any mounts that would permit writing down or reading up. It > automatically converts read-write mounts to read-only if the label of > the zone requesting access dominates the label of the owner of the > filesystem. Flask cannot grant access to anything that is denied by > the existing MAC policy. > > Similarly, some of the inflexible cross-zone MAC policies enforced in > the trusted networking code may need to be replaced with calls into > Flask. This also applies to doorfs, fifofs, and UNIX domain sockets. Yes, this sounds useful. > This leads to the question of whether the existing MAC policy enforced > by Trusted Extensions should itself be disabled when Flask is disabled > or running in permissive mode. In other words, should Trusted > Extensions require the use of Flask? Thus far I've considered such > flexibility in MLS as a weakness, but I'll leave that question open > for discussion. I'm not sure about "requiring" use of Flask for TX, but certainly leveraging Flask/FMAC when it is enabled makes sense. MLS solutions based on SELinux make extensive use of the TE policy as a means of confining and protecting MLS trusted subjects, providing integrity, and enforcing controlled information flows (assured pipelines) between levels; TE was actually originally designed to complement MLS in that manner during the SAT/LOCK days. -- Stephen Smalley National Security Agency From john.weeks at sun.com Tue Jul 8 08:20:40 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 08 Jul 2008 08:20:40 -0700 Subject: [fmac-discuss] [PATCH] Process SID Support Message-ID: <487385C8.2070600@sun.com> This patch adds sids to the kernel cred structure and the corresponding system calls. All processes will now default to SECINITSID_KERNEL until file system contexts are implemented. Additional FMAC permission checks are also included in this patch (see below for details). New process related system calls: #include int getcon(security_context_t *context); int getpidcon(pid_t pid, security_context_t *context); int getexeccon(security_context_t *context); int setexeccon(security_context_t context); int getprevcon(security_context_t *context); void freecon(security_context_t context); New utility: /usr/bin/pcon - Print process context usage: pcon pid ... Additional permission checks (avc_has_perm() calls) have been added to: fmacsys_setenforce fmacsys_security_load_policy fmacsys_security_compute_av fmacsys_security_check_context fmacsys_getcon fmacsys_setexeccon Webrev available at: http://cr.opensolaris.org/~jweeks/fmac-proc diff --git a/usr/src/cmd/fmac/Makefile b/usr/src/cmd/fmac/Makefile --- a/usr/src/cmd/fmac/Makefile +++ b/usr/src/cmd/fmac/Makefile @@ -31,7 +31,8 @@ SUBDIR_CMD = checkpolicy \ setfiles \ loadpolicy \ setenforce \ - getenforce + getenforce \ + pcon SUBDIR_POLICY = \ policy @@ -47,9 +48,11 @@ _msg := TARGET = _msg .KEEP_STATE: -all install line clean clobber: $(SUBDIRS) +all install lint clean clobber: $(SUBDIRS) -$(SUBDIRS): +_msg: $(SUBDIR_CMD) + +$(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET) -_msg: $(SUBDIR_CMD) +FRC: diff --git a/usr/src/cmd/fmac/pcon/Makefile b/usr/src/cmd/fmac/pcon/Makefile new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/pcon/Makefile @@ -0,0 +1,42 @@ +# +# 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= pcon + +include ../../Makefile.cmd + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTPROG) + +clean: + +lint: lint_PROG + +include ../../Makefile.targ diff --git a/usr/src/cmd/fmac/pcon/pcon.c b/usr/src/cmd/fmac/pcon/pcon.c new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/pcon/pcon.c @@ -0,0 +1,78 @@ +/* + * 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. + */ + +/* + * Display context for specified PIDs + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void +show_context(const char *arg) +{ + pid_t pid; + security_context_t context; + char *endptr = 0; + + errno = 0; + + pid = strtoul(arg, &endptr, 10); + + if (endptr == arg || *endptr != '\0' || errno || pid < 0) + return; + + if (getpidcon(pid, &context) == 0) { + (void) printf("%ld: %s\n", pid, context); + freecon(context); + } +} + +int +main(int argc, char *argv[]) +{ + (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); + + if (argc <= 1) { + (void) fprintf(stderr, gettext("usage: pcon pid ...\n")); + return (1); + } + + while (--argc >= 1) + show_context(*++argv); + + return (0); +} diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c --- a/usr/src/cmd/truss/systable.c +++ b/usr/src/cmd/truss/systable.c @@ -846,6 +846,10 @@ const struct systable fmacsystable[] = { {"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 */ +{"getcon", 2, DEC, NOV, HID, HEX}, /* 6 */ +{"getpidcon", 3, DEC, NOV, HID, DEC, HEX}, /* 7 */ +{"getexeccon", 2, DEC, NOV, HID, HEX}, /* 8 */ +{"setexeccon", 2, DEC, NOV, HID, STG}, /* 9 */ }; #define NFMACSYSCODE (sizeof (fmacsystable) / sizeof (struct systable)) @@ -1012,6 +1016,10 @@ const struct sysalias sysalias[] = { { "is_fmac_enabled ", SYS_fmacsys }, { "security_compute_av", SYS_fmacsys }, { "security_check_context", SYS_fmacsys }, + { "getcon", SYS_fmacsys }, + { "getpidcon", SYS_fmacsys }, + { "getexeccon", SYS_fmacsys }, + { "setexeccon", SYS_fmacsys }, { NULL, 0 } /* end-of-list */ }; diff --git a/usr/src/common/fmac/policy/flask/access_vectors b/usr/src/common/fmac/policy/flask/access_vectors --- a/usr/src/common/fmac/policy/flask/access_vectors +++ b/usr/src/common/fmac/policy/flask/access_vectors @@ -255,6 +255,7 @@ class process getsession getpgid setpgid + getattr setexec setfscreate execsetid diff --git a/usr/src/head/fmac/fmac.h b/usr/src/head/fmac/fmac.h --- a/usr/src/head/fmac/fmac.h +++ b/usr/src/head/fmac/fmac.h @@ -35,6 +35,7 @@ extern "C" { extern "C" { #endif +#include #include #include @@ -44,10 +45,16 @@ int security_compute_av(security_context 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_check_context(security_context_t context); int security_getenforce(void); int security_setenforce(int mode); int is_fmac_enabled(void); +int getcon(security_context_t *context); +int getpidcon(pid_t pid, security_context_t *context); +int getexeccon(security_context_t *context); +int setexeccon(security_context_t context); +int getprevcon(security_context_t *context); +void freecon(security_context_t context); #ifdef __cplusplus } diff --git a/usr/src/lib/libc/inc/synonyms.h b/usr/src/lib/libc/inc/synonyms.h --- a/usr/src/lib/libc/inc/synonyms.h +++ b/usr/src/lib/libc/inc/synonyms.h @@ -386,6 +386,7 @@ extern "C" { #define gconvert _gconvert #define gcvt _gcvt #define getacct _getacct +#define getcon _getcon #define getcontext _getcontext #define getcpuid _getcpuid #define getcwd _getcwd @@ -394,6 +395,7 @@ extern "C" { #define getdents _getdents #define getegid _getegid #define geteuid _geteuid +#define getexeccon _getexeccon #define getexecname _getexecname #define getextmntent _getextmntent #define getgid _getgid @@ -427,8 +429,10 @@ extern "C" { #define getpgid _getpgid #define getpgrp _getpgrp #define getpid _getpid +#define getpidcon _getpidcon #define getpmsg _getpmsg #define getppid _getppid +#define getprevcon _getprevcon #define getppriv _getppriv #define getprivimplinfo _getprivimplinfo #define getprojid _getprojid @@ -919,6 +923,7 @@ extern "C" { #define setegid _setegid #define setenv _setenv #define seteuid _seteuid +#define setexeccon _setexeccon #define setgid _setgid #define setgrent _setgrent #define setgroups _setgroups diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -67,11 +67,16 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11) fgetattr; forkallx; forkx; + freecon; fsetattr; getattrat; + getcon; + getexeccon; _getpagesizes; getpagesizes2; _getpagesizes2; + getpidcon; + getprevcon; htonl; htons; is_fmac_enabled; @@ -124,6 +129,7 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11) sem_unlink; sem_wait; setattrat; + setexeccon; _sharefs; shm_open; shm_unlink; diff --git a/usr/src/lib/libc/port/sys/fmacsys.c b/usr/src/lib/libc/port/sys/fmacsys.c --- a/usr/src/lib/libc/port/sys/fmacsys.c +++ b/usr/src/lib/libc/port/sys/fmacsys.c @@ -30,11 +30,20 @@ #pragma weak security_getenforce = _security_getenforce #pragma weak security_setenforce = _security_setenforce #pragma weak is_fmac_enabled = _is_fmac_enabled +#pragma weak getcon = _getcon +#pragma weak getpidcon = _getpidcon +#pragma weak getexeccon = _getexeccon +#pragma weak setexeccon = _setexeccon +#pragma weak getprevcon = _getprevcon #include "synonyms.h" #include #include +#include #include +#include +#include +#include int security_load_policy(char *path) @@ -51,9 +60,9 @@ security_compute_av(security_context_t s } int -security_check_context(security_context_t scontext) +security_check_context(security_context_t context) { - return (syscall(SYS_fmacsys, FMACSYS_SECURITYCHECKCONTEXT, scontext)); + return (syscall(SYS_fmacsys, FMACSYS_SECURITYCHECKCONTEXT, context)); } int @@ -73,3 +82,121 @@ is_fmac_enabled() { return (syscall(SYS_fmacsys, FMACSYS_ISFMACENABLED)); } + +int +getcon(security_context_t *context) +{ + security_context_t acontext; + security_context_t dcontext; + + if (context == NULL) { + errno = EINVAL; + return (-1); + } + + acontext = alloca(FMAC_MAX_CONTEXT_LEN); + + if (syscall(SYS_fmacsys, FMACSYS_GETCON, acontext) < 0) { + return (-1); + } + + if (dcontext=strdup(acontext)) { + *context = dcontext; + return (0); + } else + return (-1); +} + +int +getpidcon(pid_t pid, security_context_t *context) +{ + security_context_t acontext; + security_context_t dcontext; + + if (context == NULL) { + errno = EINVAL; + return (-1); + } + + acontext = alloca(FMAC_MAX_CONTEXT_LEN); + + if (syscall(SYS_fmacsys, FMACSYS_GETPIDCON, pid, acontext) < 0) { + return (-1); + } + + if (dcontext=strdup(acontext)) { + *context = dcontext; + return (0); + } else + return (-1); +} + +int +getexeccon(security_context_t *context) +{ + security_context_t acontext; + security_context_t dcontext; + + if (context == NULL) { + errno = EINVAL; + return (-1); + } + + acontext = alloca(FMAC_MAX_CONTEXT_LEN); + + if (syscall(SYS_fmacsys, FMACSYS_GETEXECCON, acontext) < 0) { + return (-1); + } + + if (*acontext == 0) { + *context = 0; + return (0); + } + + if (dcontext=strdup(acontext)) { + *context = dcontext; + return (0); + } else + return (-1); +} + +int +setexeccon(security_context_t context) +{ + return (syscall(SYS_fmacsys, FMACSYS_SETEXECCON, context)); +} + +int +getprevcon(security_context_t *context) +{ + security_context_t acontext; + security_context_t dcontext; + + if (context == NULL) { + errno = EINVAL; + return (-1); + } + + acontext = alloca(FMAC_MAX_CONTEXT_LEN); + + if (syscall(SYS_fmacsys, FMACSYS_GETPREVCON, acontext) < 0) { + return (-1); + } + + if (*acontext == 0) { + *context = 0; + return (0); + } + + if (dcontext=strdup(acontext)) { + *context = dcontext; + return (0); + } else + return (-1); +} + +void +freecon(security_context_t context) +{ + free(context); +} diff --git a/usr/src/pkgdefs/SUNWesu/prototype_com b/usr/src/pkgdefs/SUNWesu/prototype_com --- a/usr/src/pkgdefs/SUNWesu/prototype_com +++ b/usr/src/pkgdefs/SUNWesu/prototype_com @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -83,6 +83,7 @@ l none usr/bin/pargs=../../usr/lib/isaex l none usr/bin/pargs=../../usr/lib/isaexec f none usr/bin/paste 555 root bin s none usr/bin/pcat=./unpack +f none usr/bin/pcon 555 root bin l none usr/bin/pcred=../../usr/lib/isaexec l none usr/bin/pfiles=../../usr/lib/isaexec l none usr/bin/pflags=../../usr/lib/isaexec diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c --- a/usr/src/uts/common/os/cred.c +++ b/usr/src/uts/common/os/cred.c @@ -64,6 +64,7 @@ #include #include #include +#include /* Ephemeral IDs Zones specific data */ @@ -196,6 +197,10 @@ cred_init(void) dummycr->cr_suid = (uid_t)-1; dummycr->cr_sgid = (gid_t)-1; + dummycr->cr_secid = SECSID_NULL; + dummycr->cr_exec_secid = SECSID_NULL; + dummycr->cr_prev_secid = SECSID_NULL; + /* * kcred is used by anything that needs all privileges; it's @@ -224,6 +229,8 @@ cred_init(void) CR_EPRIV(kcred) = CR_PPRIV(kcred) = CR_IPRIV(kcred); CR_FLAGS(kcred) = NET_MAC_AWARE; + + kcred->cr_secid = SECINITSID_KERNEL; /* * Set up credentials of p0. @@ -685,6 +692,46 @@ crgetprojid(const cred_t *cr) crgetprojid(const cred_t *cr) { return (cr->cr_projid); +} + +security_id_t +crgetsecid(cred_t *cr) +{ + return (cr->cr_secid); +} + +void +crsetsecid(cred_t *cr, security_id_t sid) +{ + ASSERT(cr->cr_ref <= 2); + + cr->cr_secid = sid; +} + +security_id_t +crgetexecsecid(cred_t *cr) +{ + return (cr->cr_exec_secid); +} + +void +crsetexecsecid(cred_t *cr, security_id_t sid) +{ + ASSERT(cr->cr_ref <= 2); + + cr->cr_exec_secid = sid; +} + +security_id_t +crgetprevsecid(cred_t *cr) +{ + return (cr->cr_prev_secid); +} + +void +crsetprevsecid(cred_t *cr, security_id_t sid) +{ + cr->cr_prev_secid = sid; } zone_t * diff --git a/usr/src/uts/common/sys/cred.h b/usr/src/uts/common/sys/cred.h --- a/usr/src/uts/common/sys/cred.h +++ b/usr/src/uts/common/sys/cred.h @@ -37,6 +37,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include +#include #ifdef __cplusplus extern "C" { @@ -135,6 +136,16 @@ extern void crsetprojid(cred_t *, projid extern void crsetprojid(cred_t *, projid_t); /* + * Private interfaces for getting and setting security identifiers. + */ +extern security_id_t crgetsecid(cred_t *); +extern void crsetsecid(cred_t *, security_id_t); +extern security_id_t crgetexecsecid(cred_t *); +extern void crsetexecsecid(cred_t *, security_id_t); +extern security_id_t crgetprevsecid(cred_t *); +extern void crsetprevsecid(cred_t *, security_id_t); + +/* * Private interface for nfs. */ extern cred_t *crnetadjust(cred_t *); diff --git a/usr/src/uts/common/sys/cred_impl.h b/usr/src/uts/common/sys/cred_impl.h --- a/usr/src/uts/common/sys/cred_impl.h +++ b/usr/src/uts/common/sys/cred_impl.h @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -76,6 +77,9 @@ struct cred { gid_t cr_sgid; /* "saved" group id (from exec) */ uint_t cr_ngroups; /* number of groups returned by */ /* crgroups() */ + security_id_t cr_secid; /* security identifier */ + security_id_t cr_exec_secid; /* exec security identifier */ + security_id_t cr_prev_secid; /* previous security identifier */ cred_priv_t cr_priv; /* privileges */ projid_t cr_projid; /* project */ struct zone *cr_zone; /* pointer to per-zone structure */ diff --git a/usr/src/uts/common/sys/fmac/fmac.h b/usr/src/uts/common/sys/fmac/fmac.h --- a/usr/src/uts/common/sys/fmac/fmac.h +++ b/usr/src/uts/common/sys/fmac/fmac.h @@ -56,12 +56,13 @@ extern "C" { #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 +#define FMACSYS_GETPREVCON 10 +#define FMACSYS_GETFILECON 11 +#define FMACSYS_SETFILECON 12 +#define FMACSYS_LGETFILECON 13 +#define FMACSYS_LSETFILECON 14 +#define FMACSYS_FGETFILECON 15 +#define FMACSYS_FSETFILECON 16 #if defined(_KERNEL) extern int fmac_enabled; diff --git a/usr/src/uts/common/syscall/fmacsys.c b/usr/src/uts/common/syscall/fmacsys.c --- a/usr/src/uts/common/syscall/fmacsys.c +++ b/usr/src/uts/common/syscall/fmacsys.c @@ -55,14 +55,12 @@ fmacsys_setenforce(int mode) { int err = 0; - if (!INGLOBALZONE(curproc)) { - err = EINVAL; - goto done; - } + if (!INGLOBALZONE(curproc)) + return (set_errno(EINVAL)); - /* 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; + if (err = avc_has_perm(crgetsecid(CRED()), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__SETENFORCE)) + return (set_errno(err)); switch (mode) { @@ -77,7 +75,7 @@ fmacsys_setenforce(int mode) break; } -done: +out: if (err) return (set_errno(err)); else @@ -90,28 +88,19 @@ fmacsys_security_load_policy(char *path) char *kpath = 0; int err; - if (!INGLOBALZONE(curproc)) { - err = EINVAL; - goto done; - } + if (!INGLOBALZONE(curproc)) + return (set_errno(EINVAL)); - /* - * 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; + if (err = avc_has_perm(crgetsecid(CRED()), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__LOAD_POLICY)) + return (set_errno(err)); kpath = kmem_alloc(MAXPATHLEN, KM_SLEEP); - if ((err = copyinstr(path, kpath, MAXPATHLEN, NULL)) != 0) - goto done; + if ((err = copyinstr(path, kpath, MAXPATHLEN, NULL)) == 0) + err = fmac_load_policy(kpath); - - err = fmac_load_policy(kpath); -done: - if (kpath) - kmem_free(kpath, MAXPATHLEN); + kmem_free(kpath, MAXPATHLEN); if (err) return (set_errno(err)); @@ -146,32 +135,36 @@ fmacsys_security_compute_av( size_t tlen; int err; + if (err = avc_has_perm(crgetsecid(CRED()), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__COMPUTE_AV)) + return (set_errno(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; + goto out; if ((err = copyinstr(tcontext, ktcontext, FMAC_MAX_CONTEXT_LEN, &tlen)) != 0) - goto done; + goto out; if ((err = security_context_to_sid(kscontext, slen, &ssid))) - goto done; + goto out; if ((err = security_context_to_sid(ktcontext, tlen, &tsid))) - goto done; + goto out; if ((err = security_compute_av(ssid, tsid, tclass, request, &kavd))) - goto done; + goto out; if (copyout(&kavd, avd, sizeof (struct av_decision))) { err = EFAULT; - goto done; + goto out; } -done: +out: kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); kmem_free(ktcontext, FMAC_MAX_CONTEXT_LEN); @@ -189,16 +182,16 @@ fmacsys_security_check_context(security_ size_t slen; int err; + if (err = avc_has_perm(crgetsecid(CRED()), SECINITSID_SECURITY, + SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT)) + return (set_errno(err)); + kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); if ((err = copyinstr(scontext, kscontext, FMAC_MAX_CONTEXT_LEN, - &slen)) != 0) - goto done; + &slen)) == 0) + err = security_context_to_sid(kscontext, slen, &ssid); - if ((err = security_context_to_sid(kscontext, slen, &ssid))) - goto done; - -done: kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); if (err) @@ -210,25 +203,155 @@ static int static int fmacsys_getcon(pid_t pid, security_context_t scontext) { - _NOTE(ARGUNUSED(pid, scontext)); + security_context_t pcontext; + uint32_t pcontext_len; + security_id_t sid; + proc_t *p; + int err = 0; - return (set_errno(ENOSYS)); + if (pid == P_MYID) { + sid = crgetsecid(CRED()); + } else { + mutex_enter(&pidlock); + if ((p = prfind(pid)) == NULL || + (secpolicy_basic_procinfo(CRED(), p, curproc) != 0)) { + mutex_exit(&pidlock); + return (set_errno(ESRCH)); + } + mutex_enter(&p->p_lock); + mutex_exit(&pidlock); + mutex_enter(&p->p_crlock); + sid = crgetsecid(p->p_cred); + mutex_exit(&p->p_crlock); + mutex_exit(&p->p_lock); + } + + if (err = avc_has_perm(crgetsecid(CRED()), sid, SECCLASS_PROCESS, + PROCESS__GETATTR)) + return (set_errno(err)); + + if ((err = security_sid_to_context(sid, &pcontext, + &pcontext_len)) == 0) { + if (copyout(pcontext, scontext, pcontext_len)) + err = EFAULT; + security_context_free(pcontext); + } + + if (err) + return (set_errno(err)); + else + return (0); } static int fmacsys_getexeccon(security_context_t scontext) { - _NOTE(ARGUNUSED(scontext)); + security_context_t pcontext; + uint32_t pcontext_len; + int err = 0; - return (set_errno(ENOSYS)); + /* If exec context not set, return null string */ + if (crgetexecsecid(CRED()) == SECSID_NULL) { + if (subyte(scontext, 0) < 0) + return (set_errno(EFAULT)); + else + return (0); + } + + if (err = security_sid_to_context(crgetexecsecid(CRED()), &pcontext, + &pcontext_len)) + return (set_errno(err)); + + if (copyout(pcontext, scontext, pcontext_len)) + err = EFAULT; + + security_context_free(pcontext); + + if (err) + return (set_errno(err)); + else + return (0); } static int fmacsys_setexeccon(security_context_t scontext) { - _NOTE(ARGUNUSED(scontext)); + security_context_t kscontext; + security_id_t sid; + size_t slen; + proc_t *p; + cred_t *cr; + cred_t *newcr; + int err; - return (set_errno(ENOSYS)); + if (err = avc_has_perm(crgetsecid(CRED()), crgetsecid(CRED()), + SECCLASS_PROCESS, PROCESS__SETEXEC)) + return (set_errno(err)); + + if (scontext == 0) { + sid = SECSID_NULL; + } else { + + kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + + err = copyinstr(scontext, kscontext, FMAC_MAX_CONTEXT_LEN, + &slen); + + if (!err) + err = security_context_to_sid(kscontext, slen, &sid); + + kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); + + if (err) + return (set_errno(err)); + } + + newcr = cralloc_ksid(); + p = ttoproc(curthread); + mutex_enter(&p->p_crlock); + cr = p->p_cred; + crdup_to(cr, newcr); + crsetexecsecid(newcr, sid); + p->p_cred = newcr; + crhold(newcr); + crfree(cr); + mutex_exit(&p->p_crlock); + crset(p, newcr); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_getprevcon(security_context_t scontext) +{ + security_context_t pcontext; + uint32_t pcontext_len; + int err = 0; + + /* If previous context not set, return null string */ + if (crgetexecsecid(CRED()) == SECSID_NULL) { + if (subyte(scontext, 0) < 0) + return (set_errno(EFAULT)); + else + return (0); + } + + if (err = security_sid_to_context(crgetprevsecid(CRED()), &pcontext, + &pcontext_len)) + return (set_errno(err)); + + if (copyout(pcontext, scontext, pcontext_len)) + err = EFAULT; + + security_context_free(pcontext); + + if (err) + return (set_errno(err)); + else + return (0); } static int @@ -287,7 +410,7 @@ fmacsys(int op, void *a1, void *a2, void if (!fmac_enabled) return (set_errno(ENOSYS)); - + switch (op) { case FMACSYS_SECURITYGETENFORCE: return (fmacsys_getenforce()); @@ -304,7 +427,7 @@ fmacsys(int op, void *a1, void *a2, void 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)); + return (fmacsys_getcon(P_MYID, (security_context_t)a1)); case FMACSYS_GETPIDCON: return (fmacsys_getcon((pid_t)(uintptr_t)a1, (security_context_t)a2)); @@ -312,6 +435,8 @@ fmacsys(int op, void *a1, void *a2, void return (fmacsys_getexeccon((security_context_t)a1)); case FMACSYS_SETEXECCON: return (fmacsys_setexeccon((security_context_t)a1)); + case FMACSYS_GETPREVCON: + return (fmacsys_getprevcon((security_context_t)a1)); case FMACSYS_GETFILECON: return (fmacsys_getfilecon((char *)a1, (security_context_t)a2)); case FMACSYS_SETFILECON: @@ -329,7 +454,7 @@ fmacsys(int op, void *a1, void *a2, void return (fmacsys_fsetfilecon((int)(uintptr_t)a1, (security_context_t)a2)); default: - return (ENOSYS); + return (set_errno(ENOSYS)); } /* NOTREACHED */ } -John From darrenm at opensolaris.org Tue Jul 8 09:12:07 2008 From: darrenm at opensolaris.org (Darren J Moffat) Date: Tue, 08 Jul 2008 17:12:07 +0100 Subject: [fmac-discuss] [PATCH] Process SID Support In-Reply-To: <487385C8.2070600@sun.com> References: <487385C8.2070600@sun.com> Message-ID: <487391D7.1070704@opensolaris.org> John Weeks wrote: > This patch adds sids to the kernel cred structure and the corresponding system calls. All processes will now default to SECINITSID_KERNEL until file system contexts are implemented. I've not looked at the patch but that isn't really relevant to my comment. When I saw SID support I was surprised because we already have SID support in Solaris for CIFS/ZFS. But then that SID and this SID are different. Just a comment on the clashing terminology in this area. -- Darren J Moffat From john.weeks at sun.com Tue Jul 8 09:24:06 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 08 Jul 2008 09:24:06 -0700 Subject: [fmac-discuss] [PATCH] Process SID Support In-Reply-To: <487391D7.1070704@opensolaris.org> References: <487385C8.2070600@sun.com> <487391D7.1070704@opensolaris.org> Message-ID: <487394A6.1070006@sun.com> Darren J Moffat wrote: > John Weeks wrote: >> This patch adds sids to the kernel cred structure and the corresponding system calls. All processes will now default to SECINITSID_KERNEL until file system contexts are implemented. > > > I've not looked at the patch but that isn't really relevant to my comment. > > When I saw SID support I was surprised because we already have SID > support in Solaris for CIFS/ZFS. But then that SID and this SID are > different. Just a comment on the clashing terminology in this area. > Good point Darren. I would have used security identifier, but then the subject line gets longer. To help differentiate FMAC SIDs in the code, we are using secid for structure members. -John From Glenn.Faden at Sun.COM Tue Jul 8 12:11:34 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Tue, 08 Jul 2008 12:11:34 -0700 Subject: [fmac-discuss] MLS and FMAC In-Reply-To: <1215440983.27975.75.camel@moss-spartans.epoch.ncsc.mil> References: <486D6FF3.1040807@sun.com> <1215440983.27975.75.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <4873BBE6.9050803@sun.com> Stephen Smalley wrote: > On Thu, 2008-07-03 at 17:33 -0700, Glenn Faden wrote: > > > > In the SELinux and FMAC security servers, we use an extensible bitmap > structure to represent the category sets and there is no bound in the > implementation on the number of categories; it is only limited by the > definitions in the configuration files themselves. > I think the key point is that MLS labels are already defined in existing TX databases for users, zones, and network templates. So some kind of compatibility and/or migration strategy needs to be developed to deal with any MLS labels specified in FMAC policy files. > > > FWIW, the polyinstantiated directory mechanism is not entirely > satisfying, as it requires a priori set up, is relatively static, and > constrains sharing more than is strictly required. So if we can improve > matters there that would be a good thing I think. For example, handling > of user home directories and dotfiles seems generally problematic. > In an earlier prototype of Trusted Extensions I implemented multilevel directories via a special autofs trigger, /zone, which was similar to /net except that it used zonenames instead of hostnames. However, this was abandoned because it's not permitted to share NFS mounts done in the global zone with non-global zones. It also is not currently possible for non-global zones to be NFS servers. So we express valid cross-zone mounts (which provide read-only access) using global-zone relative pathnames. It works, should be improved. > >> Trusted Extensions does not currently store any labels in the >> underlying filesystem. FMAC requires that each file is labeled with a >> security context. The obvious solution is to store the current >> implicit MLS label that Trusted Extensions computes based on the >> mountpoint label into each file's security context. This would provide >> an added level of assurance, without introducing any incompatibility. >> > > This seems overly limiting to me; we would like to be able to maintain > distinct file security contexts within a single filesystem owned by a > single zone, including the MLS label as well as the TE label. > > In SELinux, we do perform an 'associate' check between each file > security context and a security context associated with the filesystem > as a whole in order to bound the contexts that can exist within a given > filesystem. Applying that same check between the FMAC file context and > a context derived from the TX label would make sense as a way of > achieving such control. > I view this MLS restriction as a part of a phased development plan. In the first step we would add Flask support to Solaris, but the current MLS behavior would be preserved. In other words, the Flask policy for MLS would be either unspecified, or matching what is currently done in TX. So the MLS components of the file context (if present) would match what is currently returned by getlabel(1). In a subsequent step, the MLS constraint of the mount policy for shared file systems (via NFS, LOFS, or CIFS) would be specified in the policy so that specified shares could be mounted read-write if they had properly labeled file contexts. This assumes that the open(2) system calls Flask to enforce MLS contraints based on those file contexts. At that point the getlabel(1) command would be returning the value from the file context, if present. This flexibility would also make it possible to have file labels that don't correspond to existing zone labels. So labeled zones would only be needed for subjects, not objects. During the development process we should ensure that new features don't compromise existing ones, and that the system reverts to safe behavior when features are disabled. For example, the default policy for TX cross-zone mounts would revert to read-only if FMAC were disabled. --Glenn From sds at tycho.nsa.gov Thu Jul 10 07:44:41 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Thu, 10 Jul 2008 10:44:41 -0400 Subject: [fmac-discuss] [PATCH] Process SID Support In-Reply-To: <487385C8.2070600@sun.com> References: <487385C8.2070600@sun.com> Message-ID: <1215701081.31554.57.camel@moss-spartans.epoch.ncsc.mil> On Tue, 2008-07-08 at 08:20 -0700, John Weeks wrote: > This patch adds sids to the kernel cred structure and the corresponding system calls. All processes will now default to SECINITSID_KERNEL until file system contexts are implemented. > > Additional FMAC permission checks are also included in this patch (see below for details). > > New process related system calls: > > #include > int getcon(security_context_t *context); > int getpidcon(pid_t pid, security_context_t *context); > int getexeccon(security_context_t *context); > int setexeccon(security_context_t context); > int getprevcon(security_context_t *context); > void freecon(security_context_t context); > > New utility: > > /usr/bin/pcon - Print process context > > usage: pcon pid ... > > Additional permission checks (avc_has_perm() calls) have been added to: > > fmacsys_setenforce > fmacsys_security_load_policy > fmacsys_security_compute_av > fmacsys_security_check_context > fmacsys_getcon > fmacsys_setexeccon > > Webrev available at: http://cr.opensolaris.org/~jweeks/fmac-proc Looks good to me, but we'd certainly benefit from others on this alias reviewing the code and sanity checking that the technical approach is sound and won't present any problems for later integrating this code into the onnv repo when we get to that stage. Acked-by: Stephen Smalley -- Stephen Smalley National Security Agency From john.weeks at sun.com Wed Jul 16 06:30:36 2008 From: john.weeks at sun.com (John Weeks) Date: Wed, 16 Jul 2008 06:30:36 -0700 Subject: [fmac-discuss] [PATCH] truss missing getprevcon and other fixes Message-ID: <487DF7FC.2090106@sun.com> This patch adds getprevcon to truss that was missed when the system call was integrated. The argument format type for system calls that return context strings should have been specified as a return string (RST) rather than HEX. -John diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c --- a/usr/src/cmd/truss/systable.c +++ b/usr/src/cmd/truss/systable.c @@ -846,10 +846,11 @@ const struct systable fmacsystable[] = { {"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 */ -{"getcon", 2, DEC, NOV, HID, HEX}, /* 6 */ -{"getpidcon", 3, DEC, NOV, HID, DEC, HEX}, /* 7 */ -{"getexeccon", 2, DEC, NOV, HID, HEX}, /* 8 */ +{"getcon", 2, DEC, NOV, HID, RST}, /* 6 */ +{"getpidcon", 3, DEC, NOV, HID, DEC, RST}, /* 7 */ +{"getexeccon", 2, DEC, NOV, HID, RST}, /* 8 */ {"setexeccon", 2, DEC, NOV, HID, STG}, /* 9 */ +{"getprevcon", 2, DEC, NOV, HID, RST}, /* 10 */ }; #define NFMACSYSCODE (sizeof (fmacsystable) / sizeof (struct systable)) @@ -1013,13 +1014,14 @@ const struct sysalias sysalias[] = { { "security_getenforce", SYS_fmacsys }, { "security_setenforce", SYS_fmacsys }, { "security_load_policy", SYS_fmacsys }, - { "is_fmac_enabled ", SYS_fmacsys }, + { "is_fmac_enabled", SYS_fmacsys }, { "security_compute_av", SYS_fmacsys }, { "security_check_context", SYS_fmacsys }, { "getcon", SYS_fmacsys }, { "getpidcon", SYS_fmacsys }, { "getexeccon", SYS_fmacsys }, { "setexeccon", SYS_fmacsys }, + { "getprevcon", SYS_fmacsys }, { NULL, 0 } /* end-of-list */ }; From sds at tycho.nsa.gov Wed Jul 16 06:49:31 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Wed, 16 Jul 2008 09:49:31 -0400 Subject: [fmac-discuss] [PATCH] truss missing getprevcon and other fixes In-Reply-To: <487DF7FC.2090106@sun.com> References: <487DF7FC.2090106@sun.com> Message-ID: <1216216171.17602.113.camel@moss-spartans.epoch.ncsc.mil> On Wed, 2008-07-16 at 06:30 -0700, John Weeks wrote: > This patch adds getprevcon to truss that was missed when the system call was integrated. The argument format type for system calls that return context strings should have been specified as a return string (RST) rather than HEX. > > -John Acked-by: Stephen Smalley > > > diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c > --- a/usr/src/cmd/truss/systable.c > +++ b/usr/src/cmd/truss/systable.c > @@ -846,10 +846,11 @@ const struct systable fmacsystable[] = { > {"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 */ > -{"getcon", 2, DEC, NOV, HID, HEX}, /* 6 */ > -{"getpidcon", 3, DEC, NOV, HID, DEC, HEX}, /* 7 */ > -{"getexeccon", 2, DEC, NOV, HID, HEX}, /* 8 */ > +{"getcon", 2, DEC, NOV, HID, RST}, /* 6 */ > +{"getpidcon", 3, DEC, NOV, HID, DEC, RST}, /* 7 */ > +{"getexeccon", 2, DEC, NOV, HID, RST}, /* 8 */ > {"setexeccon", 2, DEC, NOV, HID, STG}, /* 9 */ > +{"getprevcon", 2, DEC, NOV, HID, RST}, /* 10 */ > }; > #define NFMACSYSCODE (sizeof (fmacsystable) / sizeof (struct systable)) > > @@ -1013,13 +1014,14 @@ const struct sysalias sysalias[] = { > { "security_getenforce", SYS_fmacsys }, > { "security_setenforce", SYS_fmacsys }, > { "security_load_policy", SYS_fmacsys }, > - { "is_fmac_enabled ", SYS_fmacsys }, > + { "is_fmac_enabled", SYS_fmacsys }, > { "security_compute_av", SYS_fmacsys }, > { "security_check_context", SYS_fmacsys }, > { "getcon", SYS_fmacsys }, > { "getpidcon", SYS_fmacsys }, > { "getexeccon", SYS_fmacsys }, > { "setexeccon", SYS_fmacsys }, > + { "getprevcon", SYS_fmacsys }, > { NULL, 0 } /* end-of-list */ > }; > > _______________________________________________ > fmac-discuss mailing list > fmac-discuss at opensolaris.org > http://mail.opensolaris.org/mailman/listinfo/fmac-discuss -- Stephen Smalley National Security Agency From Pedro.Molleda at Sun.COM Sun Jul 20 12:14:11 2008 From: Pedro.Molleda at Sun.COM (Pedro Molleda) Date: Sun, 20 Jul 2008 21:14:11 +0200 Subject: [fmac-discuss] Pedro Molleda Message-ID: <48838E83.2000103@sun.com> Hello, my name is Pedro Molleda and I work for Sun Microsystems Luxembourg as a contractor. Actually I am working onsite at the EIB (European Investement Bank) giving JES support, mainly Sun Java System Messaging Server, Sun Java System Calendar Server and Sun Java System Directory Server. I also have some technicall expertise with Sun Java System Access Manager and Sun Java System Portal Server I acquiered during my period as a Customer Face Engineer at Sun Microsystems Iberica in Madrid. I have always been interested in the security world,this is why my career path at university was always focused on this subject and how OS works, spending hours and hours of my free time trying to learn about this exciting area, this is why when I first heard about the FMAC project reading Mr Schwartz's blog I inmediateli knew I wanted to help. To be honest with you I am not a guru in any area of software or system but I think that the enthusiasm and passion to learn new things can thwart this initial disadvantage. If you give me an oportunity I can guarantee you that I will not dissapoint you, I really want to help and be involved in this new "adventure" worrking has hard as needed to achieve any goal or task you give me. I can begin if you need with translations, I am a native French and Spanish speaker. Please let me know if I can be of any help and do not hesitate to contact me if you have any questions or need more info about me. Sincerely, Pedro Molleda From alan.duboff at sun.com Sun Jul 20 14:32:50 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Sun, 20 Jul 2008 14:32:50 -0700 (PDT) Subject: [fmac-discuss] Pedro Molleda In-Reply-To: <48838E83.2000103@sun.com> References: <48838E83.2000103@sun.com> Message-ID: On Sun, 20 Jul 2008, Pedro Molleda wrote: > Hello, > > my name is Pedro Molleda and I work for Sun Microsystems Luxembourg as a > contractor. Welcome to FMAC. > If you give me an oportunity I can guarantee you that I will not > dissapoint you, I really want to help and be involved in this new > "adventure" worrking has hard as needed to achieve any goal or task you > give me. > I can begin if you need with translations, I am a native French and > Spanish speaker. I think that would be helpful, I know that Cathleen Reiher recently did a couple man pages, which are most likely in english. A spanish and/or french version would certainly be welcome. If you're not familiar with cloning a mercurial repository, that would be something to learn, since you'll need to be able to pull the sources from the repository using hg. See this page for more info: http://www.opensolaris.org/os/project/fmac/contribute/ -- Alan DuBoff - Solaris x86 IHV/OEM Group From john.weeks at sun.com Thu Jul 24 18:14:25 2008 From: john.weeks at sun.com (John Weeks) Date: Thu, 24 Jul 2008 18:14:25 -0700 Subject: [fmac-discuss] [PATCH] typo in truss for security_getenforce/setenforce Message-ID: <488928F1.9010103@sun.com> security_getenforce/setenforce shouldn't have an underscore between the get/set and the enforce. -John diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c --- a/usr/src/cmd/truss/systable.c +++ b/usr/src/cmd/truss/systable.c @@ -840,8 +840,8 @@ const struct systable sidsystable[] = { #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_getenforce", 1, DEC, NOV, HID}, /* 0 */ +{"security_setenforce", 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 */ From stephen.smalley at gmail.com Thu Jul 24 19:11:53 2008 From: stephen.smalley at gmail.com (Stephen Smalley) Date: Thu, 24 Jul 2008 22:11:53 -0400 Subject: [fmac-discuss] [PATCH] typo in truss for security_getenforce/setenforce In-Reply-To: <488928F1.9010103@sun.com> References: <488928F1.9010103@sun.com> Message-ID: <1216951926.5185.39.camel@sulphur> On Thu, 2008-07-24 at 18:14 -0700, John Weeks wrote: > security_getenforce/setenforce shouldn't have an underscore between the > get/set and the enforce. Acked-by: Stephen Smalley Posting from alternate account due to being in Ottawa at the moment... > > -John > > diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c > --- a/usr/src/cmd/truss/systable.c > +++ b/usr/src/cmd/truss/systable.c > @@ -840,8 +840,8 @@ const struct systable sidsystable[] = { > #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_getenforce", 1, DEC, NOV, HID}, /* 0 */ > +{"security_setenforce", 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 */ > > _______________________________________________ > fmac-discuss mailing list > fmac-discuss at opensolaris.org > http://mail.opensolaris.org/mailman/listinfo/fmac-discuss From Cathleen.Reiher at Sun.COM Fri Jul 25 16:51:48 2008 From: Cathleen.Reiher at Sun.COM (Cathleen Reiher) Date: Fri, 25 Jul 2008 16:51:48 -0700 Subject: [fmac-discuss] First draft of FMAC utility man pages Message-ID: The following are first drafts of the FMAC utilities that have been created in the repository: - checkpolicy(1M) - getenforce(1M) - loadpolicy(1M) - pcon(1M) - setenforce(1M) (see getenforce(1M)) - setfiles(1M) Please review and send your comments to the list by Wednesday, July 30th and I'll post updated man page drafts to the OpenSolaris FMAC project page by Friday, August 1st. Cathleen. System Administration Commands checkpolicy(1M) NAME checkpolicy - compile and check an FMAC policy configuration file SYNOPSIS checkpolicy [ -bd ] [ -o output-file ] [ input-file ] DESCRIPTION The checkpolicy command compiles an flexible mandatory access control (FMAC) policy configuration file into the binary format required by the security server. Use the load- policy command to load the compiled policy into the kernel on the security server. This command can also be used to check the validity of the policy configuration file in either the text or binary for- mat. By default, checkpolicy checks the text version of the policy configuration file named policy.conf. To check the binary version of the policy that is loaded in the kernel on the security server, specify the -b option. OPTIONS The checkpolicy command supports the following options. -b Checks the binary version of the policy configuration file that is loaded in the kernel on the security server rather than the text version. By default, the binary policy configuration file is named policy. -d Loads the policy configuration with debug mode enabled so that a user can interactively test the security server functions. -o output-file Writes the binary version of the policy configuration to the specified file, output-file. EXIT STATUS The following exit values are returned: 0 Successful completion. >0 An error occurred. EXAMPLES Example 1 Checking and Compiling a Policy Configuration File This example shows how to check the policy.conf policy con- figuration, and compile it into its binary format, policy. $ checkpolicy Example 2 Writing the Compiled Policy Configuration to an Alternate File This example shows how to compile the policy.conf policy configuration into its binary format. Rather than writing the binary version to the default policy file, name the binary policy.test. $ checkpolicy -o policy.test Example 3 Checking the Binary Version of the Policy Confi- guration File This example shows how to check the binary version of the policy configuration, policy.test. $ checkpolicy -b policy.test Example 4 Loading the Policy Configuration This example shows how to load the binary version of the policy configuration, policy.test, for testing. $ checkpolicy -d policy.test SEE ALSO loadpolicy(1M) SunOS 5.11 Last change: 25 July 2008 1 ----- System Administration Commands getenforce(1M) NAME getenforce, setenforce - view and set the FMAC enforcement mode SYNOPSIS getenforce setenforce [ 0 | 1 | permissive | enforcing ] DESCRIPTION When flexible mandatory access control (FMAC) is enabled, security contexts are assigned to processes and objects, and permission checks are performed. However, when FMAC is dis- abled, no security labeling or permission checks are per- formed. The getenforce and setenforce commands are used to view and set the FMAC enforcement mode when FMAC is enabled. FMAC runs in one of the following modes: o permissive mode. Performs an operation even if it is denied by policy. The operation proceeds past the permission check as if the check had succeeded, but an access vector cache (AVC) denial message is logged. When in permissive mode, only unique denial instances are logged. A unique denial is defined with respect to a given tuple, which includes source context, target context, target class, and permission. To set the enforcement mode to permissive mode, type: $ setenforce permissive Permissive mode is useful for policy-development and recovery purposes. o enforcing mode. Only performs an operation that is permitted by the policy. If an operation is denied by policy, the operation aborts with an error and the denial is logged. When in enforcing mode, every denial is logged or audited, not only the first unique instance. To set the enforcement mode to enforcing mode, type: $ setenforce enforcing By default, FMAC is enabled and operates in permissive mode. Instead of disabling and then reenabling FMAC to perform recovery or workaround operations, set the enforcement mode to permissive. By temporarily using permissive mode, you can perform these operations without having to relabel file sys- tems. Such relabeling must be performed to ensure that any files created while FMAC was disabled are correctly labeled. The /etc/system file specifies FMAC property settings, such as the default policy file location, the enforcement mode, and whether FMAC is enabled. You can enable or disable FMAC by setting the appropriate value to the fmac_enabled property in the /etc/system file. To enable FMAC, add the following to the /etc/system file: set fmac_enabled = 1 To disable FMAC, add the following to the /etc/system file: set fmac_enabled = 0 EXIT STATUS The following exit values are returned by getenforce: 0 Permissive mode is set. If ENOSYS is also returned, enforcement is disabled. 1 Enforcing mode is set. The following exit values are returned by setenforce: 0 Successful completion. >0 An error occurred. FILES /etc/system System configuation information file. SEE ALSO system(4) SunOS 5.11 Last change: 25 July 2008 1 ----- System Administration Commands loadpolicy(1M) NAME loadpolicy - load FMAC policy file SYNOPSIS loadpolicy policy-file DESCRIPTION The loadpolicy command is used to load a flexible mandatory access control (FMAC) policy configuration, policy-file, into the kernel. You can change the default location of the policy configura- tion file that is used by the kernel at boot time by speci- fying the new default path as the value to the fmac_default_policy_file property in the /etc/system file. Before you can load the policy configuration, the file must be in binary form. To compile the policy configuration file, use the checkpolicy command. FILES /etc/security/fmac/ss_policy Default location of the security policy file. SEE ALSO checkpolicy(1M), system(4) SunOS 5.11 Last change: 25 July 2008 1 ----- System Administration Commands pcon(1M) NAME pcon - show process context information SYNOPSIS pcon pid [ pid ] ... DESCRIPTION The pcon command is used to show the process context for one or more specified process IDs, pid. These contexts can only be viewed when flexible mandatory access control (FMAC) is enabled. SunOS 5.11 Last change: 25 July 2008 1 ----- System Administration Commands setfiles(1M) NAME setfiles - assign FMAC security contexts to file system objects SYNOPSIS setfiles [ -dnqvW ] spec-file pathname ... setfiles -s filename ... spec-file DESCRIPTION The setfiles command is used to assign flexible mandatory access control (FMAC) contexts (labels) to the contents of file systems, specified by pathname. The specification file, spec-file, contains specification entries that assign secu- rity contexts to particular files and directories. Each specification entry has the following form: regexp [ type ] ( context | <> ) o The regular expression, regexp, represents a file or directory to be labeled. By default, regexp is an anchored match, which begins with a caret character (^) and terminates with a dollar sign character ($). These characters are automatically added. Override this default behavior by using the .* characters at the begin- ning or end of the regular expression, or both. o The optional type field specifies the file type as shown in the mode field by the ls command. For instance, specify -d to match only directories or -- to match only regular files. o The context field specifies the security context to assign to the file or directory. If the context value is <>, matching files are not rela- beled. The last matching specification is used. setfiles issues a warning when multiple hard links point to a file matched by different specifications that apply dif- ferent security contexts. The file is still labeled based on the last matching specification unless the <> context is specified. OPTIONS The setfiles command supports the following options. -d Shows the specification that matched each file. -n Prevents exisiting file labels from being changed. -q Enables quiet mode, which suppresses non-error output. -s Specifies the list of files to be labeled from standard input. This option cannot be used if the pathname operand is specified. -v Shows the changes to file labels. -W Issues warnings about entries that have no matching file. EXAMPLES Example 1 Setting Security Contexts on File System Objects This example shows how to use the setfiles command to set security contexts on file system objects. The specification file, file_contexts, includes specification entries that are used to assign contexts to particular files and directories. The example shows how the mount and awk commands are used to specify the file systems to label. $ setfiles -v file_contexts `mount | awk '/ext3/{print $3}'` The following file_contexts file fragment shows the contexts to assign to files and directories in /bin, /var/spool, and /var/log: # # /bin # /bin(|/.*) system_u:object_r:bin_t /bin/login system_u:object_r:login_exec_t /bin/tcsh system_u:object_r:shell_exec_t /bin/bash system_u:object_r:shell_exec_t /bin/ash system_u:object_r:shell_exec_t /bin/su system_u:object_r:su_exec_t /bin/ls system_u:object_r:ls_exec_t # # /var/spool # /var/spool(|/.*) system_u:object_r:var_spool_t /var/spool/at(|/.*) system_u:object_r:at_spool_t /var/spool/cron(|/.*) system_u:object_r:cron_spool_t /var/spool/lpd(|/.*) system_u:object_r:lpd_spool_t /var/spool/mail(|/.*) system_u:object_r:mail_spool_t /var/spool/mqueue(|/.*) system_u:object_r:mqueue_spool_t # # /var/log # /var/log(|/.*) system_u:object_r:var_log_t /var/log/wtmp system_u:object_r:wtmp_t /var/log/sendmail.st system_u:object_r:sendmail_var_log_t /var/log/cron system_u:object_r:cron_log_t SunOS 5.11 Last change: 25 July 2008 1 From alan.duboff at sun.com Fri Jul 25 17:18:09 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Fri, 25 Jul 2008 17:18:09 -0700 (PDT) Subject: [fmac-discuss] First draft of FMAC utility man pages In-Reply-To: References: Message-ID: On Fri, 25 Jul 2008, Cathleen Reiher wrote: > The following are first drafts of the FMAC > utilities that have been created in the > repository: I have to say, excellent. Thanks for doing such a nice job on the man pages, and prompt also!:-) -- Alan DuBoff - Solaris x86 IHV/OEM Group From stephen.smalley at gmail.com Fri Jul 25 18:10:28 2008 From: stephen.smalley at gmail.com (Stephen Smalley) Date: Fri, 25 Jul 2008 21:10:28 -0400 Subject: [fmac-discuss] First draft of FMAC utility man pages In-Reply-To: References: Message-ID: <1217034639.14295.26.camel@sulphur> On Fri, 2008-07-25 at 16:51 -0700, Cathleen Reiher wrote: > The following are first drafts of the FMAC > utilities that have been created in the > repository: > > - checkpolicy(1M) > - getenforce(1M) > - loadpolicy(1M) > - pcon(1M) > - setenforce(1M) (see getenforce(1M)) > - setfiles(1M) Thanks. > Please review and send your comments to > the list by Wednesday, July 30th and I'll post > updated man page drafts to the OpenSolaris > FMAC project page by Friday, August 1st. > > Cathleen. > > System Administration Commands checkpolicy(1M) > > NAME > checkpolicy - compile and check an FMAC policy configuration > file > > SYNOPSIS > checkpolicy [ -bd ] [ -o output-file ] [ input-file ] > > DESCRIPTION > The checkpolicy command compiles an flexible mandatory > access control (FMAC) policy configuration file into the > binary format required by the security server. Use the load- > policy command to load the compiled policy into the kernel > on the security server. > > This command can also be used to check the validity of the > policy configuration file in either the text or binary for- > mat. By default, checkpolicy checks the text version of the > policy configuration file named policy.conf. To check the > binary version of the policy that is loaded in the kernel on > the security server, specify the -b option. > > OPTIONS > The checkpolicy command supports the following options. > > -b Checks the binary version of the policy configuration > file that is loaded in the kernel on the security server > rather than the text version. By default, the binary > policy configuration file is named policy. > > -d Loads the policy configuration with debug mode enabled > so that a user can interactively test the security > server functions. > > -o output-file > Writes the binary version of the policy configuration to > the specified file, output-file. > > EXIT STATUS > The following exit values are returned: > > 0 Successful completion. > > >0 An error occurred. > > EXAMPLES > Example 1 Checking and Compiling a Policy Configuration File > > This example shows how to check the policy.conf policy con- > figuration, and compile it into its binary format, policy. > > $ checkpolicy you may also wish to show the more explicit form of invocation: $ checkpolicy -o policy policy.conf > Example 2 Writing the Compiled Policy Configuration to an > Alternate File > > This example shows how to compile the policy.conf policy > configuration into its binary format. Rather than writing > the binary version to the default policy file, name the > binary policy.test. > > $ checkpolicy -o policy.test > > Example 3 Checking the Binary Version of the Policy Confi- > guration File > > This example shows how to check the binary version of the > policy configuration, policy.test. > > $ checkpolicy -b policy.test > > Example 4 Loading the Policy Configuration > > This example shows how to load the binary version of the > policy configuration, policy.test, for testing. > > $ checkpolicy -d policy.test checkpolicy -d -b policy.test if policy.test is a binary policy file. > > SEE ALSO > loadpolicy(1M) > > SunOS 5.11 Last change: 25 July 2008 1 > > ----- > > System Administration Commands getenforce(1M) > > NAME > getenforce, setenforce - view and set the FMAC enforcement > mode > > SYNOPSIS > getenforce > > setenforce [ 0 | 1 | permissive | enforcing ] > > DESCRIPTION > When flexible mandatory access control (FMAC) is enabled, > security contexts are assigned to processes and objects, and > permission checks are performed. However, when FMAC is dis- > abled, no security labeling or permission checks are per- > formed. > > The getenforce and setenforce commands are used to view and > set the FMAC enforcement mode when FMAC is enabled. I'd tend to describe this by saying that FMAC has three possible states: - disabled, - permissive, or - enforcing Otherwise, it sounds almost as though disabled vs. enabled is the same thing as permissive vs. enforcing. Enabled vs. disabled can only be set at boot via kernel options or via /etc/system settings. Permissive vs. enforcing can be initially set in the same manner but can be changed during runtime using setenforce. > > FMAC runs in one of the following modes: > > o permissive mode. Performs an operation even if it > is denied by policy. The operation proceeds past > the permission check as if the check had succeeded, > but an access vector cache (AVC) denial message is > logged. > > When in permissive mode, only unique denial > instances are logged. A unique denial is defined > with respect to a given tuple, which includes > source context, target context, target class, and > permission. We'll likely need to explain this a bit further somewhere, e.g. what is a source context, target context, target class, and permission? > > To set the enforcement mode to permissive mode, > type: > > $ setenforce permissive > > Permissive mode is useful for policy-development > and recovery purposes. > > o enforcing mode. Only performs an operation that is > permitted by the policy. If an operation is denied > by policy, the operation aborts with an error and > the denial is logged. > > When in enforcing mode, every denial is logged or > audited, not only the first unique instance. > > To set the enforcement mode to enforcing mode, > type: > > $ setenforce enforcing > > By default, FMAC is enabled and operates in permissive mode. > > Instead of disabling and then reenabling FMAC to perform > recovery or workaround operations, set the enforcement mode > to permissive. By temporarily using permissive mode, you can > perform these operations without having to relabel file sys- > tems. Such relabeling must be performed to ensure that any > files created while FMAC was disabled are correctly labeled. > > The /etc/system file specifies FMAC property settings, such > as the default policy file location, the enforcement mode, > and whether FMAC is enabled. > > You can enable or disable FMAC by setting the appropriate > value to the fmac_enabled property in the /etc/system file. > To enable FMAC, add the following to the /etc/system file: > > set fmac_enabled = 1 > > To disable FMAC, add the following to the /etc/system file: > > set fmac_enabled = 0 Also they can set fmac_enforcing = 0 or 1 to control permissive vs. enforcing if enabled. > > EXIT STATUS > The following exit values are returned by getenforce: > > 0 Permissive mode is set. If ENOSYS is also > returned, enforcement is disabled. This confuses the system call errno with the utility exit status. The utility exits with 0 if permissive, 1 if enforcing, and 255 (low bytes of -1) if disabled. > > 1 Enforcing mode is set. > > The following exit values are returned by setenforce: > > 0 Successful completion. > > >0 An error occurred. > > FILES > /etc/system > System configuation information file. > > SEE ALSO > system(4) > > SunOS 5.11 Last change: 25 July 2008 1 > > ----- > > System Administration Commands loadpolicy(1M) > > NAME loadpolicy - load FMAC policy file > SYNOPSIS > loadpolicy policy-file > > DESCRIPTION > The loadpolicy command is used to load a flexible mandatory > access control (FMAC) policy configuration, policy-file, > into the kernel. > > You can change the default location of the policy configura- > tion file that is used by the kernel at boot time by speci- > fying the new default path as the value to the > fmac_default_policy_file property in the /etc/system file. > > Before you can load the policy configuration, the file must be in binary form. To compile the policy configuration file, > use the checkpolicy command. > > FILES > /etc/security/fmac/ss_policy > Default location of the security policy file. > > SEE ALSO > checkpolicy(1M), system(4) > > SunOS 5.11 Last change: 25 July 2008 1 > > ----- > > System Administration Commands pcon(1M) > > NAME > pcon - show process context information > > SYNOPSIS > pcon pid [ pid ] ... > > DESCRIPTION > The pcon command is used to show the process context for one > or more specified process IDs, pid. > > These contexts can only be viewed when flexible mandatory > access control (FMAC) is enabled. I think that the utility should be changed to display the current process' context if no arguments are provided so that the user can easily see his own context without needing to specify $$. > > SunOS 5.11 Last change: 25 July 2008 1 > > ----- > > System Administration Commands setfiles(1M) > > NAME > setfiles - assign FMAC security contexts to file system > objects > > SYNOPSIS > setfiles [ -dnqvW ] spec-file pathname ... > > setfiles -s filename ... spec-file > > DESCRIPTION > The setfiles command is used to assign flexible mandatory > access control (FMAC) contexts (labels) to the contents of > file systems, specified by pathname. The specification file, > spec-file, contains specification entries that assign secu- > rity contexts to particular files and directories. > > Each specification entry has the following form: > > regexp [ type ] ( context | <> ) > > o The regular expression, regexp, represents a file > or directory to be labeled. > > By default, regexp is an anchored match, which > begins with a caret character (^) and terminates > with a dollar sign character ($). These characters > are automatically added. Override this default > behavior by using the .* characters at the begin- > ning or end of the regular expression, or both. > > o The optional type field specifies the file type as > shown in the mode field by the ls command. For > instance, specify -d to match only directories or > -- to match only regular files. > > o The context field specifies the security context to > assign to the file or directory. If the context > value is <>, matching files are not rela- > beled. > > The last matching specification is used. > > setfiles issues a warning when multiple hard links point to > a file matched by different specifications that apply dif- > ferent security contexts. The file is still labeled based on > the last matching specification unless the <> context > is specified. > > OPTIONS > The setfiles command supports the following options. > > -d Shows the specification that matched each file. > > -n Prevents exisiting file labels from being changed. > > -q Enables quiet mode, which suppresses non-error output. > > -s Specifies the list of files to be labeled from standard > input. This option cannot be used if the pathname > operand is specified. > > -v Shows the changes to file labels. > > -W Issues warnings about entries that have no matching > file. > > EXAMPLES > Example 1 Setting Security Contexts on File System Objects > > This example shows how to use the setfiles command to set > security contexts on file system objects. The specification > file, file_contexts, includes specification entries that are > used to assign contexts to particular files and directories. > The example shows how the mount and awk commands are used to > specify the file systems to label. > > $ setfiles -v file_contexts `mount | awk '/ext3/{print $3}'` You presumably want to adjust this for Solaris, e.g. replace ext3 with zfs or ufs and check that $3 (3rd field in mount output) is the mount point directory. setfiles doesn't actually work yet in FMAC, of course, as we don't yet have the file labeling support implemented. > > The following file_contexts file fragment shows the contexts > to assign to files and directories in /bin, /var/spool, and > /var/log: > > # > # /bin > # > /bin(|/.*) system_u:object_r:bin_t > /bin/login system_u:object_r:login_exec_t > /bin/tcsh system_u:object_r:shell_exec_t > /bin/bash system_u:object_r:shell_exec_t > /bin/ash system_u:object_r:shell_exec_t > /bin/su system_u:object_r:su_exec_t > /bin/ls system_u:object_r:ls_exec_t > > # > # /var/spool > # > /var/spool(|/.*) system_u:object_r:var_spool_t > /var/spool/at(|/.*) system_u:object_r:at_spool_t > /var/spool/cron(|/.*) system_u:object_r:cron_spool_t > /var/spool/lpd(|/.*) system_u:object_r:lpd_spool_t > /var/spool/mail(|/.*) system_u:object_r:mail_spool_t > /var/spool/mqueue(|/.*) system_u:object_r:mqueue_spool_t > > # > # /var/log > # > /var/log(|/.*) system_u:object_r:var_log_t > /var/log/wtmp system_u:object_r:wtmp_t > /var/log/sendmail.st system_u:object_r:sendmail_var_log_t > /var/log/cron system_u:object_r:cron_log_t > > SunOS 5.11 Last change: 25 July 2008 1 > _______________________________________________ > fmac-discuss mailing list > fmac-discuss at opensolaris.org > http://mail.opensolaris.org/mailman/listinfo/fmac-discuss From Mark.Shellenbaum at Sun.COM Sun Jul 27 12:50:26 2008 From: Mark.Shellenbaum at Sun.COM (Mark Shellenbaum) Date: Sun, 27 Jul 2008 13:50:26 -0600 Subject: [fmac-discuss] FMAC support needed in file system? Message-ID: <488CD182.5060902@Sun.COM> I would like to start a discussion on what is needed to be stored in the file system (ZFS) to support FMAC. It looks like you need a security context and PSID? I have a number of questions about this. - The security context is a string. Is the string variable in size? Is there a max/min length? - Is the security context just opaque data to the file system? - Does every file/dir have a security context? Will the same security context be used for multiple files or is it unique to every file system object? - The PSID appears to be just a simple number, that only the kernel is concerned with. Is this private to the file system, or does the FMAC code need to be able to retrieve it. - Will a user application be setting the context or will it only be set by the kernel? - What OpenSolaris privileges are required for setting the context. - Would it be desirable to create the context at the time a file/dir is created? From sds at tycho.nsa.gov Mon Jul 28 11:06:59 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 28 Jul 2008 14:06:59 -0400 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <488CD182.5060902@Sun.COM> References: <488CD182.5060902@Sun.COM> Message-ID: <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> On Sun, 2008-07-27 at 13:50 -0600, Mark Shellenbaum wrote: > I would like to start a discussion on what is needed to > be stored in the file system (ZFS) to support FMAC. > It looks like you need a security context and PSID? In Linux, we now store the security context as an extended attribute of the inode. If the inode has sufficient space, then the extended attributes can be stored inline; if not, they are stored out of line in separate data blocks. PSIDs were an artifact of the original SELinux implementation; they aren't used presently. The idea there was that we would only store an integer PSID in the on-disk inode and use it as an index into a security context mapping stored in the filesystem. They went away when we migrated to using native Linux extended attributes. > I have a number of questions about this. > > - The security context is a string. Is the string variable in size? > Is there a max/min length? The string is variable in size. The core logic imposes no limits on its size but the syscall interface does impose an upper limit; at present this is defined as FMAC_MAX_CONTEXT_LEN in fmac/fmac.h. That is currently defined as 4K, similar to the Linux interface limitation. In practice, the context strings are usually much smaller, less than 64 bytes, but can grow larger if you are using MLS and have a large set of categories. > - Is the security context just opaque data to the file system? Yes - opaque to the filesystem but interpreted by FMAC and used by it for access control decisions. > - Does every file/dir have a security context? Will the same security > context be used for multiple files or is it unique to every file > system object? Each file/dir can potentially have its own distinct context, but often an entire directory tree may have a single context. In Linux, sharing of extended attribute data blocks is possible when they are stored out of line from the inode. > - The PSID appears to be just a simple number, that only the kernel is > concerned with. Is this private to the file system, or does the FMAC > code need to be able to retrieve it. We don't use them anymore, but in the original SELinux implementation, they were private to the filesystem. > - Will a user application be setting the context or will it only be set > by the kernel? Both. A userspace process can specify the context to use when creating new files (setfscreatecon) or can relabel an existing file (setfilecon) if authorized by policy, and the kernel will initially set the security context of new files, using a policy-provided default computed from the creating process' context and the parent directory context if the application did not specify any context. > - What OpenSolaris privileges are required for setting the context. FMAC will apply its own set of permission checks to control setting of the context. There may be a DAC check applied as well that might mirror the existing DAC check for chmod(). > - Would it be desirable to create the context at the time a file/dir is > created? Yes, that's required - objects need to be labeled before they can first be accessed by userspace. A few other items that merit discussion: - The userland API for getting/setting the in-core security context of a file/dir needs to be independent of storage mechanism (i.e. userland shouldn't need to know whether they are backed by extended attributes or by some persistent label mapping or purely in-memory constructs for pseudo filesystems, etc). In modern SELinux, we have the getfilecon and setfilecon APIs and associated l* (symlink) and f* (file descriptor) variants; in original SELinux, we had extended versions of the stat calls that also included the context information. - Internally, the vnode operations interface used to get/set the file contexts from the kernel code (e.g. from FMAC) needs to likewise be independent of the storage mechanism. In looking around a bit at Solaris internals, it seems like we could use the getattr/setattr vnode ops using the xvattr structure, or we could introduce dedicated getseclabel / setseclabel vnode ops modeled after the getsecattr / setsecattr ops that exist for ACLs. - We need to populate the incore vnode secid before any other thread can access the vnode on the lookup path. - We want new files to be labeled "atomically" at creation time. In Linux, the inode creation and setting of the extended attribute happen within the same ext3 transaction. - Given the differences between Linux extended attributes and Solaris EAs, if we use Solaris EAs for storage of file contexts, then we'll need to address certain issues, such as how to protect the EAs from direct manipulation as files and how to atomically get and set their values. I have a patch that adds a secid to the vnode, hooks the lookup path to initialize it (just to a default value at present, waiting on resolution of some of these issues before I start having it fetch a value from the filesystem), and exports it to userspace via getfilecon calls. -- Stephen Smalley National Security Agency From Mark.Shellenbaum at Sun.COM Mon Jul 28 11:46:39 2008 From: Mark.Shellenbaum at Sun.COM (Mark Shellenbaum) Date: Mon, 28 Jul 2008 12:46:39 -0600 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> References: <488CD182.5060902@Sun.COM> <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <488E140F.5000907@Sun.COM> Stephen Smalley wrote: > On Sun, 2008-07-27 at 13:50 -0600, Mark Shellenbaum wrote: >> I would like to start a discussion on what is needed to >> be stored in the file system (ZFS) to support FMAC. >> It looks like you need a security context and PSID? > > In Linux, we now store the security context as an extended attribute of > the inode. If the inode has sufficient space, then the extended > attributes can be stored inline; if not, they are stored out of line in > separate data blocks. > > PSIDs were an artifact of the original SELinux implementation; they > aren't used presently. The idea there was that we would only store an > integer PSID in the on-disk inode and use it as an index into a security > context mapping stored in the filesystem. They went away when we > migrated to using native Linux extended attributes. > >> I have a number of questions about this. >> >> - The security context is a string. Is the string variable in size? >> Is there a max/min length? > > The string is variable in size. The core logic imposes no limits on its > size but the syscall interface does impose an upper limit; at present > this is defined as FMAC_MAX_CONTEXT_LEN in fmac/fmac.h. That is > currently defined as 4K, similar to the Linux interface limitation. In > practice, the context strings are usually much smaller, less than 64 > bytes, but can grow larger if you are using MLS and have a large set of > categories. > >> - Is the security context just opaque data to the file system? > > Yes - opaque to the filesystem but interpreted by FMAC and used by it > for access control decisions. > >> - Does every file/dir have a security context? Will the same security >> context be used for multiple files or is it unique to every file >> system object? > > Each file/dir can potentially have its own distinct context, but often > an entire directory tree may have a single context. In Linux, sharing > of extended attribute data blocks is possible when they are stored out > of line from the inode. > >> - The PSID appears to be just a simple number, that only the kernel is >> concerned with. Is this private to the file system, or does the FMAC >> code need to be able to retrieve it. > > We don't use them anymore, but in the original SELinux implementation, > they were private to the filesystem. > >> - Will a user application be setting the context or will it only be set >> by the kernel? > > Both. A userspace process can specify the context to use when creating > new files (setfscreatecon) or can relabel an existing file (setfilecon) > if authorized by policy, and the kernel will initially set the security > context of new files, using a policy-provided default computed from the > creating process' context and the parent directory context if the > application did not specify any context. > >> - What OpenSolaris privileges are required for setting the context. > > FMAC will apply its own set of permission checks to control setting of > the context. There may be a DAC check applied as well that might > mirror the existing DAC check for chmod(). > >> - Would it be desirable to create the context at the time a file/dir is >> created? > > Yes, that's required - objects need to be labeled before they can first > be accessed by userspace. > > A few other items that merit discussion: > - The userland API for getting/setting the in-core security context of a > file/dir needs to be independent of storage mechanism (i.e. userland > shouldn't need to know whether they are backed by extended attributes or > by some persistent label mapping or purely in-memory constructs for > pseudo filesystems, etc). In modern SELinux, we have the getfilecon and > setfilecon APIs and associated l* (symlink) and f* (file descriptor) > variants; in original SELinux, we had extended versions of the stat > calls that also included the context information. > > - Internally, the vnode operations interface used to get/set the file > contexts from the kernel code (e.g. from FMAC) needs to likewise be > independent of the storage mechanism. In looking around a bit at > Solaris internals, it seems like we could use the getattr/setattr vnode > ops using the xvattr structure, or we could introduce dedicated > getseclabel / setseclabel vnode ops modeled after the getsecattr / > setsecattr ops that exist for ACLs. > Yes, thats what I was thinking too. We could easily add this as a new system attribute that can be managed from user code via the getattrat()/setattrat() libc interfaces and via VOP_SETATTR in kernel code. This will require some code in ZFS to manage the contexts, but that shouldn't be very hard. You can also pass an xvattr_t to VOP_CREATE/VOP_MKDIR to have the initial context set atomically on ZFS. By adding this as a new sysattr exposed via either the SUNWattr_rw or SUNWattr_ro file then we won't have the problem of an application inadvertently removing it. Would you want an application such as "cp" to copy the context when a file is copied? > - We need to populate the incore vnode secid before any other thread can > access the vnode on the lookup path. > > - We want new files to be labeled "atomically" at creation time. In > Linux, the inode creation and setting of the extended attribute happen > within the same ext3 transaction. > Yep, ZFS could do that too. > - Given the differences between Linux extended attributes and Solaris > EAs, if we use Solaris EAs for storage of file contexts, then we'll need > to address certain issues, such as how to protect the EAs from direct > manipulation as files and how to atomically get and set their values. > I'm not sure I would advocate using the generic solaris extended attribute model, but would be an excellent candidate for the new sysattr framework which has some special extended attribute files (SUNWattr_rw, SUNWattr_ro) that are used to expose special attributes such as "immutable, nounlink, appendonly, CIFS SIDs and so on). For a generic attribute you could run into problems with users deleting them and it also creates a bit of overhead in the file system to manage an extra directory hung over of every file/dir. The sysattr framework doesn't have this problem. It will only create a *real* extended attribute directory when one is needed to store a generic user attribute. > I have a patch that adds a secid to the vnode, hooks the lookup path to > initialize it (just to a default value at present, waiting on resolution > of some of these issues before I start having it fetch a value from the > filesystem), and exports it to userspace via getfilecon calls. > -Mark From sds at tycho.nsa.gov Mon Jul 28 12:21:05 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 28 Jul 2008 15:21:05 -0400 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <488E140F.5000907@Sun.COM> References: <488CD182.5060902@Sun.COM> <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> <488E140F.5000907@Sun.COM> Message-ID: <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> On Mon, 2008-07-28 at 12:46 -0600, Mark Shellenbaum wrote: > Stephen Smalley wrote: > > - Internally, the vnode operations interface used to get/set the file > > contexts from the kernel code (e.g. from FMAC) needs to likewise be > > independent of the storage mechanism. In looking around a bit at > > Solaris internals, it seems like we could use the getattr/setattr vnode > > ops using the xvattr structure, or we could introduce dedicated > > getseclabel / setseclabel vnode ops modeled after the getsecattr / > > setsecattr ops that exist for ACLs. > > > > Yes, thats what I was thinking too. We could easily add this as a new > system attribute that can be managed from user code via the > getattrat()/setattrat() libc interfaces and via VOP_SETATTR in kernel > code. This will require some code in ZFS to manage the contexts, but > that shouldn't be very hard. > > You can also pass an xvattr_t to VOP_CREATE/VOP_MKDIR to have the > initial context set atomically on ZFS. > > By adding this as a new sysattr exposed via either the SUNWattr_rw or > SUNWattr_ro file then we won't have the problem of an application > inadvertently removing it. > > Would you want an application such as "cp" to copy the context when a > file is copied? Yes, although it needs a graceful fallback in the case where it isn't allowed to do so (e.g. when a topsecret process copies an unclassified file, the new file is necessarily labeled topsecret because the data flows through the topsecret process and may be tainted by its own private data). GNU coreutils has incorporated SELinux support with the following behavior: - "cp -a" will try to preserve context but failure to do so does not change its exit status, so it falls back to just preserving other attributes if not allowed to preserve security contexts. - "cp --preserve=context" is similar but will fail with a nonzero status if it cannot preserve the context. > > - Given the differences between Linux extended attributes and Solaris > > EAs, if we use Solaris EAs for storage of file contexts, then we'll need > > to address certain issues, such as how to protect the EAs from direct > > manipulation as files and how to atomically get and set their values. > > > > I'm not sure I would advocate using the generic solaris extended > attribute model, but would be an excellent candidate for the new sysattr > framework which has some special extended attribute files (SUNWattr_rw, > SUNWattr_ro) that are used to expose special attributes such as > "immutable, nounlink, appendonly, CIFS SIDs and so on). > > For a generic attribute you could run into problems with users deleting > them and it also creates a bit of overhead in the file system to manage > an extra directory hung over of every file/dir. The sysattr framework > doesn't have this problem. It will only create a *real* extended > attribute directory when one is needed to store a generic user attribute. That sounds promising. When I looked briefly at the xvattr support though, it appeared that it is only fully supported by ZFS (and smbsrv), and the ZFS implementation seemed to be somewhat constrained in its ability to support additional variable length data like contexts (e.g. already overloading the small amount of free space left in the physical znode for inline symlinks and antivirus timestamps). -- Stephen Smalley National Security Agency From Mark.Shellenbaum at Sun.COM Mon Jul 28 12:28:49 2008 From: Mark.Shellenbaum at Sun.COM (Mark Shellenbaum) Date: Mon, 28 Jul 2008 13:28:49 -0600 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> References: <488CD182.5060902@Sun.COM> <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> <488E140F.5000907@Sun.COM> <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <488E1DF1.8060508@Sun.COM> >> >> For a generic attribute you could run into problems with users deleting >> them and it also creates a bit of overhead in the file system to manage >> an extra directory hung over of every file/dir. The sysattr framework >> doesn't have this problem. It will only create a *real* extended >> attribute directory when one is needed to store a generic user attribute. > > That sounds promising. When I looked briefly at the xvattr support > though, it appeared that it is only fully supported by ZFS (and smbsrv), > and the ZFS implementation seemed to be somewhat constrained in its > ability to support additional variable length data like contexts (e.g. > already overloading the small amount of free space left in the physical > znode for inline symlinks and antivirus timestamps). > Well, I'm currently in the process of redoing the way the znode is laid out in ZFS. We have other consumers that want to store some special attributes, such as Lustre. This will allow us to store other system'ish attribute in a better way, and allow for better future expansion. I think that the security context can be added to current ZFS on disk format without the need of the new improved znode layout. The xvattr_t support is only fully supported in ZFS, and we can't easily modify UFS today. Is there any sort of requirement for this to work on UFS, or can we say it will only for on ZFS? -Mark From sds at tycho.nsa.gov Mon Jul 28 12:48:50 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 28 Jul 2008 15:48:50 -0400 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <488E1DF1.8060508@Sun.COM> References: <488CD182.5060902@Sun.COM> <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> <488E140F.5000907@Sun.COM> <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> <488E1DF1.8060508@Sun.COM> Message-ID: <1217274530.20373.137.camel@moss-spartans.epoch.ncsc.mil> On Mon, 2008-07-28 at 13:28 -0600, Mark Shellenbaum wrote: > >> > >> For a generic attribute you could run into problems with users deleting > >> them and it also creates a bit of overhead in the file system to manage > >> an extra directory hung over of every file/dir. The sysattr framework > >> doesn't have this problem. It will only create a *real* extended > >> attribute directory when one is needed to store a generic user attribute. > > > > That sounds promising. When I looked briefly at the xvattr support > > though, it appeared that it is only fully supported by ZFS (and smbsrv), > > and the ZFS implementation seemed to be somewhat constrained in its > > ability to support additional variable length data like contexts (e.g. > > already overloading the small amount of free space left in the physical > > znode for inline symlinks and antivirus timestamps). > > > > Well, I'm currently in the process of redoing the way the znode is laid > out in ZFS. We have other consumers that want to store some special > attributes, such as Lustre. This will allow us to store other > system'ish attribute in a better way, and allow for better future > expansion. > > I think that the security context can be added to current ZFS on disk > format without the need of the new improved znode layout. > > The xvattr_t support is only fully supported in ZFS, and we can't easily > modify UFS today. > > Is there any sort of requirement for this to work on UFS, or can we say > it will only for on ZFS? I suppose it depends on whether users are likely to keep using UFS in future releases of Solaris or if they will migrate entirely to ZFS. Using a zfs-root would be a requirement for FMAC if we only support file security contexts on ZFS. Are there any other (non-legacy) disk-based filesystems supported by Solaris that we need to concern ourselves with? I should note too that we'd like to extend this same support across NFSv4; there is work in progress on labeled NFSv4 support and standardization. And we would want to support getting and setting of file contexts on certain non-disk-based filesystems, e.g. tmpfs, although there we can just store a secid in the in-core vnode and handle it entirely at the VFS layer. -- Stephen Smalley National Security Agency From Darren.Moffat at Sun.COM Tue Jul 29 05:48:56 2008 From: Darren.Moffat at Sun.COM (Darren J Moffat) Date: Tue, 29 Jul 2008 13:48:56 +0100 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> References: <488CD182.5060902@Sun.COM> <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> <488E140F.5000907@Sun.COM> <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <488F11B8.10301@Sun.COM> Stephen Smalley wrote: > GNU coreutils has incorporated SELinux support with the following > behavior: > - "cp -a" will try to preserve context but failure to do so does not > change its exit status, so it falls back to just preserving other > attributes if not allowed to preserve security contexts. > - "cp --preserve=context" is similar but will fail with a nonzero status > if it cannot preserve the context. The OpenSolaris cp has: -@ Preserves extended attributes. cp attempts to copy all of the source file's extended attributes along with the file data to the destination file. -/ Preserves extended attributes and extended system attributes. Along with the file's data, the cp utility attempts to copy extended attributes and extended sys- tem attributes from each source file, and extended system attributes associated with extended attributes to the destination file. If cp is unable to copy extended attributes or extended system attributes, then a diagnostic message is written to stderr and (after processing any remaining operands) exits with a non-zero exit status. Note also: /usr/bin/cp If the -p option is specified with either the -@ option or the -/ option, /usr/bin/cp behaves as follows o When both -p and -@ are specified in any order, the copy fails if extended attributes cannot be copied. o When both -p and -/ are specified in any order, the copy fails if extended system attributes cannot be copied. /usr/xpg4/bin/cp If the -p option is specified with either the -@ option or the -/ option, /usr/xpg4/bin/cp behaves as follows: o When both -p and -@ are specified, the last option specified determines whether the copy fails if extended attributes cannot be preserved. o When both -p and -/ are specified, the last option specified determines whether the copy fails if extended system attributes cannot be preserved. Other utilities (cpio,tar,pax,..) have a -/ and -@ flag as well. -- Darren J Moffat From sds at tycho.nsa.gov Tue Jul 29 06:41:02 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 29 Jul 2008 09:41:02 -0400 Subject: [fmac-discuss] FMAC support needed in file system? In-Reply-To: <488F11B8.10301@Sun.COM> References: <488CD182.5060902@Sun.COM> <1217268420.20373.88.camel@moss-spartans.epoch.ncsc.mil> <488E140F.5000907@Sun.COM> <1217272865.20373.121.camel@moss-spartans.epoch.ncsc.mil> <488F11B8.10301@Sun.COM> Message-ID: <1217338862.20373.203.camel@moss-spartans.epoch.ncsc.mil> On Tue, 2008-07-29 at 13:48 +0100, Darren J Moffat wrote: > Stephen Smalley wrote: > > GNU coreutils has incorporated SELinux support with the following > > behavior: > > - "cp -a" will try to preserve context but failure to do so does not > > change its exit status, so it falls back to just preserving other > > attributes if not allowed to preserve security contexts. > > - "cp --preserve=context" is similar but will fail with a nonzero status > > if it cannot preserve the context. > > The OpenSolaris cp has: > > -@ Preserves extended attributes. cp attempts to copy all > of the source file's extended attributes along with > the file data to the destination file. > > > -/ Preserves extended attributes and extended system > attributes. Along with the file's data, the cp utility > attempts to copy extended attributes and extended sys- > tem attributes from each source file, and extended > system attributes associated with extended attributes > to the destination file. If cp is unable to copy > extended attributes or extended system attributes, > then a diagnostic message is written to stderr and > (after processing any remaining operands) exits with a > non-zero exit status. > > Note also: > > /usr/bin/cp > If the -p option is specified with either the -@ option or > the -/ option, /usr/bin/cp behaves as follows > > o When both -p and -@ are specified in any order, the > copy fails if extended attributes cannot be copied. > > o When both -p and -/ are specified in any order, the > copy fails if extended system attributes cannot be > copied. > > /usr/xpg4/bin/cp > If the -p option is specified with either the -@ option or > the -/ option, /usr/xpg4/bin/cp behaves as follows: > > o When both -p and -@ are specified, the last option > specified determines whether the copy fails if > extended attributes cannot be preserved. > > o When both -p and -/ are specified, the last option > specified determines whether the copy fails if > extended system attributes cannot be preserved. > > Other utilities (cpio,tar,pax,..) have a -/ and -@ flag as well. Ok. Only thing we have to be careful about is to make sure that existing usage patterns by users and scripts don't suddenly break when the FMAC context is present, as the access rules governing the ability to set the FMAC context are different than the privileges or logic governing the ability to set existing attributes. Also, we want the userland API to remain independent of the storage mechanism and to work cleanly across not only zfs but also tmpfs and any other filesystem where it makes sense to be able to set and get individual file contexts, including ultimately across NFSv4 when labeled NFSv4 support gets implemented and standardized. There will also be cases where even though the filesystem itself supports storage of FMAC contexts, we won't trust it to provide them and will want to treat all files on it as having a single admin-specified FMAC context; in SELinux, this is the context= mount option, which also serves to allow assigning a single context to filesystems that do not support labeling at all. When that mount option is used, the interface for getting the file context returns that context rather than any actual attribute value, and the interface for setting the file context fails with EOPNOTSUPP. -- Stephen Smalley National Security Agency From Cathleen.Reiher at Sun.COM Tue Jul 29 10:09:39 2008 From: Cathleen.Reiher at Sun.COM (Cathleen Reiher) Date: Tue, 29 Jul 2008 10:09:39 -0700 Subject: [fmac-discuss] First draft of FMAC utility man pages In-Reply-To: <1217034639.14295.26.camel@sulphur> References: <1217034639.14295.26.camel@sulphur> Message-ID: Thanks for the feedback, Stephen. I have updated the checkpolicy(1M) and setfiles(1M) man pages based on your comments. I've made some changes to the genenforce(1M) man page, but I have more work to do here. Stephen Smalley wrote: > On Fri, 2008-07-25 at 16:51 -0700, Cathleen Reiher wrote: > > System Administration Commands getenforce(1M) > > > > When flexible mandatory access control (FMAC) is enabled, > > security contexts are assigned to processes and objects, and > > permission checks are performed. However, when FMAC is dis- > > abled, no security labeling or permission checks are per- > > formed. > > > > The getenforce and setenforce commands are used to view and > > set the FMAC enforcement mode when FMAC is enabled. > > I'd tend to describe this by saying that FMAC has three possible states: > - disabled, > - permissive, or > - enforcing > > Otherwise, it sounds almost as though disabled vs. enabled is the same > thing as permissive vs. enforcing. > > Enabled vs. disabled can only be set at boot via kernel options or > via /etc/system settings. Permissive vs. enforcing can be initially set > in the same manner but can be changed during runtime using setenforce. Okay. Let me think about this a bit and see what I can come up with. I'll send it out for another review when it's ready. > > When in permissive mode, only unique denial > > instances are logged. A unique denial is defined > > with respect to a given tuple, which includes > > source context, target context, target class, and > > permission. > > We'll likely need to explain this a bit further somewhere, e.g. what is > a source context, target context, target class, and permission? Yeah, you're right. Let me see what I can find. Do you think that defining these terms would be appropriate content for the fmac(5) man page or should they be defined in the getenforce(1M) man page? > I think that the [pcon] utility should be changed to display the current > process' context if no arguments are provided so that the user can > easily see his own context without needing to specify $$. This is a good idea, Stephen. I'll wait to update the man page until the code has been changed as you suggest. Cathleen.