From john.weeks at sun.com Wed Jun 4 12:48:11 2008 From: john.weeks at sun.com (John Weeks) Date: Wed, 04 Jun 2008 12:48:11 -0700 Subject: [fmac-discuss] Progress Update Message-ID: <4846F17B.2080306@sun.com> Our list has been quite for the past couple of weeks so I thought it would be a good time for a brief update. The Alpha 1 code does build on SPARC :-) We will be posting a contribution process shortly that will cover new functionality and bug fixes. I'm doing my best to keep it simple ;-) A new bug category on defect.opensolaris.org (development/fmac) has been created and our first bug (#2131) has been filed. After we get the process posted, I'll post the fix for #2131 for review. I have the first set of system calls prototyped (e.g., security_compute_av and security_load_policy) that will be posted for review after the fix for #2131 goes out. We have created a notification list (fmac-notify at opensolaris.org) for repo notifications. So, if you want to track code as it's going into the repo, join the list: http://mail.opensolaris.org/mailman/listinfo/fmac-notify Stay tuned, things are happening. Regards, John From john.weeks at sun.com Fri Jun 6 06:45:19 2008 From: john.weeks at sun.com (John Weeks) Date: Fri, 06 Jun 2008 06:45:19 -0700 Subject: [fmac-discuss] Code Contribution Procedure Message-ID: <48493F6F.7040509@sun.com> Procedure for submitting code and/or bug fixes for the opensolaris.org Flexible Mandatory Access Control (FMAC) project: The contributor must have a contributor agreement on file with Sun or be Sun employee. Code reviews should be submitted to the fmac-discuss at opensolaris.org list as diffs (hg diff -g). Webrevs posted to http://cr.opensolaris.org are also acceptable and are preferred for complex changes. If submitting a bug fix for a bug entered on defect.opensolaris.org, the bug number(s) should be included in the commit message using the following style: Bug number Bug Summary Example: 2131 checkpolicy produces different policy files on x86 & SPARC One or more FMAC contributors must approve the submission before it can be pushed to the repo. A review by at least 1 FMAC contributor other than the contributor is required. Kernel code should be lint clean. Code should pass cstyle. Header files should pass hdrchk. We have to remember that FMAC is a development project in it's own repository and does not need to meet all the requirements that are necessary to integrate into the onnv repo. This does not mean that we will drop our quality needs, but it does allow for more wiggle room. We will try to follow the OpenSolaris Development Process as closely as makes sense for our project: http://opensolaris.org/os/community/on/os_dev_process/ We also need to be aware that when FMAC is ready, we plan to integrate into onnv and we can't let things go until the end or we will be stuck in a cleanup spiral. OpenSolaris Integration Procedure: http://www.opensolaris.org/os/community/on/devref_toc/devref_6/ Mercurial Usage: http://www.genunix.org/wiki/index.php/Mercurial If you would like to receive repo changeset notifications, subscribe to the fmac-notify at opensolaris.org list. From john.weeks at sun.com Fri Jun 6 08:39:29 2008 From: john.weeks at sun.com (John Weeks) Date: Fri, 06 Jun 2008 08:39:29 -0700 Subject: [fmac-discuss] Bug Fix 2131 checkpolicy produces different policy files on x86 & SPARC Message-ID: <48495A31.4060003@sun.com> 2131 checkpolicy produces different policy files on x86 & SPARC bash-3.2$ cmp -l ss_policy.x86 ss_policy.sparc 924862 177 1 924865 1 177 924902 220 0 924903 63 31 924904 31 63 924905 0 220 924906 377 0 924909 0 377 This was discovered with binaries produced with the FMAC Alpha 1 version (hg tag fmac_onnv_87). The internal format of the node address is created in little-endian format. usr/src/cmd/fmac/checkpolicy/policy_parse.y: ipv4_addr_def : number '.' number '.' number '.' number { unsigned int addr; unsigned char *p = ((unsigned char *)&addr); p[0] = $1 & 0xff; p[1] = $3 & 0xff; p[2] = $5 & 0xff; p[3] = $7 & 0xff; $$ = addr; } ; The node field is then converted to little-endian when it is written to the policy file. usr/src/cmd/fmac/checkpolicy/write.c: case OCON_NODE: buf[0] = SS_CPU_TO_LE32(c->u.node.addr); buf[1] = SS_CPU_TO_LE32(c->u.node.mask); items = fwrite(buf, sizeof (uint32_t), 2, fp); if (items != 2) return (-1); if (context_write(&c->context[0], fp)) return (-1); Since SS_CPU_TO_LE32() on a little-endian system does not swap the bytes, the node field is stored as little-endian on x86 systems. On a SPARC system (big-endian), the internal node format is byte swapped by SS_CPU_TO_LE32() thus storing the node field as big-endian. This explains the difference in files generated on x86 & SPARC. The node and mask values should be stored in network order in the policy file. Webrev: http://cr.opensolaris.org/~jweeks/bug-2131/ Bug report: http://defect.opensolaris.org/bz/show_bug.cgi?id=2131 diff --git a/usr/src/cmd/fmac/checkpolicy/policy_parse.y b/usr/src/cmd/fmac/checkpolicy/policy_parse.y --- a/usr/src/cmd/fmac/checkpolicy/policy_parse.y +++ b/usr/src/cmd/fmac/checkpolicy/policy_parse.y @@ -21,6 +21,11 @@ */ /* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * Original files contributed to OpenSolaris.org under license by the * United States Government (NSA) to Sun Microsystems, Inc. */ @@ -34,7 +39,10 @@ #include "queue.h" #include #include +#include +#include #include +#include #include "checkpolicy.h" #include #include @@ -135,6 +143,7 @@ static int define_node_context(int addr, %token IDENTIFIER %token USER_IDENTIFIER %token NUMBER +%token IPV4ADDRESS %token EQUALS %token NOTEQUAL @@ -498,16 +507,14 @@ genfs_context_def : GENFSCON identifier | GENFSCON identifier path security_context_def {if (define_genfs_context(0)) return -1;} ; -ipv4_addr_def : number '.' number '.' number '.' number +ipv4_addr_def : IPV4ADDRESS { - unsigned int addr; - unsigned char *p = ((unsigned char *)&addr); - - p[0] = $1 & 0xff; - p[1] = $3 & 0xff; - p[2] = $5 & 0xff; - p[3] = $7 & 0xff; - $$ = addr; + in_addr_t addr; + if (inet_pton(AF_INET, yytext, &addr) != 1) { + yyerror("invalid IPv4 address"); + return -1; + } + $$ = addr; /* network order */ } ; security_context_def : user_id ':' identifier ':' identifier opt_mls_range_def diff --git a/usr/src/cmd/fmac/checkpolicy/policy_scan.l b/usr/src/cmd/fmac/checkpolicy/policy_scan.l --- a/usr/src/cmd/fmac/checkpolicy/policy_scan.l +++ b/usr/src/cmd/fmac/checkpolicy/policy_scan.l @@ -20,6 +20,11 @@ * 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. */ /* @@ -47,8 +52,10 @@ int yywarn(char *msg); %p 12500 %a 10000 %n 2500 -letter [A-Za-z] -digit [0-9] +letter [A-Za-z] +digit [0-9] +octet ({digit}{1,3}) +ipv4address {octet}((\.{octet}){3}) %% \n.* { strncpy(linebuf[lno], yytext+1, 255); linebuf[lno][254] = 0; @@ -161,6 +168,7 @@ T2 { return(T2); } {letter}({letter}|{digit}|_)* { return(IDENTIFIER); } {letter}({letter}|{digit}|_|"."|"-")* { return(USER_IDENTIFIER); } {digit}{digit}* { return(NUMBER); } +{ipv4address} { return(IPV4ADDRESS); } #[^\n]* { /* delete comments */ } [ \t\f]+ { /* delete whitespace */ } "==" { return(EQUALS); } diff --git a/usr/src/cmd/fmac/checkpolicy/write.c b/usr/src/cmd/fmac/checkpolicy/write.c --- a/usr/src/cmd/fmac/checkpolicy/write.c +++ b/usr/src/cmd/fmac/checkpolicy/write.c @@ -17,6 +17,11 @@ * 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. */ /* @@ -735,8 +740,9 @@ policydb_write(policydb_t *p, FILE *fp) return (-1); break; case OCON_NODE: - buf[0] = SS_CPU_TO_LE32(c->u.node.addr); - buf[1] = SS_CPU_TO_LE32(c->u.node.mask); + /* store in network order */ + buf[0] = c->u.node.addr; + buf[1] = c->u.node.mask; items = fwrite(buf, sizeof (uint32_t), 2, fp); if (items != 2) return (-1); diff --git a/usr/src/common/fmac/ss/policydb.c b/usr/src/common/fmac/ss/policydb.c --- a/usr/src/common/fmac/ss/policydb.c +++ b/usr/src/common/fmac/ss/policydb.c @@ -1237,8 +1237,9 @@ policydb_read(policydb_t *p, void *fp) fp); if (items != 2) goto bad; - c->u.node.addr = SS_LE32_TO_CPU(buf[0]); - c->u.node.mask = SS_LE32_TO_CPU(buf[1]); + /* addr and mask stored in network order */ + c->u.node.addr = buf[0]; + c->u.node.mask = buf[1]; if (context_read_and_validate(&c->context[0], p, fp)) goto bad; From sds at tycho.nsa.gov Fri Jun 6 09:10:42 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Fri, 06 Jun 2008 12:10:42 -0400 Subject: [fmac-discuss] Bug Fix 2131 checkpolicy produces different policy files on x86 & SPARC In-Reply-To: <48495A31.4060003@sun.com> References: <48495A31.4060003@sun.com> Message-ID: <1212768642.2763.298.camel@moss-spartans.epoch.ncsc.mil> On Fri, 2008-06-06 at 08:39 -0700, John Weeks wrote: > 2131 checkpolicy produces different policy files on x86 & SPARC > > bash-3.2$ cmp -l ss_policy.x86 ss_policy.sparc > 924862 177 1 > 924865 1 177 > 924902 220 0 > 924903 63 31 > 924904 31 63 > 924905 0 220 > 924906 377 0 > 924909 0 377 > > This was discovered with binaries produced with the FMAC Alpha 1 version (hg > tag fmac_onnv_87). > > The internal format of the node address is created in little-endian format. > > usr/src/cmd/fmac/checkpolicy/policy_parse.y: > > ipv4_addr_def : number '.' number '.' number '.' number > { > unsigned int addr; > unsigned char *p = ((unsigned char *)&addr); > > p[0] = $1 & 0xff; > p[1] = $3 & 0xff; > p[2] = $5 & 0xff; > p[3] = $7 & 0xff; > $$ = addr; > } > ; > > The node field is then converted to little-endian when it is written to the > policy file. > > usr/src/cmd/fmac/checkpolicy/write.c: > > case OCON_NODE: > buf[0] = SS_CPU_TO_LE32(c->u.node.addr); > buf[1] = SS_CPU_TO_LE32(c->u.node.mask); > items = fwrite(buf, sizeof (uint32_t), 2, fp); > if (items != 2) > return (-1); > if (context_write(&c->context[0], fp)) > return (-1); > > Since SS_CPU_TO_LE32() on a little-endian system does not swap the bytes, the > node field is stored as little-endian on x86 systems. On a SPARC system > (big-endian), the internal node format is byte swapped by SS_CPU_TO_LE32() thus > storing the node field as big-endian. This explains the difference in files > generated on x86 & SPARC. > > The node and mask values should be stored in network order in the policy file. > > Webrev: http://cr.opensolaris.org/~jweeks/bug-2131/ > > Bug report: http://defect.opensolaris.org/bz/show_bug.cgi?id=2131 > > > diff --git a/usr/src/cmd/fmac/checkpolicy/policy_parse.y > b/usr/src/cmd/fmac/checkpolicy/policy_parse.y > --- a/usr/src/cmd/fmac/checkpolicy/policy_parse.y > +++ b/usr/src/cmd/fmac/checkpolicy/policy_parse.y > @@ -21,6 +21,11 @@ > */ > > /* > + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. > + * Use is subject to license terms. > + */ > + > +/* > * Original files contributed to OpenSolaris.org under license by the > * United States Government (NSA) to Sun Microsystems, Inc. > */ > @@ -34,7 +39,10 @@ > #include "queue.h" > #include > #include > +#include > +#include > #include > +#include > #include "checkpolicy.h" > #include > #include > @@ -135,6 +143,7 @@ static int define_node_context(int addr, > %token IDENTIFIER > %token USER_IDENTIFIER > %token NUMBER > +%token IPV4ADDRESS > %token EQUALS > %token NOTEQUAL > > @@ -498,16 +507,14 @@ genfs_context_def : GENFSCON identifier > | GENFSCON identifier path security_context_def > {if (define_genfs_context(0)) return -1;} > ; > -ipv4_addr_def : number '.' number '.' number '.' number > +ipv4_addr_def : IPV4ADDRESS > { > - unsigned int addr; > - unsigned char *p = ((unsigned char *)&addr); > - > - p[0] = $1 & 0xff; > - p[1] = $3 & 0xff; > - p[2] = $5 & 0xff; > - p[3] = $7 & 0xff; > - $$ = addr; > + in_addr_t addr; > + if (inet_pton(AF_INET, yytext, &addr) != 1) { > + yyerror("invalid IPv4 address"); > + return -1; > + } > + $$ = addr; /* network order */ > } > ; > security_context_def : user_id ':' identifier ':' identifier opt_mls_range_def > diff --git a/usr/src/cmd/fmac/checkpolicy/policy_scan.l > b/usr/src/cmd/fmac/checkpolicy/policy_scan.l > --- a/usr/src/cmd/fmac/checkpolicy/policy_scan.l > +++ b/usr/src/cmd/fmac/checkpolicy/policy_scan.l > @@ -20,6 +20,11 @@ > * 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. > */ > > /* > @@ -47,8 +52,10 @@ int yywarn(char *msg); > %p 12500 > %a 10000 > %n 2500 > -letter [A-Za-z] > -digit [0-9] > +letter [A-Za-z] > +digit [0-9] > +octet ({digit}{1,3}) > +ipv4address {octet}((\.{octet}){3}) > %% > \n.* { strncpy(linebuf[lno], yytext+1, 255); > linebuf[lno][254] = 0; > @@ -161,6 +168,7 @@ T2 { return(T2); } > {letter}({letter}|{digit}|_)* { return(IDENTIFIER); } > {letter}({letter}|{digit}|_|"."|"-")* { return(USER_IDENTIFIER); } > {digit}{digit}* { return(NUMBER); } > +{ipv4address} { return(IPV4ADDRESS); } > #[^\n]* { /* delete comments */ } > [ \t\f]+ { /* delete whitespace */ } > "==" { return(EQUALS); } > diff --git a/usr/src/cmd/fmac/checkpolicy/write.c > b/usr/src/cmd/fmac/checkpolicy/write.c > --- a/usr/src/cmd/fmac/checkpolicy/write.c > +++ b/usr/src/cmd/fmac/checkpolicy/write.c > @@ -17,6 +17,11 @@ > * 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. > */ > > /* > @@ -735,8 +740,9 @@ policydb_write(policydb_t *p, FILE *fp) > return (-1); > break; > case OCON_NODE: > - buf[0] = SS_CPU_TO_LE32(c->u.node.addr); > - buf[1] = SS_CPU_TO_LE32(c->u.node.mask); > + /* store in network order */ > + buf[0] = c->u.node.addr; > + buf[1] = c->u.node.mask; > items = fwrite(buf, sizeof (uint32_t), 2, fp); > if (items != 2) > return (-1); > diff --git a/usr/src/common/fmac/ss/policydb.c b/usr/src/common/fmac/ss/policydb.c > --- a/usr/src/common/fmac/ss/policydb.c > +++ b/usr/src/common/fmac/ss/policydb.c > @@ -1237,8 +1237,9 @@ policydb_read(policydb_t *p, void *fp) > fp); > if (items != 2) > goto bad; > - c->u.node.addr = SS_LE32_TO_CPU(buf[0]); > - c->u.node.mask = SS_LE32_TO_CPU(buf[1]); > + /* addr and mask stored in network order */ > + c->u.node.addr = buf[0]; > + c->u.node.mask = buf[1]; > if (context_read_and_validate(&c->context[0], > p, fp)) > goto bad; I made a clarification in the bug report as the above description isn't quite right. But the patch is correct - we shouldn't be applying conversions between cpu/host order and little endian on policy write/read for node addresses/masks that are stored in network order. Acked-by: Stephen Smalley -- Stephen Smalley National Security Agency From john.weeks at sun.com Fri Jun 6 17:50:42 2008 From: john.weeks at sun.com (John Weeks) Date: Fri, 06 Jun 2008 17:50:42 -0700 Subject: [fmac-discuss] Bug Fix 2131 checkpolicy produces different policy files on x86 & SPARC In-Reply-To: <1212768642.2763.298.camel@moss-spartans.epoch.ncsc.mil> References: <48495A31.4060003@sun.com> <1212768642.2763.298.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <4849DB62.3050004@sun.com> Stephen Smalley wrote: > On Fri, 2008-06-06 at 08:39 -0700, John Weeks wrote: >> 2131 checkpolicy produces different policy files on x86 & SPARC >> >> bash-3.2$ cmp -l ss_policy.x86 ss_policy.sparc >> 924862 177 1 >> 924865 1 177 >> 924902 220 0 >> 924903 63 31 >> 924904 31 63 >> 924905 0 220 >> 924906 377 0 >> 924909 0 377 >> >> This was discovered with binaries produced with the FMAC Alpha 1 version (hg >> tag fmac_onnv_87). >> >> The internal format of the node address is created in little-endian format. >> >> usr/src/cmd/fmac/checkpolicy/policy_parse.y: >> >> ipv4_addr_def : number '.' number '.' number '.' number >> { >> unsigned int addr; >> unsigned char *p = ((unsigned char *)&addr); >> >> p[0] = $1 & 0xff; >> p[1] = $3 & 0xff; >> p[2] = $5 & 0xff; >> p[3] = $7 & 0xff; >> $$ = addr; >> } >> ; >> >> The node field is then converted to little-endian when it is written to the >> policy file. >> >> usr/src/cmd/fmac/checkpolicy/write.c: >> >> case OCON_NODE: >> buf[0] = SS_CPU_TO_LE32(c->u.node.addr); >> buf[1] = SS_CPU_TO_LE32(c->u.node.mask); >> items = fwrite(buf, sizeof (uint32_t), 2, fp); >> if (items != 2) >> return (-1); >> if (context_write(&c->context[0], fp)) >> return (-1); >> >> Since SS_CPU_TO_LE32() on a little-endian system does not swap the bytes, the >> node field is stored as little-endian on x86 systems. On a SPARC system >> (big-endian), the internal node format is byte swapped by SS_CPU_TO_LE32() thus >> storing the node field as big-endian. This explains the difference in files >> generated on x86 & SPARC. >> >> The node and mask values should be stored in network order in the policy file. >> >> Webrev: http://cr.opensolaris.org/~jweeks/bug-2131/ >> >> Bug report: http://defect.opensolaris.org/bz/show_bug.cgi?id=2131 >> >> >> diff --git a/usr/src/cmd/fmac/checkpolicy/policy_parse.y >> b/usr/src/cmd/fmac/checkpolicy/policy_parse.y >> --- a/usr/src/cmd/fmac/checkpolicy/policy_parse.y >> +++ b/usr/src/cmd/fmac/checkpolicy/policy_parse.y >> @@ -21,6 +21,11 @@ >> */ >> >> /* >> + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. >> + * Use is subject to license terms. >> + */ >> + >> +/* >> * Original files contributed to OpenSolaris.org under license by the >> * United States Government (NSA) to Sun Microsystems, Inc. >> */ >> @@ -34,7 +39,10 @@ >> #include "queue.h" >> #include >> #include >> +#include >> +#include >> #include >> +#include >> #include "checkpolicy.h" >> #include >> #include >> @@ -135,6 +143,7 @@ static int define_node_context(int addr, >> %token IDENTIFIER >> %token USER_IDENTIFIER >> %token NUMBER >> +%token IPV4ADDRESS >> %token EQUALS >> %token NOTEQUAL >> >> @@ -498,16 +507,14 @@ genfs_context_def : GENFSCON identifier >> | GENFSCON identifier path security_context_def >> {if (define_genfs_context(0)) return -1;} >> ; >> -ipv4_addr_def : number '.' number '.' number '.' number >> +ipv4_addr_def : IPV4ADDRESS >> { >> - unsigned int addr; >> - unsigned char *p = ((unsigned char *)&addr); >> - >> - p[0] = $1 & 0xff; >> - p[1] = $3 & 0xff; >> - p[2] = $5 & 0xff; >> - p[3] = $7 & 0xff; >> - $$ = addr; >> + in_addr_t addr; >> + if (inet_pton(AF_INET, yytext, &addr) != 1) { >> + yyerror("invalid IPv4 address"); >> + return -1; >> + } >> + $$ = addr; /* network order */ >> } >> ; >> security_context_def : user_id ':' identifier ':' identifier opt_mls_range_def >> diff --git a/usr/src/cmd/fmac/checkpolicy/policy_scan.l >> b/usr/src/cmd/fmac/checkpolicy/policy_scan.l >> --- a/usr/src/cmd/fmac/checkpolicy/policy_scan.l >> +++ b/usr/src/cmd/fmac/checkpolicy/policy_scan.l >> @@ -20,6 +20,11 @@ >> * 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. >> */ >> >> /* >> @@ -47,8 +52,10 @@ int yywarn(char *msg); >> %p 12500 >> %a 10000 >> %n 2500 >> -letter [A-Za-z] >> -digit [0-9] >> +letter [A-Za-z] >> +digit [0-9] >> +octet ({digit}{1,3}) >> +ipv4address {octet}((\.{octet}){3}) >> %% >> \n.* { strncpy(linebuf[lno], yytext+1, 255); >> linebuf[lno][254] = 0; >> @@ -161,6 +168,7 @@ T2 { return(T2); } >> {letter}({letter}|{digit}|_)* { return(IDENTIFIER); } >> {letter}({letter}|{digit}|_|"."|"-")* { return(USER_IDENTIFIER); } >> {digit}{digit}* { return(NUMBER); } >> +{ipv4address} { return(IPV4ADDRESS); } >> #[^\n]* { /* delete comments */ } >> [ \t\f]+ { /* delete whitespace */ } >> "==" { return(EQUALS); } >> diff --git a/usr/src/cmd/fmac/checkpolicy/write.c >> b/usr/src/cmd/fmac/checkpolicy/write.c >> --- a/usr/src/cmd/fmac/checkpolicy/write.c >> +++ b/usr/src/cmd/fmac/checkpolicy/write.c >> @@ -17,6 +17,11 @@ >> * 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. >> */ >> >> /* >> @@ -735,8 +740,9 @@ policydb_write(policydb_t *p, FILE *fp) >> return (-1); >> break; >> case OCON_NODE: >> - buf[0] = SS_CPU_TO_LE32(c->u.node.addr); >> - buf[1] = SS_CPU_TO_LE32(c->u.node.mask); >> + /* store in network order */ >> + buf[0] = c->u.node.addr; >> + buf[1] = c->u.node.mask; >> items = fwrite(buf, sizeof (uint32_t), 2, fp); >> if (items != 2) >> return (-1); >> diff --git a/usr/src/common/fmac/ss/policydb.c b/usr/src/common/fmac/ss/policydb.c >> --- a/usr/src/common/fmac/ss/policydb.c >> +++ b/usr/src/common/fmac/ss/policydb.c >> @@ -1237,8 +1237,9 @@ policydb_read(policydb_t *p, void *fp) >> fp); >> if (items != 2) >> goto bad; >> - c->u.node.addr = SS_LE32_TO_CPU(buf[0]); >> - c->u.node.mask = SS_LE32_TO_CPU(buf[1]); >> + /* addr and mask stored in network order */ >> + c->u.node.addr = buf[0]; >> + c->u.node.mask = buf[1]; >> if (context_read_and_validate(&c->context[0], >> p, fp)) >> goto bad; > > I made a clarification in the bug report as the above description isn't > quite right. But the patch is correct - we shouldn't be applying > conversions between cpu/host order and little endian on policy > write/read for node addresses/masks that are stored in network order. Pushed to hg.opensolaris.org/hg/fmac/fmac-gate > > Acked-by: Stephen Smalley > From john.weeks at sun.com Mon Jun 9 10:42:00 2008 From: john.weeks at sun.com (John Weeks) Date: Mon, 09 Jun 2008 10:42:00 -0700 Subject: [fmac-discuss] [patch] Lint cleanup Message-ID: <484D6B68.1040807@sun.com> Cleanup of pending lint errors. -John diff --git a/usr/src/common/fmac/ss/avtab.c b/usr/src/common/fmac/ss/avtab.c --- a/usr/src/common/fmac/ss/avtab.c +++ b/usr/src/common/fmac/ss/avtab.c @@ -34,6 +34,8 @@ /* * Implementation of the access vector table type. */ + +#include #if defined(_KERNEL) #include @@ -230,7 +232,6 @@ avtab_hash_eval(avtab_t *h, char *tag) max_chain_len); } -/*ARGSUSED*/ int avtab_read(avtab_t *a, void *fp, uint32_t config) { @@ -241,6 +242,7 @@ avtab_read(avtab_t *a, void *fp, uint32_ uint32_t nel; size_t items, items2; + _NOTE(ARGUNUSED(config)); items = next_entry(&nel, sizeof (uint32_t), 1, fp); if (items != 1) { diff --git a/usr/src/common/fmac/ss/mls.c b/usr/src/common/fmac/ss/mls.c --- a/usr/src/common/fmac/ss/mls.c +++ b/usr/src/common/fmac/ss/mls.c @@ -49,6 +49,7 @@ #endif /* defined(_KERNEL) */ #include +#include #include "ss_impl.h" #include "mls.h" #include "policydb.h" @@ -118,7 +119,6 @@ int int mls_compute_context_len(context_struct_t *context) { - int categories; int i; int l; int len; @@ -176,7 +176,7 @@ mls_compute_context_len(context_struct_t * * Format: sensitivity[:category,...][-sensitivity[:category,...]] */ -int +void mls_sid_to_context(context_struct_t *context, char *scontextp) { int categories; @@ -235,8 +235,6 @@ mls_sid_to_context(context_struct_t *con break; } } - - return (0); } /* @@ -404,8 +402,9 @@ mls_context_to_sid(char oldc, char **sco if (l == 0) { context->range.level[1].sens = context->range.level[0].sens; - ebitmap_cpy(&context->range.level[1].cat, - &context->range.level[0].cat); + if (!ebitmap_cpy(&context->range.level[1].cat, + &context->range.level[0].cat)) + return (ENOMEM); } *scontext = ++p; return (0); @@ -474,11 +473,12 @@ mls_convert_context(policydb_t *oldp, po return (0); } -/*ARGSUSED*/ int mls_compute_sid(context_struct_t *scontext, context_struct_t *tcontext, security_class_t tclass, uint32_t specified, context_struct_t *newcontext) { + _NOTE(ARGUNUSED(tclass)); + switch (specified) { case AVTAB_TRANSITION: case AVTAB_CHANGE: @@ -747,11 +747,12 @@ cat_index(hashtab_key_t key, hashtab_dat return (0); } -/*ARGSUSED*/ int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { level_datum_t *levdatum; + + _NOTE(ARGUNUSED(p)); if (key) SS_FREE(key, strlen(key) + 1); @@ -764,17 +765,17 @@ sens_destroy(hashtab_key_t key, hashtab_ return (0); } -/*ARGSUSED*/ int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { + _NOTE(ARGUNUSED(p)); + if (key) SS_FREE(key, strlen(key) + 1); SS_FREE(datum, sizeof (cat_datum_t)); return (0); } -/*ARGSUSED*/ int sens_read(policydb_t *p, hashtab_t h, void *fp) { @@ -782,6 +783,8 @@ sens_read(policydb_t *p, hashtab_t h, vo level_datum_t *levdatum; uint32_t buf[2], len; int items; + + _NOTE(ARGUNUSED(p)); levdatum = SS_ALLOC_NOSLEEP(sizeof (level_datum_t)); if (!levdatum) @@ -813,12 +816,11 @@ sens_read(policydb_t *p, hashtab_t h, vo return (0); bad: - sens_destroy(key, levdatum, NULL); + (void) sens_destroy(key, levdatum, NULL); return (-1); } -/*ARGSUSED*/ int cat_read(policydb_t *p, hashtab_t h, void *fp) { @@ -826,6 +828,8 @@ cat_read(policydb_t *p, hashtab_t h, voi cat_datum_t *catdatum; uint32_t buf[3], len; int items; + + _NOTE(ARGUNUSED(p)); catdatum = SS_ALLOC_NOSLEEP(sizeof (cat_datum_t)); if (!catdatum) @@ -854,6 +858,6 @@ cat_read(policydb_t *p, hashtab_t h, voi return (0); bad: - cat_destroy(key, catdatum, NULL); + (void) cat_destroy(key, catdatum, NULL); return (-1); } diff --git a/usr/src/common/fmac/ss/mls.h b/usr/src/common/fmac/ss/mls.h --- a/usr/src/common/fmac/ss/mls.h +++ b/usr/src/common/fmac/ss/mls.h @@ -50,7 +50,7 @@ void mls_compute_av(context_struct_t *sc int mls_compute_context_len(context_struct_t * context); -int mls_sid_to_context(context_struct_t *context, char *scontext); +void mls_sid_to_context(context_struct_t *context, char *scontext); int mls_context_isvalid(policydb_t *p, context_struct_t * c); diff --git a/usr/src/common/fmac/ss/policydb.c b/usr/src/common/fmac/ss/policydb.c --- a/usr/src/common/fmac/ss/policydb.c +++ b/usr/src/common/fmac/ss/policydb.c @@ -36,7 +36,7 @@ */ #include - +#include #if defined(_KERNEL) #include @@ -302,22 +302,23 @@ policydb_index_others(policydb_t *p) * free any memory allocated for each kind of * symbol data in the policy database. */ - -/*ARGSUSED*/ static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { + _NOTE(ARGUNUSED(p)); + if (key) SS_FREE(key, strlen(key) + 1); SS_FREE(datum, sizeof (perm_datum_t)); return (0); } -/*ARGSUSED*/ static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { common_datum_t *comdatum; + + _NOTE(ARGUNUSED(p)); if (key) SS_FREE(key, strlen(key) + 1); @@ -328,13 +329,14 @@ common_destroy(hashtab_key_t key, hashta return (0); } -/*ARGSUSED*/ static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { class_datum_t *cladatum; constraint_node_t *constraint, *ctemp; constraint_expr_t *e, *etmp; + + _NOTE(ARGUNUSED(p)); if (key) SS_FREE(key, strlen(key) + 1); @@ -360,11 +362,12 @@ class_destroy(hashtab_key_t key, hashtab return (0); } -/*ARGSUSED*/ static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { role_datum_t *role; + + _NOTE(ARGUNUSED(p)); if (key) SS_FREE(key, strlen(key) + 1); @@ -375,21 +378,23 @@ role_destroy(hashtab_key_t key, hashtab_ return (0); } -/*ARGSUSED*/ static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { + _NOTE(ARGUNUSED(p)); + if (key) SS_FREE(key, strlen(key) + 1); SS_FREE(datum, sizeof (type_datum_t)); return (0); } -/*ARGSUSED*/ static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) { user_datum_t *usrdatum; + + _NOTE(ARGUNUSED(p)); if (key) SS_FREE(key, strlen(key) + 1); @@ -589,8 +594,6 @@ context_read_and_validate(context_struct * read the symbol data from a policy database * binary representation file. */ - -/*ARGSUSED*/ static int perm_read(policydb_t *p, hashtab_t h, void *fp) { @@ -598,6 +601,8 @@ perm_read(policydb_t *p, hashtab_t h, vo perm_datum_t *perdatum; uint32_t buf[2], len; int items, items2; + + _NOTE(ARGUNUSED(p)); perdatum = SS_ALLOC_SLEEP(sizeof (perm_datum_t)); if (!perdatum) @@ -839,7 +844,6 @@ bad: return (-1); } -/*ARGSUSED*/ static int role_read(policydb_t *p, hashtab_t h, void *fp) { @@ -847,6 +851,8 @@ role_read(policydb_t *p, hashtab_t h, vo role_datum_t *role; uint32_t buf[2], len; int items; + + _NOTE(ARGUNUSED(p)); role = SS_ALLOC_SLEEP(sizeof (role_datum_t)); if (!role) @@ -895,7 +901,6 @@ bad: return (-1); } -/*ARGSUSED*/ static int type_read(policydb_t *p, hashtab_t h, void *fp) { @@ -903,6 +908,8 @@ type_read(policydb_t *p, hashtab_t h, vo type_datum_t *typdatum; uint32_t buf[3], len; int items; + + _NOTE(ARGUNUSED(p)); typdatum = SS_ALLOC_SLEEP(sizeof (type_datum_t)); if (!typdatum) @@ -935,7 +942,6 @@ bad: return (-1); } -/*ARGSUSED*/ static int user_read(policydb_t *p, hashtab_t h, void *fp) { @@ -944,6 +950,7 @@ user_read(policydb_t *p, hashtab_t h, vo uint32_t buf[2], len; int items; + _NOTE(ARGUNUSED(p)); usrdatum = SS_ALLOC_SLEEP(sizeof (user_datum_t)); if (!usrdatum) diff --git a/usr/src/common/fmac/ss/services.c b/usr/src/common/fmac/ss/services.c --- a/usr/src/common/fmac/ss/services.c +++ b/usr/src/common/fmac/ss/services.c @@ -39,6 +39,7 @@ #include #include +#include #include #if defined(_KERNEL) @@ -243,6 +244,8 @@ context_struct_compute_av(context_struct avtab_key_t avkey; avtab_datum_t *avdatum; class_datum_t *tclass_datum; + + _NOTE(ARGUNUSED(requested)); if (!tclass || tclass > policydb.p_classes.nprim) { (void) printf("security_compute_av: unrecognized class %d\n", @@ -935,7 +938,6 @@ typedef struct { * context is valid under the new policy. */ -/*ARGSUSED*/ static int convert_context(security_id_t key, context_struct_t *c, void *p) { @@ -947,6 +949,8 @@ convert_context(security_id_t key, conte security_context_t s; uint32_t len; int rc = EINVAL; + + _NOTE(ARGUNUSED(key)); args = (convert_context_args_t *) p; @@ -1157,14 +1161,14 @@ out: * Return the SID of the port specified by * `domain', `type', `protocol', and `port'. */ - -/*ARGSUSED*/ int security_port_sid(uint16_t domain, uint16_t type, uint8_t protocol, uint16_t port, security_id_t *out_sid) { ocontext_t *c; int rc = 0; + + _NOTE(ARGUNUSED(domain, type)); POLICY_RDLOCK; diff --git a/usr/src/common/fmac/ss/symtab.c b/usr/src/common/fmac/ss/symtab.c --- a/usr/src/common/fmac/ss/symtab.c +++ b/usr/src/common/fmac/ss/symtab.c @@ -30,6 +30,8 @@ * Implementation of the symbol table type. */ +#include + #if defined(_KERNEL) #include #else @@ -54,11 +56,12 @@ symhash(hashtab_t h, hashtab_key_t key) return (val & (h->size - 1)); } -/*ARGSUSED*/ static int symcmp(hashtab_t h, hashtab_key_t key1, hashtab_key_t key2) { char *keyp1, *keyp2; + + _NOTE(ARGUNUSED(h)); keyp1 = (char *) key1; keyp2 = (char *) key2; 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 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -519,6 +520,9 @@ avc_audit( uint32_t denied, /* IN */ avc_audit_data_t *a) /* IN */ { + + _NOTE(ARGUNUSED(ae)); + if (a && a->type == AVC_AUDIT_DATA_DONTAUDIT) return; @@ -564,13 +568,12 @@ avc_add_callback(int (*callback)(uint32_ c = (avc_callback_node_t *) kmem_alloc(sizeof (avc_callback_node_t), KM_SLEEP); - if (!c) - return (ENOMEM); c->callback = callback; c->events = events; c->ssid = ssid; c->tsid = tsid; + c->tclass = tclass; c->perms = perms; c->next = avc_callbacks; avc_callbacks = c; From sds at tycho.nsa.gov Mon Jun 9 11:03:37 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 09 Jun 2008 14:03:37 -0400 Subject: [fmac-discuss] [patch] Lint cleanup In-Reply-To: <484D6B68.1040807@sun.com> References: <484D6B68.1040807@sun.com> Message-ID: <1213034617.9375.121.camel@moss-spartans.epoch.ncsc.mil> On Mon, 2008-06-09 at 10:42 -0700, John Weeks wrote: > Cleanup of pending lint errors. Acked-by: Stephen Smalley > -John > > diff --git a/usr/src/common/fmac/ss/avtab.c b/usr/src/common/fmac/ss/avtab.c > --- a/usr/src/common/fmac/ss/avtab.c > +++ b/usr/src/common/fmac/ss/avtab.c > @@ -34,6 +34,8 @@ > /* > * Implementation of the access vector table type. > */ > + > +#include > > #if defined(_KERNEL) > #include > @@ -230,7 +232,6 @@ avtab_hash_eval(avtab_t *h, char *tag) > max_chain_len); > } > > -/*ARGSUSED*/ > int > avtab_read(avtab_t *a, void *fp, uint32_t config) > { > @@ -241,6 +242,7 @@ avtab_read(avtab_t *a, void *fp, uint32_ > uint32_t nel; > size_t items, items2; > > + _NOTE(ARGUNUSED(config)); > > items = next_entry(&nel, sizeof (uint32_t), 1, fp); > if (items != 1) { > diff --git a/usr/src/common/fmac/ss/mls.c b/usr/src/common/fmac/ss/mls.c > --- a/usr/src/common/fmac/ss/mls.c > +++ b/usr/src/common/fmac/ss/mls.c > @@ -49,6 +49,7 @@ > #endif /* defined(_KERNEL) */ > > #include > +#include > #include "ss_impl.h" > #include "mls.h" > #include "policydb.h" > @@ -118,7 +119,6 @@ int > int > mls_compute_context_len(context_struct_t *context) > { > - int categories; > int i; > int l; > int len; > @@ -176,7 +176,7 @@ mls_compute_context_len(context_struct_t > * > * Format: sensitivity[:category,...][-sensitivity[:category,...]] > */ > -int > +void > mls_sid_to_context(context_struct_t *context, char *scontextp) > { > int categories; > @@ -235,8 +235,6 @@ mls_sid_to_context(context_struct_t *con > break; > } > } > - > - return (0); > } > > /* > @@ -404,8 +402,9 @@ mls_context_to_sid(char oldc, char **sco > > if (l == 0) { > context->range.level[1].sens = context->range.level[0].sens; > - ebitmap_cpy(&context->range.level[1].cat, > - &context->range.level[0].cat); > + if (!ebitmap_cpy(&context->range.level[1].cat, > + &context->range.level[0].cat)) > + return (ENOMEM); > } > *scontext = ++p; > return (0); > @@ -474,11 +473,12 @@ mls_convert_context(policydb_t *oldp, po > return (0); > } > > -/*ARGSUSED*/ > int > mls_compute_sid(context_struct_t *scontext, context_struct_t *tcontext, > security_class_t tclass, uint32_t specified, context_struct_t *newcontext) > { > + _NOTE(ARGUNUSED(tclass)); > + > switch (specified) { > case AVTAB_TRANSITION: > case AVTAB_CHANGE: > @@ -747,11 +747,12 @@ cat_index(hashtab_key_t key, hashtab_dat > return (0); > } > > -/*ARGSUSED*/ > int > sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > level_datum_t *levdatum; > + > + _NOTE(ARGUNUSED(p)); > > if (key) > SS_FREE(key, strlen(key) + 1); > @@ -764,17 +765,17 @@ sens_destroy(hashtab_key_t key, hashtab_ > return (0); > } > > -/*ARGSUSED*/ > int > cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > + _NOTE(ARGUNUSED(p)); > + > if (key) > SS_FREE(key, strlen(key) + 1); > SS_FREE(datum, sizeof (cat_datum_t)); > return (0); > } > > -/*ARGSUSED*/ > int > sens_read(policydb_t *p, hashtab_t h, void *fp) > { > @@ -782,6 +783,8 @@ sens_read(policydb_t *p, hashtab_t h, vo > level_datum_t *levdatum; > uint32_t buf[2], len; > int items; > + > + _NOTE(ARGUNUSED(p)); > > levdatum = SS_ALLOC_NOSLEEP(sizeof (level_datum_t)); > if (!levdatum) > @@ -813,12 +816,11 @@ sens_read(policydb_t *p, hashtab_t h, vo > return (0); > > bad: > - sens_destroy(key, levdatum, NULL); > + (void) sens_destroy(key, levdatum, NULL); > return (-1); > } > > > -/*ARGSUSED*/ > int > cat_read(policydb_t *p, hashtab_t h, void *fp) > { > @@ -826,6 +828,8 @@ cat_read(policydb_t *p, hashtab_t h, voi > cat_datum_t *catdatum; > uint32_t buf[3], len; > int items; > + > + _NOTE(ARGUNUSED(p)); > > catdatum = SS_ALLOC_NOSLEEP(sizeof (cat_datum_t)); > if (!catdatum) > @@ -854,6 +858,6 @@ cat_read(policydb_t *p, hashtab_t h, voi > return (0); > > bad: > - cat_destroy(key, catdatum, NULL); > + (void) cat_destroy(key, catdatum, NULL); > return (-1); > } > diff --git a/usr/src/common/fmac/ss/mls.h b/usr/src/common/fmac/ss/mls.h > --- a/usr/src/common/fmac/ss/mls.h > +++ b/usr/src/common/fmac/ss/mls.h > @@ -50,7 +50,7 @@ void mls_compute_av(context_struct_t *sc > > int mls_compute_context_len(context_struct_t * context); > > -int mls_sid_to_context(context_struct_t *context, char *scontext); > +void mls_sid_to_context(context_struct_t *context, char *scontext); > > int mls_context_isvalid(policydb_t *p, context_struct_t * c); > > diff --git a/usr/src/common/fmac/ss/policydb.c b/usr/src/common/fmac/ss/policydb.c > --- a/usr/src/common/fmac/ss/policydb.c > +++ b/usr/src/common/fmac/ss/policydb.c > @@ -36,7 +36,7 @@ > */ > > #include > - > +#include > > #if defined(_KERNEL) > #include > @@ -302,22 +302,23 @@ policydb_index_others(policydb_t *p) > * free any memory allocated for each kind of > * symbol data in the policy database. > */ > - > -/*ARGSUSED*/ > static int > perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > + _NOTE(ARGUNUSED(p)); > + > if (key) > SS_FREE(key, strlen(key) + 1); > SS_FREE(datum, sizeof (perm_datum_t)); > return (0); > } > > -/*ARGSUSED*/ > static int > common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > common_datum_t *comdatum; > + > + _NOTE(ARGUNUSED(p)); > > if (key) > SS_FREE(key, strlen(key) + 1); > @@ -328,13 +329,14 @@ common_destroy(hashtab_key_t key, hashta > return (0); > } > > -/*ARGSUSED*/ > static int > class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > class_datum_t *cladatum; > constraint_node_t *constraint, *ctemp; > constraint_expr_t *e, *etmp; > + > + _NOTE(ARGUNUSED(p)); > > if (key) > SS_FREE(key, strlen(key) + 1); > @@ -360,11 +362,12 @@ class_destroy(hashtab_key_t key, hashtab > return (0); > } > > -/*ARGSUSED*/ > static int > role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > role_datum_t *role; > + > + _NOTE(ARGUNUSED(p)); > > if (key) > SS_FREE(key, strlen(key) + 1); > @@ -375,21 +378,23 @@ role_destroy(hashtab_key_t key, hashtab_ > return (0); > } > > -/*ARGSUSED*/ > static int > type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > + _NOTE(ARGUNUSED(p)); > + > if (key) > SS_FREE(key, strlen(key) + 1); > SS_FREE(datum, sizeof (type_datum_t)); > return (0); > } > > -/*ARGSUSED*/ > static int > user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) > { > user_datum_t *usrdatum; > + > + _NOTE(ARGUNUSED(p)); > > if (key) > SS_FREE(key, strlen(key) + 1); > @@ -589,8 +594,6 @@ context_read_and_validate(context_struct > * read the symbol data from a policy database > * binary representation file. > */ > - > -/*ARGSUSED*/ > static int > perm_read(policydb_t *p, hashtab_t h, void *fp) > { > @@ -598,6 +601,8 @@ perm_read(policydb_t *p, hashtab_t h, vo > perm_datum_t *perdatum; > uint32_t buf[2], len; > int items, items2; > + > + _NOTE(ARGUNUSED(p)); > > perdatum = SS_ALLOC_SLEEP(sizeof (perm_datum_t)); > if (!perdatum) > @@ -839,7 +844,6 @@ bad: > return (-1); > } > > -/*ARGSUSED*/ > static int > role_read(policydb_t *p, hashtab_t h, void *fp) > { > @@ -847,6 +851,8 @@ role_read(policydb_t *p, hashtab_t h, vo > role_datum_t *role; > uint32_t buf[2], len; > int items; > + > + _NOTE(ARGUNUSED(p)); > > role = SS_ALLOC_SLEEP(sizeof (role_datum_t)); > if (!role) > @@ -895,7 +901,6 @@ bad: > return (-1); > } > > -/*ARGSUSED*/ > static int > type_read(policydb_t *p, hashtab_t h, void *fp) > { > @@ -903,6 +908,8 @@ type_read(policydb_t *p, hashtab_t h, vo > type_datum_t *typdatum; > uint32_t buf[3], len; > int items; > + > + _NOTE(ARGUNUSED(p)); > > typdatum = SS_ALLOC_SLEEP(sizeof (type_datum_t)); > if (!typdatum) > @@ -935,7 +942,6 @@ bad: > return (-1); > } > > -/*ARGSUSED*/ > static int > user_read(policydb_t *p, hashtab_t h, void *fp) > { > @@ -944,6 +950,7 @@ user_read(policydb_t *p, hashtab_t h, vo > uint32_t buf[2], len; > int items; > > + _NOTE(ARGUNUSED(p)); > > usrdatum = SS_ALLOC_SLEEP(sizeof (user_datum_t)); > if (!usrdatum) > diff --git a/usr/src/common/fmac/ss/services.c b/usr/src/common/fmac/ss/services.c > --- a/usr/src/common/fmac/ss/services.c > +++ b/usr/src/common/fmac/ss/services.c > @@ -39,6 +39,7 @@ > > #include > #include > +#include > #include > > #if defined(_KERNEL) > @@ -243,6 +244,8 @@ context_struct_compute_av(context_struct > avtab_key_t avkey; > avtab_datum_t *avdatum; > class_datum_t *tclass_datum; > + > + _NOTE(ARGUNUSED(requested)); > > if (!tclass || tclass > policydb.p_classes.nprim) { > (void) printf("security_compute_av: unrecognized class %d\n", > @@ -935,7 +938,6 @@ typedef struct { > * context is valid under the new policy. > */ > > -/*ARGSUSED*/ > static int > convert_context(security_id_t key, context_struct_t *c, void *p) > { > @@ -947,6 +949,8 @@ convert_context(security_id_t key, conte > security_context_t s; > uint32_t len; > int rc = EINVAL; > + > + _NOTE(ARGUNUSED(key)); > > args = (convert_context_args_t *) p; > > @@ -1157,14 +1161,14 @@ out: > * Return the SID of the port specified by > * `domain', `type', `protocol', and `port'. > */ > - > -/*ARGSUSED*/ > int > security_port_sid(uint16_t domain, uint16_t type, uint8_t protocol, > uint16_t port, security_id_t *out_sid) > { > ocontext_t *c; > int rc = 0; > + > + _NOTE(ARGUNUSED(domain, type)); > > POLICY_RDLOCK; > > diff --git a/usr/src/common/fmac/ss/symtab.c b/usr/src/common/fmac/ss/symtab.c > --- a/usr/src/common/fmac/ss/symtab.c > +++ b/usr/src/common/fmac/ss/symtab.c > @@ -30,6 +30,8 @@ > * Implementation of the symbol table type. > */ > > +#include > + > #if defined(_KERNEL) > #include > #else > @@ -54,11 +56,12 @@ symhash(hashtab_t h, hashtab_key_t key) > return (val & (h->size - 1)); > } > > -/*ARGSUSED*/ > static int > symcmp(hashtab_t h, hashtab_key_t key1, hashtab_key_t key2) > { > char *keyp1, *keyp2; > + > + _NOTE(ARGUNUSED(h)); > > keyp1 = (char *) key1; > keyp2 = (char *) key2; > 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 > @@ -49,6 +49,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -519,6 +520,9 @@ avc_audit( > uint32_t denied, /* IN */ > avc_audit_data_t *a) /* IN */ > { > + > + _NOTE(ARGUNUSED(ae)); > + > if (a && a->type == AVC_AUDIT_DATA_DONTAUDIT) > return; > > @@ -564,13 +568,12 @@ avc_add_callback(int (*callback)(uint32_ > > c = (avc_callback_node_t *) kmem_alloc(sizeof (avc_callback_node_t), > KM_SLEEP); > - if (!c) > - return (ENOMEM); > > c->callback = callback; > c->events = events; > c->ssid = ssid; > c->tsid = tsid; > + c->tclass = tclass; > c->perms = perms; > c->next = avc_callbacks; > avc_callbacks = c; > _______________________________________________ > fmac-discuss mailing list > fmac-discuss at opensolaris.org > http://mail.opensolaris.org/mailman/listinfo/fmac-discuss -- Stephen Smalley National Security Agency From john.weeks at sun.com Tue Jun 10 06:58:43 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 10 Jun 2008 06:58:43 -0700 Subject: [fmac-discuss] [patch] Lint cleanup In-Reply-To: <1213034617.9375.121.camel@moss-spartans.epoch.ncsc.mil> References: <484D6B68.1040807@sun.com> <1213034617.9375.121.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <484E8893.1020908@sun.com> Stephen Smalley wrote: > On Mon, 2008-06-09 at 10:42 -0700, John Weeks wrote: >> Cleanup of pending lint errors. > > Acked-by: Stephen Smalley Pushed to hg.opensolaris.org/hg/fmac/fmac-gate > >> -John >> >> diff --git a/usr/src/common/fmac/ss/avtab.c b/usr/src/common/fmac/ss/avtab.c >> --- a/usr/src/common/fmac/ss/avtab.c >> +++ b/usr/src/common/fmac/ss/avtab.c >> @@ -34,6 +34,8 @@ >> /* >> * Implementation of the access vector table type. >> */ >> + >> +#include >> >> #if defined(_KERNEL) >> #include >> @@ -230,7 +232,6 @@ avtab_hash_eval(avtab_t *h, char *tag) >> max_chain_len); >> } >> >> -/*ARGSUSED*/ >> int >> avtab_read(avtab_t *a, void *fp, uint32_t config) >> { >> @@ -241,6 +242,7 @@ avtab_read(avtab_t *a, void *fp, uint32_ >> uint32_t nel; >> size_t items, items2; >> >> + _NOTE(ARGUNUSED(config)); >> >> items = next_entry(&nel, sizeof (uint32_t), 1, fp); >> if (items != 1) { >> diff --git a/usr/src/common/fmac/ss/mls.c b/usr/src/common/fmac/ss/mls.c >> --- a/usr/src/common/fmac/ss/mls.c >> +++ b/usr/src/common/fmac/ss/mls.c >> @@ -49,6 +49,7 @@ >> #endif /* defined(_KERNEL) */ >> >> #include >> +#include >> #include "ss_impl.h" >> #include "mls.h" >> #include "policydb.h" >> @@ -118,7 +119,6 @@ int >> int >> mls_compute_context_len(context_struct_t *context) >> { >> - int categories; >> int i; >> int l; >> int len; >> @@ -176,7 +176,7 @@ mls_compute_context_len(context_struct_t >> * >> * Format: sensitivity[:category,...][-sensitivity[:category,...]] >> */ >> -int >> +void >> mls_sid_to_context(context_struct_t *context, char *scontextp) >> { >> int categories; >> @@ -235,8 +235,6 @@ mls_sid_to_context(context_struct_t *con >> break; >> } >> } >> - >> - return (0); >> } >> >> /* >> @@ -404,8 +402,9 @@ mls_context_to_sid(char oldc, char **sco >> >> if (l == 0) { >> context->range.level[1].sens = context->range.level[0].sens; >> - ebitmap_cpy(&context->range.level[1].cat, >> - &context->range.level[0].cat); >> + if (!ebitmap_cpy(&context->range.level[1].cat, >> + &context->range.level[0].cat)) >> + return (ENOMEM); >> } >> *scontext = ++p; >> return (0); >> @@ -474,11 +473,12 @@ mls_convert_context(policydb_t *oldp, po >> return (0); >> } >> >> -/*ARGSUSED*/ >> int >> mls_compute_sid(context_struct_t *scontext, context_struct_t *tcontext, >> security_class_t tclass, uint32_t specified, context_struct_t *newcontext) >> { >> + _NOTE(ARGUNUSED(tclass)); >> + >> switch (specified) { >> case AVTAB_TRANSITION: >> case AVTAB_CHANGE: >> @@ -747,11 +747,12 @@ cat_index(hashtab_key_t key, hashtab_dat >> return (0); >> } >> >> -/*ARGSUSED*/ >> int >> sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> level_datum_t *levdatum; >> + >> + _NOTE(ARGUNUSED(p)); >> >> if (key) >> SS_FREE(key, strlen(key) + 1); >> @@ -764,17 +765,17 @@ sens_destroy(hashtab_key_t key, hashtab_ >> return (0); >> } >> >> -/*ARGSUSED*/ >> int >> cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> + _NOTE(ARGUNUSED(p)); >> + >> if (key) >> SS_FREE(key, strlen(key) + 1); >> SS_FREE(datum, sizeof (cat_datum_t)); >> return (0); >> } >> >> -/*ARGSUSED*/ >> int >> sens_read(policydb_t *p, hashtab_t h, void *fp) >> { >> @@ -782,6 +783,8 @@ sens_read(policydb_t *p, hashtab_t h, vo >> level_datum_t *levdatum; >> uint32_t buf[2], len; >> int items; >> + >> + _NOTE(ARGUNUSED(p)); >> >> levdatum = SS_ALLOC_NOSLEEP(sizeof (level_datum_t)); >> if (!levdatum) >> @@ -813,12 +816,11 @@ sens_read(policydb_t *p, hashtab_t h, vo >> return (0); >> >> bad: >> - sens_destroy(key, levdatum, NULL); >> + (void) sens_destroy(key, levdatum, NULL); >> return (-1); >> } >> >> >> -/*ARGSUSED*/ >> int >> cat_read(policydb_t *p, hashtab_t h, void *fp) >> { >> @@ -826,6 +828,8 @@ cat_read(policydb_t *p, hashtab_t h, voi >> cat_datum_t *catdatum; >> uint32_t buf[3], len; >> int items; >> + >> + _NOTE(ARGUNUSED(p)); >> >> catdatum = SS_ALLOC_NOSLEEP(sizeof (cat_datum_t)); >> if (!catdatum) >> @@ -854,6 +858,6 @@ cat_read(policydb_t *p, hashtab_t h, voi >> return (0); >> >> bad: >> - cat_destroy(key, catdatum, NULL); >> + (void) cat_destroy(key, catdatum, NULL); >> return (-1); >> } >> diff --git a/usr/src/common/fmac/ss/mls.h b/usr/src/common/fmac/ss/mls.h >> --- a/usr/src/common/fmac/ss/mls.h >> +++ b/usr/src/common/fmac/ss/mls.h >> @@ -50,7 +50,7 @@ void mls_compute_av(context_struct_t *sc >> >> int mls_compute_context_len(context_struct_t * context); >> >> -int mls_sid_to_context(context_struct_t *context, char *scontext); >> +void mls_sid_to_context(context_struct_t *context, char *scontext); >> >> int mls_context_isvalid(policydb_t *p, context_struct_t * c); >> >> diff --git a/usr/src/common/fmac/ss/policydb.c b/usr/src/common/fmac/ss/policydb.c >> --- a/usr/src/common/fmac/ss/policydb.c >> +++ b/usr/src/common/fmac/ss/policydb.c >> @@ -36,7 +36,7 @@ >> */ >> >> #include >> - >> +#include >> >> #if defined(_KERNEL) >> #include >> @@ -302,22 +302,23 @@ policydb_index_others(policydb_t *p) >> * free any memory allocated for each kind of >> * symbol data in the policy database. >> */ >> - >> -/*ARGSUSED*/ >> static int >> perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> + _NOTE(ARGUNUSED(p)); >> + >> if (key) >> SS_FREE(key, strlen(key) + 1); >> SS_FREE(datum, sizeof (perm_datum_t)); >> return (0); >> } >> >> -/*ARGSUSED*/ >> static int >> common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> common_datum_t *comdatum; >> + >> + _NOTE(ARGUNUSED(p)); >> >> if (key) >> SS_FREE(key, strlen(key) + 1); >> @@ -328,13 +329,14 @@ common_destroy(hashtab_key_t key, hashta >> return (0); >> } >> >> -/*ARGSUSED*/ >> static int >> class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> class_datum_t *cladatum; >> constraint_node_t *constraint, *ctemp; >> constraint_expr_t *e, *etmp; >> + >> + _NOTE(ARGUNUSED(p)); >> >> if (key) >> SS_FREE(key, strlen(key) + 1); >> @@ -360,11 +362,12 @@ class_destroy(hashtab_key_t key, hashtab >> return (0); >> } >> >> -/*ARGSUSED*/ >> static int >> role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> role_datum_t *role; >> + >> + _NOTE(ARGUNUSED(p)); >> >> if (key) >> SS_FREE(key, strlen(key) + 1); >> @@ -375,21 +378,23 @@ role_destroy(hashtab_key_t key, hashtab_ >> return (0); >> } >> >> -/*ARGSUSED*/ >> static int >> type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> + _NOTE(ARGUNUSED(p)); >> + >> if (key) >> SS_FREE(key, strlen(key) + 1); >> SS_FREE(datum, sizeof (type_datum_t)); >> return (0); >> } >> >> -/*ARGSUSED*/ >> static int >> user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p) >> { >> user_datum_t *usrdatum; >> + >> + _NOTE(ARGUNUSED(p)); >> >> if (key) >> SS_FREE(key, strlen(key) + 1); >> @@ -589,8 +594,6 @@ context_read_and_validate(context_struct >> * read the symbol data from a policy database >> * binary representation file. >> */ >> - >> -/*ARGSUSED*/ >> static int >> perm_read(policydb_t *p, hashtab_t h, void *fp) >> { >> @@ -598,6 +601,8 @@ perm_read(policydb_t *p, hashtab_t h, vo >> perm_datum_t *perdatum; >> uint32_t buf[2], len; >> int items, items2; >> + >> + _NOTE(ARGUNUSED(p)); >> >> perdatum = SS_ALLOC_SLEEP(sizeof (perm_datum_t)); >> if (!perdatum) >> @@ -839,7 +844,6 @@ bad: >> return (-1); >> } >> >> -/*ARGSUSED*/ >> static int >> role_read(policydb_t *p, hashtab_t h, void *fp) >> { >> @@ -847,6 +851,8 @@ role_read(policydb_t *p, hashtab_t h, vo >> role_datum_t *role; >> uint32_t buf[2], len; >> int items; >> + >> + _NOTE(ARGUNUSED(p)); >> >> role = SS_ALLOC_SLEEP(sizeof (role_datum_t)); >> if (!role) >> @@ -895,7 +901,6 @@ bad: >> return (-1); >> } >> >> -/*ARGSUSED*/ >> static int >> type_read(policydb_t *p, hashtab_t h, void *fp) >> { >> @@ -903,6 +908,8 @@ type_read(policydb_t *p, hashtab_t h, vo >> type_datum_t *typdatum; >> uint32_t buf[3], len; >> int items; >> + >> + _NOTE(ARGUNUSED(p)); >> >> typdatum = SS_ALLOC_SLEEP(sizeof (type_datum_t)); >> if (!typdatum) >> @@ -935,7 +942,6 @@ bad: >> return (-1); >> } >> >> -/*ARGSUSED*/ >> static int >> user_read(policydb_t *p, hashtab_t h, void *fp) >> { >> @@ -944,6 +950,7 @@ user_read(policydb_t *p, hashtab_t h, vo >> uint32_t buf[2], len; >> int items; >> >> + _NOTE(ARGUNUSED(p)); >> >> usrdatum = SS_ALLOC_SLEEP(sizeof (user_datum_t)); >> if (!usrdatum) >> diff --git a/usr/src/common/fmac/ss/services.c b/usr/src/common/fmac/ss/services.c >> --- a/usr/src/common/fmac/ss/services.c >> +++ b/usr/src/common/fmac/ss/services.c >> @@ -39,6 +39,7 @@ >> >> #include >> #include >> +#include >> #include >> >> #if defined(_KERNEL) >> @@ -243,6 +244,8 @@ context_struct_compute_av(context_struct >> avtab_key_t avkey; >> avtab_datum_t *avdatum; >> class_datum_t *tclass_datum; >> + >> + _NOTE(ARGUNUSED(requested)); >> >> if (!tclass || tclass > policydb.p_classes.nprim) { >> (void) printf("security_compute_av: unrecognized class %d\n", >> @@ -935,7 +938,6 @@ typedef struct { >> * context is valid under the new policy. >> */ >> >> -/*ARGSUSED*/ >> static int >> convert_context(security_id_t key, context_struct_t *c, void *p) >> { >> @@ -947,6 +949,8 @@ convert_context(security_id_t key, conte >> security_context_t s; >> uint32_t len; >> int rc = EINVAL; >> + >> + _NOTE(ARGUNUSED(key)); >> >> args = (convert_context_args_t *) p; >> >> @@ -1157,14 +1161,14 @@ out: >> * Return the SID of the port specified by >> * `domain', `type', `protocol', and `port'. >> */ >> - >> -/*ARGSUSED*/ >> int >> security_port_sid(uint16_t domain, uint16_t type, uint8_t protocol, >> uint16_t port, security_id_t *out_sid) >> { >> ocontext_t *c; >> int rc = 0; >> + >> + _NOTE(ARGUNUSED(domain, type)); >> >> POLICY_RDLOCK; >> >> diff --git a/usr/src/common/fmac/ss/symtab.c b/usr/src/common/fmac/ss/symtab.c >> --- a/usr/src/common/fmac/ss/symtab.c >> +++ b/usr/src/common/fmac/ss/symtab.c >> @@ -30,6 +30,8 @@ >> * Implementation of the symbol table type. >> */ >> >> +#include >> + >> #if defined(_KERNEL) >> #include >> #else >> @@ -54,11 +56,12 @@ symhash(hashtab_t h, hashtab_key_t key) >> return (val & (h->size - 1)); >> } >> >> -/*ARGSUSED*/ >> static int >> symcmp(hashtab_t h, hashtab_key_t key1, hashtab_key_t key2) >> { >> char *keyp1, *keyp2; >> + >> + _NOTE(ARGUNUSED(h)); >> >> keyp1 = (char *) key1; >> keyp2 = (char *) key2; >> 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 >> @@ -49,6 +49,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -519,6 +520,9 @@ avc_audit( >> uint32_t denied, /* IN */ >> avc_audit_data_t *a) /* IN */ >> { >> + >> + _NOTE(ARGUNUSED(ae)); >> + >> if (a && a->type == AVC_AUDIT_DATA_DONTAUDIT) >> return; >> >> @@ -564,13 +568,12 @@ avc_add_callback(int (*callback)(uint32_ >> >> c = (avc_callback_node_t *) kmem_alloc(sizeof (avc_callback_node_t), >> KM_SLEEP); >> - if (!c) >> - return (ENOMEM); >> >> c->callback = callback; >> c->events = events; >> c->ssid = ssid; >> c->tsid = tsid; >> + c->tclass = tclass; >> c->perms = perms; >> c->next = avc_callbacks; >> avc_callbacks = c; >> _______________________________________________ >> fmac-discuss mailing list >> fmac-discuss at opensolaris.org >> http://mail.opensolaris.org/mailman/listinfo/fmac-discuss From john.weeks at sun.com Wed Jun 18 15:03:09 2008 From: john.weeks at sun.com (John Weeks) Date: Wed, 18 Jun 2008 15:03:09 -0700 Subject: [fmac-discuss] [PATCH] First FMAC System Calls Message-ID: <4859861D.2080505@sun.com> This patch includes the first FMAC related system calls, a new utility (loadpolicy) and policy boot parameters. Other related FMAC policy control changes are also included. New Utilities: loadpolicy - load FMAC policy file loadpolicy file New System Calls: #include int security_load_policy(char *path); int security_compute_av(security_context_t scontext, security_context_t tcontext, security_class_t tclass, access_vector_t request, struct av_decision *avd); int security_check_context(security_context_t scontext); int security_getenforce(void); int security_setenforce(int mode); int is_fmac_enabled(void); The system calls above are modeled after their SELinux counterparts. I would have provided manpages for the interfaces, but I'm still waiting for an inbound source review of libselinux where the manpage sources for the interfaces resides. truss(1) was modified to accommodate the new systems calls. Additional work to translate class, permission, and AVC return values will be done when we have equivalent libselinux translation functions available. Normally I would not introduce "dead" code into the kernel, but I have included the following stub functions in uts/common/syscall/fmacsys.c for the next round of system call development: int getcon(security_context_t scontext) int getpidcon(pid_t pid, security_context_t scontext) int fmacsys_getexeccon(security_context_t scontext) int fmacsys_setexeccon(security_context_t scontext) int getfilecon(const char *path, security_context_t *con) int lgetfilecon(const char *path, security_context_t *con) int fgetfilecon(int fd, security_context_t *con) int setfilecon(const char *path, security_context_t con) int fsetfilecon(int fd, security_context_t con) int lsetfilecon(const char *path, security_context_t con) My original plan was to share existing labelsys() system call, but I wasn't happy with the resulting implementation. So, I created an FMAC specific syscall #127 fmacsys(). This also simplified the truss enhancements for the new system calls. FMAC Kernel Policy Defaults: int fmac_enabled = 1; /* enforcing */ int fmac_enforcing = 0; /* permissive */ The defaults above will probably change as the project progresses. If fmac_enabled is set to 1 and the kernel can't load or parse the policy file, the system will now panic (a security feature). New FMAC Boot Arguments (-p policy flags): -p [disabled|enforcing|permissive] Since these are boot arguments, I decided not to prefix the names with fmac since it just makes them longer. If we run into collisions, we can always adjust as necessary. It's possible to boot single user with polity disabled to diagnose a policy load panic situation: -p disabled -m milestone=single-user Argument translation to internal control variables: disabled: fmac_enabled = 0; enforcing: fmac_enabled = 1; fmac_enforcing = 1; permissive: fmac_enabled = 1; fmac_enforcing = 0; Policy boot arguments take precedence over defaults and /etc/system overrides. /etc/system Policy Overrides: set fmac_enabled = 0 /* disabled */ set fmac_enabled = 1 /* enabled */ set fmac_enforcing = 0 /* permissive */ set fmac_enforcing = 1 /* enforcing */ set fmac_default_policy_file = "/ss_policy" Webrev: http://cr.opensolaris.org/~jweeks/first_fmac_syscalls/ -John 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 @@ -27,9 +27,14 @@ include ../Makefile.cmd -SUBDIRS = checkpolicy \ +SUBDIR_CMD = checkpolicy \ setfiles \ + loadpolicy + +SUBDIR_POLICY = \ policy + +SUBDIRS = $(SUBDIR_CMD) $(SUBDIR_POLICY) all := TARGET = all install := TARGET = install @@ -44,3 +49,5 @@ all install line clean clobber: $(SUBDIR $(SUBDIRS): @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET) + +_msg: $(SUBDIR_CMD) diff --git a/usr/src/cmd/fmac/loadpolicy/Makefile b/usr/src/cmd/fmac/loadpolicy/Makefile new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/loadpolicy/Makefile @@ -0,0 +1,44 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= loadpolicy + +include ../../Makefile.cmd + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTSBINPROG) + +clean: + +lint: lint_PROG + +include ../../Makefile.targ diff --git a/usr/src/cmd/fmac/loadpolicy/loadpolicy.c b/usr/src/cmd/fmac/loadpolicy/loadpolicy.c new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/loadpolicy/loadpolicy.c @@ -0,0 +1,76 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Load security policy from the specified file. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char *path; + int errflg = 0; + int c; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + (void) textdomain(TEXT_DOMAIN); + + while ((c = getopt(argc, argv, "")) != EOF) { + switch (c) { + case '?': + errflg++; + break; + } + } + + if (errflg || argc != 2) { + (void) fprintf(stderr, gettext("usage: loadpolicy file\n")); + return (1); + } + + path = *++argv; + + if (security_load_policy(path)) { + (void) fprintf(stderr, + gettext("loadpolicy: policy load of %s failed: %s\n"), + path, strerror(errno)); + return (1); + } + + return (0); +} 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 @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -349,7 +349,7 @@ const struct systable systable[] = { {"lxstat", 3, DEC, NOV, DEC, STG, HEX}, /* 124 */ {"fxstat", 3, DEC, NOV, DEC, DEC, HEX}, /* 125 */ {"xmknod", 4, DEC, NOV, DEC, STG, OCT, HEX}, /* 126 */ -{ NULL, 8, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX, HEX}, +{"fmacsys", 6, UNS, UNS, DEC, HEX, HEX, HEX, HEX, HEX}, /* 127 */ {"setrlimit", 2, DEC, NOV, RLM, HEX}, /* 128 */ {"getrlimit", 2, DEC, NOV, RLM, HEX}, /* 129 */ {"lchown", 3, DEC, NOV, STG, DEC, DEC}, /* 130 */ @@ -839,6 +839,16 @@ 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_load_policy", 2, UNS, UNS, HID, STG}, /* 2 */ +{"is_fmac_enabled", 1, DEC, NOV, HID}, /* 3 */ +{"security_compute_av", 6, DEC, NOV, HID, STG, STG, DEC, DEC, HEX}, /* 4 */ +{"security_check_context", 2, DEC, NOV, HID, STG}, /* 5 */ +}; +#define NFMACSYSCODE (sizeof (fmacsystable) / sizeof (struct systable)) + const struct sysalias sysalias[] = { { "exit", SYS_exit }, { "fork", SYS_forksys }, @@ -996,6 +1006,12 @@ const struct sysalias sysalias[] = { { "rctlsys_lst", SYS_rctlsys }, { "rctlsys_ctl", SYS_rctlsys }, { "allocids", SYS_sidsys }, + { "security_getenforce", SYS_fmacsys }, + { "security_setenforce", SYS_fmacsys }, + { "security_load_policy", SYS_fmacsys }, + { "is_fmac_enabled ", SYS_fmacsys }, + { "security_compute_av", SYS_fmacsys }, + { "security_check_context", SYS_fmacsys }, { NULL, 0 } /* end-of-list */ }; @@ -1144,6 +1160,10 @@ subsys(int syscall, int subcode) case SYS_sidsys: /* SID family */ if ((unsigned)subcode < NSIDSYSCODE) stp = &sidsystable[subcode]; + break; + case SYS_fmacsys: /* FMAC family */ + if ((unsigned)subcode < NFMACSYSCODE) + stp = &fmacsystable[subcode]; break; } } @@ -1305,6 +1325,7 @@ getsubcode(private_t *pri) case SYS_labelsys: /* labelsys */ case SYS_rctlsys: /* rctlsys */ case SYS_sidsys: /* sidsys */ + case SYS_fmacsys: /* fmacsys */ subcode = arg0; break; case SYS_fcntl: /* fcntl() */ @@ -1446,6 +1467,8 @@ nsubcodes(int syscall) return (NFORKCODE); case SYS_sidsys: return (NSIDSYSCODE); + case SYS_fmacsys: + return (NFMACSYSCODE); default: return (1); } diff --git a/usr/src/common/fmac/ss/services.c b/usr/src/common/fmac/ss/services.c --- a/usr/src/common/fmac/ss/services.c +++ b/usr/src/common/fmac/ss/services.c @@ -611,7 +611,7 @@ compute_sid_handle_invalid_context(conte context_struct_t *tcontext, security_class_t tclass, context_struct_t *newcontext) { - if (flask_enforcing) { + if (fmac_enforcing) { return (EACCES); } else { security_context_t s, t, n; @@ -912,7 +912,7 @@ static inline int static inline int convert_context_handle_invalid_context(context_struct_t *context) { - if (flask_enforcing) { + if (fmac_enforcing) { return (EINVAL); } else { security_context_t s; diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile --- a/usr/src/head/Makefile +++ b/usr/src/head/Makefile @@ -279,6 +279,8 @@ LVMRPCHDRS = \ LVMRPCHDRS = \ mhdx.h mdiox.h meta_basic.h metad.h metamed.h metamhd.h metacl.h +FMACHDRS = fmac.h + SYMHDRASSERT = $(ROOT)/usr/include/iso/assert_iso.h SYMHDRERRNO = $(ROOT)/usr/include/iso/errno_iso.h SYMHDRFLOAT = $(ROOT)/usr/include/iso/float_iso.h @@ -324,9 +326,10 @@ ROOTHDRS= $(HDRS:%=$(ROOT)/usr/include/% $(RPCSVCHDRS:%=$(ROOT)/usr/include/rpcsvc/%) \ $(RPCSVCPROTS:%=$(ROOT)/usr/include/rpcsvc/%) \ $(LVMRPCHDRS:%=$(ROOT)/usr/include/%) \ - $(PROTOHDRS:%=$(ROOT)/usr/include/protocols/%) + $(PROTOHDRS:%=$(ROOT)/usr/include/protocols/%) \ + $(FMACHDRS:%=$(ROOT)/usr/include/fmac/%) -DIRS= iso arpa audio rpcsvc protocols security uuid kerberosv5 +DIRS= iso arpa audio rpcsvc protocols security uuid kerberosv5 fmac ROOTDIRS= $(DIRS:%=$(ROOT)/usr/include/%) SED= sed @@ -359,6 +362,9 @@ uuid/%.check: uuid/%.h uuid/%.check: uuid/%.h $(DOT_H_CHECK) +fmac/%.check: fmac/%.h + $(DOT_H_CHECK) + # Note that the derived headers (rpcgen) are not checked at this time. These # need work at the source level and rpcgen itself has a bug which causes a # cstyle violation. Furthermore, there seems to be good reasons for the @@ -374,7 +380,9 @@ CHECKHDRS= $(HDRS:%.h=%.check) \ $(AUDIOHDRS:%.h=audio/%.check) \ $(UUIDHDRS:%.h=uuid/%.check) \ $(RPCSVC_SRC_HDRS:%.h=rpcsvc/%.check) \ - $(PROTOHDRS:%.h=protocols/%.check) + $(PROTOHDRS:%.h=protocols/%.check) \ + $(FMACHDRS:%.h=fmac/%.check) + # headers which won't quite meet the standards... # @@ -408,6 +416,9 @@ assert.check := HDRCHK_TAIL = | grep -v $(INS.file) $(ROOT)/usr/include/uuid/%: uuid/% + $(INS.file) + +$(ROOT)/usr/include/fmac/%: fmac/% $(INS.file) $(ROOT)/usr/include/%: % diff --git a/usr/src/head/fmac/fmac.h b/usr/src/head/fmac/fmac.h new file mode 100644 --- /dev/null +++ b/usr/src/head/fmac/fmac.h @@ -0,0 +1,56 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FMAC_H +#define _FMAC_H + +/* + * Flexible Mandatory Access Control (FMAC) + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +int security_load_policy(char *path); + +int security_compute_av(security_context_t scontext, + security_context_t tcontext, security_class_t tclass, + access_vector_t request, struct av_decision *avd); + +int security_check_context(security_context_t scontext); +int security_getenforce(void); +int security_setenforce(int mode); +int is_fmac_enabled(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _FMAC_H */ diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -792,6 +792,7 @@ PORTSYS= \ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -832,6 +832,7 @@ PORTSYS= \ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \ 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 @@ -492,6 +492,7 @@ extern "C" { #define isastream _isastream #define isatty _isatty #define isenglish _isenglish +#define is_fmac_enabled _is_fmac_enabled #define isideogram _isideogram #define isnumber _isnumber #define isphonogram _isphonogram @@ -880,6 +881,11 @@ extern "C" { #define schedctl_lookup _schedctl_lookup #define scrwidth _scrwidth #define seconvert _seconvert +#define security_check_context _security_check_context +#define security_compute_av _security_compute_av +#define security_getenforce _security_getenforce +#define security_load_policy _security_load_policy +#define security_setenforce _security_setenforce #define seed48 _seed48 #define seekdir _seekdir #define select _select 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 @@ -74,6 +74,7 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11) _getpagesizes2; htonl; htons; + is_fmac_enabled; lio_listio; mkdtemp; _mkdtemp; @@ -106,6 +107,11 @@ SUNW_1.23 { # SunOS 5.11 (Solaris 11) sched_setparam; sched_setscheduler; sched_yield; + security_check_context; + security_compute_av; + security_getenforce; + security_load_policy; + security_setenforce; sem_close; sem_destroy; sem_getvalue; diff --git a/usr/src/lib/libc/port/sys/fmacsys.c b/usr/src/lib/libc/port/sys/fmacsys.c new file mode 100644 --- /dev/null +++ b/usr/src/lib/libc/port/sys/fmacsys.c @@ -0,0 +1,75 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak security_load_policy = _security_load_policy +#pragma weak security_compute_av = _security_compute_av +#pragma weak security_check_context = _security_check_context +#pragma weak security_getenforce = _security_getenforce +#pragma weak security_setenforce = _security_setenforce +#pragma weak is_fmac_enabled = _is_fmac_enabled + +#include "synonyms.h" +#include +#include +#include + +int +security_load_policy(char *path) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYLOADPOLICY, path)); +} + +int +security_compute_av(security_context_t scontext, security_context_t tcontext, + security_class_t tclass, access_vector_t request, struct av_decision *avd) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYCOMPUTEAV, scontext, + tcontext, tclass, request, avd)); +} + +int +security_check_context(security_context_t scontext) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYCHECKCONTEXT, scontext)); +} + +int +security_getenforce() +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYGETENFORCE)); +} + +int +security_setenforce(int mode) +{ + return (syscall(SYS_fmacsys, FMACSYS_SECURITYSETENFORCE, mode)); +} + +int +is_fmac_enabled() +{ + return (syscall(SYS_fmacsys, FMACSYS_ISFMACENABLED)); +} diff --git a/usr/src/lib/libc/sparc/Makefile b/usr/src/lib/libc/sparc/Makefile --- a/usr/src/lib/libc/sparc/Makefile +++ b/usr/src/lib/libc/sparc/Makefile @@ -857,6 +857,7 @@ PORTSYS= \ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \ diff --git a/usr/src/lib/libc/sparcv9/Makefile b/usr/src/lib/libc/sparcv9/Makefile --- a/usr/src/lib/libc/sparcv9/Makefile +++ b/usr/src/lib/libc/sparcv9/Makefile @@ -801,6 +801,7 @@ PORTSYS= \ execle.o \ execv.o \ faccessat.o \ + fmacsys.o \ fsmisc.o \ fstatat.o \ getpagesizes.o \ diff --git a/usr/src/lib/libproc/common/proc_names.c b/usr/src/lib/libproc/common/proc_names.c --- a/usr/src/lib/libproc/common/proc_names.c +++ b/usr/src/lib/libproc/common/proc_names.c @@ -245,7 +245,7 @@ static const char *const systable[] = { "lxstat", /* 124 */ "fxstat", /* 125 */ "xmknod", /* 126 */ - "NULL", /* 127 */ + "fmacsys", /* 127 */ "setrlimit", /* 128 */ "getrlimit", /* 129 */ "lchown", /* 130 */ diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com --- a/usr/src/pkgdefs/SUNWcsr/prototype_com +++ b/usr/src/pkgdefs/SUNWcsr/prototype_com @@ -406,6 +406,7 @@ f none sbin/ifconfig 555 root bin f none sbin/ifconfig 555 root bin f none sbin/ifparse 555 root bin s none sbin/in.mpathd=../usr/lib/inet/in.mpathd +f none sbin/loadpolicy 555 root bin f none sbin/soconfig 555 root bin f none sbin/init 555 root sys s none sbin/jsh=sh diff --git a/usr/src/pkgdefs/SUNWhea/prototype_com b/usr/src/pkgdefs/SUNWhea/prototype_com --- a/usr/src/pkgdefs/SUNWhea/prototype_com +++ b/usr/src/pkgdefs/SUNWhea/prototype_com @@ -218,6 +218,8 @@ f none usr/include/fatal.h 644 root bin f none usr/include/fatal.h 644 root bin f none usr/include/fcntl.h 644 root bin f none usr/include/float.h 644 root bin +d none usr/include/fmac 755 root bin +f none usr/include/fmac/fmac.h 644 root bin f none usr/include/fmtmsg.h 644 root bin f none usr/include/fnmatch.h 644 root bin f none usr/include/form.h 644 root bin diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -164,6 +164,7 @@ GENUNIX_OBJS += \ flock.o \ fm.o \ fmac.o \ + fmacsys.o \ $(FMAC_MLS_OBJS) \ fork.o \ vpm.o \ 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 @@ -922,7 +922,7 @@ avc_has_perm_ref_audit( if (!requested || (denied & ae->avd.auditdeny)) avc_audit(ssid, tsid, tclass, denied, ae, AVC_AUDITDENY, auditdata); - if (flask_enforcing) { + if (fmac_enforcing) { mutex_exit(&avc_lock); return (EACCES); } else { diff --git a/usr/src/uts/common/fmac/fmac.c b/usr/src/uts/common/fmac/fmac.c --- a/usr/src/uts/common/fmac/fmac.c +++ b/usr/src/uts/common/fmac/fmac.c @@ -32,21 +32,69 @@ #include #include #include +#include #include #include #include +/* Tunables */ +int fmac_enabled = 1; /* policy enabled */ +int fmac_enforcing = 0; /* permissive or enforcing */ + char *fmac_default_policy_file = FMAC_POLICY_FILE; +/* + * Parse boot arguments. Boot arguments take priority over + * defaults and /etc/system specifications. + */ +static void +fmac_parse_bootargs(const char *cp) +{ + const char *ncp; -#ifdef DEBUG -int flask_enforcing = 1; -#endif /* DEBUG */ + while (*cp != '\0') { + + /* Skip white spaces */ + while (*cp == ' ') + cp++; + + if (strncmp(cp, "enabled", sizeof ("enabled") -1) == 0) { + fmac_enabled = 1; + cp += sizeof ("enabled") - 1; + } else if (strncmp(cp, "disabled", + sizeof ("disabled")-1) == 0) { + fmac_enabled = 0; + cp += sizeof ("disabled") - 1; + } else if (strncmp(cp, "enforcing", + sizeof ("enforcing")-1) == 0) { + fmac_enabled = 1; + fmac_enforcing = 1; + cp += sizeof ("enforcing") - 1; + } else if (strncmp(cp, "permissive", + sizeof ("permissive")-1) == 0) { + fmac_enabled = 1; + fmac_enforcing = 0; + cp += sizeof ("permissive") - 1; + } + + /* Check for additional arguments */ + if (*cp != '\0' && (ncp = strchr(cp, ',')) != '\0') { + cp = ncp + 1; + } else + break; + } +} void fmac_init() { - (void) fmac_load_policy(fmac_default_policy_file); + fmac_parse_bootargs(policyargs); + + if (fmac_enabled) + if (fmac_load_policy(fmac_default_policy_file)) + if (fmac_enforcing) + cmn_err(CE_PANIC, + "security: Policy load failed"); } int @@ -63,7 +111,7 @@ fmac_load_policy(char *file) return (ENOENT); } - if ((ret = security_load_policy(policy_handle, 0)) < 0) { + if ((ret = security_load_policy(policy_handle, 0))) { cmn_err(CE_WARN, "security: Policy load failed %s\n", file); kobj_close_file(policy_handle); return (ret); @@ -72,6 +120,8 @@ fmac_load_policy(char *file) kobj_close_file(policy_handle); cmn_err(CE_CONT, "security: Policy loaded from %s\n", file); + cmn_err(CE_CONT, "security: mode is %s\n", + fmac_enforcing == 0 ? "permissive" : "enforcing"); return (0); } diff --git a/usr/src/uts/common/krtld/kobj_bootflags.c b/usr/src/uts/common/krtld/kobj_bootflags.c --- a/usr/src/uts/common/krtld/kobj_bootflags.c +++ b/usr/src/uts/common/krtld/kobj_bootflags.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -78,9 +78,9 @@ bootflags(struct bootops *ops) #if defined(_OBP) /* skip bootblk args */ - params.gos_opts = "abcdDF:gGHhi:km:o:O:rsvVwx"; + params.gos_opts = "abcdDF:gGHhi:km:o:O:p:rsvVwx"; #else - params.gos_opts = "abcdgGhi:km:O:rsvwx"; + params.gos_opts = "abcdgGhi:km:O:p:rsvwx"; #endif params.gos_strp = cp; getoptstr_init(¶ms); @@ -169,6 +169,23 @@ bootflags(struct bootops *ops) (*str)[params.gos_optarglen] = '\0'; break; } + case 'p': { + if (strlen(policyargs) + params.gos_optarglen + 1 > + sizeof (policyargs)) { + _kobj_printf(ops, + "unix: init options too long. " + "Ignoring -p.\n"); + break; + } + /* gos_optargp is not null terminated */ + (void) strncpy(scratch, params.gos_optargp, + params.gos_optarglen); + scratch[params.gos_optarglen] = '\0'; + (void) strlcat(policyargs, scratch, + sizeof (policyargs)); + (void) strlcat(policyargs, " ", sizeof (policyargs)); + break; + } case 'r': if (strlen(initargs) + 3 + 1 > sizeof (initargs)) { _kobj_printf(ops, "unix: init options too " diff --git a/usr/src/uts/common/os/main.c b/usr/src/uts/common/os/main.c --- a/usr/src/uts/common/os/main.c +++ b/usr/src/uts/common/os/main.c @@ -95,6 +95,8 @@ int interrupts_unleashed; /* set when we int interrupts_unleashed; /* set when we do the first spl0() */ kmem_cache_t *process_cache; /* kmem cache for proc structures */ + +char policyargs[BOOTARGS_MAX] = ""; /* * Process 0's lwp directory and lwpid hash table. diff --git a/usr/src/uts/common/os/sysent.c b/usr/src/uts/common/os/sysent.c --- a/usr/src/uts/common/os/sysent.c +++ b/usr/src/uts/common/os/sysent.c @@ -64,6 +64,7 @@ int exec(); int exec(); int exece(); int fcntl(); +int fmacsys(); int64_t forkall(); int64_t vfork(); int64_t forksys(); @@ -601,7 +602,7 @@ struct sysent sysent[NSYSCALL] = IF_i386( SYSENT_CI("xmknod", xmknod, 4), SYSENT_NOSYS())), - /* 127 */ SYSENT_LOADABLE(), /* was clocal */ + /* 127 */ SYSENT_CI("fmacsys", fmacsys, 6), /* 128 */ IF_LP64( SYSENT_CI("setrlimit", setrlimit64, 2), SYSENT_CI("setrlimit", setrlimit32, 2)), @@ -988,7 +989,7 @@ struct sysent sysent32[NSYSCALL] = /* 126 */ IF_386_ABI( SYSENT_CI("xmknod", xmknod, 4), SYSENT_NOSYS()), - /* 127 */ SYSENT_LOADABLE32(), /* was clocal */ + /* 127 */ SYSENT_CI("fmacsys", fmacsys, 6), /* 128 */ SYSENT_CI("setrlimit", setrlimit32, 2), /* 129 */ SYSENT_CI("getrlimit", getrlimit32, 2), /* 130 */ SYSENT_CI("lchown", lchown, 3), 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 @@ -31,28 +31,61 @@ extern "C" { extern "C" { #endif -#ifdef __cplusplus -} -#endif +#if defined(_KERNEL) +#include +#else +#include +#endif /* _KERNEL */ + +#include #define FMAC_MAX_CONTEXT_LEN 4096 #define FMAC_POLICY_FILE "/etc/security/fmac/ss_policy" #define FMAC_CONTEXT_ATTR "SUNW.fmac.security" +/* + * FMAC system calls subcodes + */ +#define FMACSYS_SECURITYGETENFORCE 0 +#define FMACSYS_SECURITYSETENFORCE 1 +#define FMACSYS_SECURITYLOADPOLICY 2 +#define FMACSYS_ISFMACENABLED 3 +#define FMACSYS_SECURITYCOMPUTEAV 4 +#define FMACSYS_SECURITYCHECKCONTEXT 5 +#define FMACSYS_GETCON 6 +#define FMACSYS_GETPIDCON 7 +#define FMACSYS_GETEXECCON 8 +#define FMACSYS_SETEXECCON 9 +#define FMACSYS_GETFILECON 10 +#define FMACSYS_SETFILECON 11 +#define FMACSYS_LGETFILECON 12 +#define FMACSYS_LSETFILECON 13 +#define FMACSYS_FGETFILECON 14 +#define FMACSYS_FSETFILECON 15 + #if defined(_KERNEL) -#if defined(DEBUG) -extern int flask_enforcing; +extern int fmac_enabled; +extern int fmac_enforcing; #else -#define flask_enforcing 1 -#endif /* DEBUG */ -#else -#define flask_enforcing 1 +#define fmac_enforcing 1 #endif /* _KERNEL */ + +struct av_decision { + access_vector_t allowed; + access_vector_t decided; + access_vector_t auditallow; + access_vector_t auditdeny; + uint32_t seqno; +}; #if defined(_KERNEL) extern char *fmac_default_policy_file; void fmac_init(void); int fmac_load_policy(char *file); +#endif /* _KERNEL */ + +#ifdef __cplusplus +} #endif #endif /* _SYS_FMAC_FMAC_H */ diff --git a/usr/src/uts/common/sys/fmac/security.h b/usr/src/uts/common/sys/fmac/security.h --- a/usr/src/uts/common/sys/fmac/security.h +++ b/usr/src/uts/common/sys/fmac/security.h @@ -39,6 +39,7 @@ extern "C" { * Security server interface. */ +#include #include #include #include @@ -53,13 +54,6 @@ int security_load_policy(void *data, siz * Compute access vectors based on a SID pair for * the permissions in a particular class. */ -struct av_decision { - access_vector_t allowed; - access_vector_t decided; - access_vector_t auditallow; - access_vector_t auditdeny; - uint32_t seqno; -}; int security_compute_av( security_id_t ssid, /* IN */ security_id_t tsid, /* IN */ diff --git a/usr/src/uts/common/sys/syscall.h b/usr/src/uts/common/sys/syscall.h --- a/usr/src/uts/common/sys/syscall.h +++ b/usr/src/uts/common/sys/syscall.h @@ -319,6 +319,7 @@ extern "C" { #define SYS_lxstat 124 #define SYS_fxstat 125 #define SYS_xmknod 126 +#define SYS_fmacsys 127 #define SYS_setrlimit 128 #define SYS_getrlimit 129 #define SYS_lchown 130 diff --git a/usr/src/uts/common/sys/systm.h b/usr/src/uts/common/sys/systm.h --- a/usr/src/uts/common/sys/systm.h +++ b/usr/src/uts/common/sys/systm.h @@ -23,7 +23,7 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -394,6 +394,11 @@ extern int exec_init(const char *, const extern int exec_init(const char *, const char *); extern int start_init_common(void); +/* + * policyargs contains security policy related boot arguments. + */ +extern char policyargs[BOOTARGS_MAX]; + #endif /* _KERNEL */ #if defined(_KERNEL) || defined(_BOOT) diff --git a/usr/src/uts/common/syscall/fmacsys.c b/usr/src/uts/common/syscall/fmacsys.c new file mode 100644 --- /dev/null +++ b/usr/src/uts/common/syscall/fmacsys.c @@ -0,0 +1,332 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int +fmacsys_getenforce() +{ + if (fmac_enforcing) + return (1); + else + return (0); +} + +static int +fmacsys_setenforce(int mode) +{ + int err = 0; + + if (!INGLOBALZONE(curproc)) { + err = EINVAL; + goto done; + } + + /* Until avc_has_perm() can be used, we'll use privilege for access */ + if (err = PRIV_POLICY(CRED(), PRIV_ALL, B_FALSE, EPERM, NULL)) + goto done; + + switch (mode) { + + case 0: + case 1: + fmac_enforcing = mode; + break; + default: + err = EINVAL; + break; + } + +done: + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_security_load_policy(char *path) +{ + char *kpath = 0; + int err; + + if (!INGLOBALZONE(curproc)) { + err = EINVAL; + goto done; + } + + if (!fmac_enabled) { + err = ENOSYS; + goto done; + } + + /* + * fmac_load_policy() calls kobj_open_file() which opens the file + * with kcred, so a privilege check is done here first. + */ + if (err = PRIV_POLICY(CRED(), PRIV_ALL, B_FALSE, EPERM, NULL)) + goto done; + + kpath = kmem_alloc(MAXPATHLEN, KM_SLEEP); + + if ((err = copyinstr(path, kpath, MAXPATHLEN, NULL)) != 0) + goto done; + + + err = fmac_load_policy(kpath); +done: + if (kpath) + kmem_free(kpath, MAXPATHLEN); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_is_fmac_enabled() +{ + if (fmac_enabled) + return (1); + else + return (0); +} + + +static int +fmacsys_security_compute_av( + security_context_t scontext, + security_context_t tcontext, + security_class_t tclass, + access_vector_t request, + struct av_decision *avd) +{ + security_context_t kscontext; + security_context_t ktcontext; + security_id_t ssid; + security_id_t tsid; + struct av_decision kavd; + size_t slen; + size_t tlen; + int err; + + kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + ktcontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + + if ((err = copyinstr(scontext, kscontext, FMAC_MAX_CONTEXT_LEN, + &slen)) != 0) + goto done; + + if ((err = copyinstr(tcontext, ktcontext, FMAC_MAX_CONTEXT_LEN, + &tlen)) != 0) + goto done; + + if ((err = security_context_to_sid(kscontext, slen, &ssid))) + goto done; + + if ((err = security_context_to_sid(ktcontext, tlen, &tsid))) + goto done; + + if ((err = security_compute_av(ssid, tsid, tclass, request, &kavd))) + goto done; + + if (copyout(&kavd, avd, sizeof (struct av_decision))) { + err = EFAULT; + goto done; + } + +done: + kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); + kmem_free(ktcontext, FMAC_MAX_CONTEXT_LEN); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_security_check_context(security_context_t scontext) +{ + security_context_t kscontext; + security_id_t ssid; + size_t slen; + int err; + + kscontext = kmem_alloc(FMAC_MAX_CONTEXT_LEN, KM_SLEEP); + + if ((err = copyinstr(scontext, kscontext, FMAC_MAX_CONTEXT_LEN, + &slen)) != 0) + goto done; + + if ((err = security_context_to_sid(kscontext, slen, &ssid))) + goto done; + +done: + kmem_free(kscontext, FMAC_MAX_CONTEXT_LEN); + + if (err) + return (set_errno(err)); + else + return (0); +} + +static int +fmacsys_getcon(pid_t pid, security_context_t scontext) +{ + _NOTE(ARGUNUSED(pid, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_getexeccon(security_context_t scontext) +{ + _NOTE(ARGUNUSED(scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_setexeccon(security_context_t scontext) +{ + _NOTE(ARGUNUSED(scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_getfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_setfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_lgetfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_lsetfilecon(char *path, security_context_t scontext) +{ + _NOTE(ARGUNUSED(path, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_fgetfilecon(int fd, security_context_t scontext) +{ + _NOTE(ARGUNUSED(fd, scontext)); + + return (set_errno(ENOSYS)); +} + +static int +fmacsys_fsetfilecon(int fd, security_context_t scontext) +{ + _NOTE(ARGUNUSED(fd, scontext)); + + return (set_errno(ENOSYS)); +} + +int +fmacsys(int op, void *a1, void *a2, void *a3, void *a4, void *a5) +{ + switch (op) { + case FMACSYS_SECURITYGETENFORCE: + return (fmacsys_getenforce()); + case FMACSYS_SECURITYSETENFORCE: + return (fmacsys_setenforce((int)(uintptr_t)a1)); + case FMACSYS_SECURITYLOADPOLICY: + return (fmacsys_security_load_policy((char *)a1)); + case FMACSYS_ISFMACENABLED: + return (fmacsys_is_fmac_enabled()); + case FMACSYS_SECURITYCOMPUTEAV: + return (fmacsys_security_compute_av((security_context_t)a1, + (security_context_t)a2, + (security_class_t)(uintptr_t)a3, + (access_vector_t)(unsigned long)a4, + (struct av_decision *)a5)); + case FMACSYS_SECURITYCHECKCONTEXT: + return (fmacsys_security_check_context((security_context_t)a1)); + case FMACSYS_GETCON: + return (fmacsys_getcon(curproc->p_pid, (security_context_t)a1)); + case FMACSYS_GETPIDCON: + return (fmacsys_getcon((pid_t)(uintptr_t)a1, + (security_context_t)a2)); + case FMACSYS_GETEXECCON: + return (fmacsys_getexeccon((security_context_t)a1)); + case FMACSYS_SETEXECCON: + return (fmacsys_setexeccon((security_context_t)a1)); + case FMACSYS_GETFILECON: + return (fmacsys_getfilecon((char *)a1, (security_context_t)a2)); + case FMACSYS_SETFILECON: + return (fmacsys_setfilecon((char *)a1, (security_context_t)a2)); + case FMACSYS_LGETFILECON: + return (fmacsys_lgetfilecon((char *)a1, + (security_context_t)a2)); + case FMACSYS_LSETFILECON: + return (fmacsys_lsetfilecon((char *)a1, + (security_context_t)a2)); + case FMACSYS_FGETFILECON: + return (fmacsys_fgetfilecon((int)(uintptr_t)a1, + (security_context_t)a2)); + case FMACSYS_FSETFILECON: + return (fmacsys_fsetfilecon((int)(uintptr_t)a1, + (security_context_t)a2)); + default: + return (ENOSYS); + } + /* NOTREACHED */ +} diff --git a/usr/src/uts/intel/os/name_to_sysnum b/usr/src/uts/intel/os/name_to_sysnum --- a/usr/src/uts/intel/os/name_to_sysnum +++ b/usr/src/uts/intel/os/name_to_sysnum @@ -113,6 +113,7 @@ lxstat 124 lxstat 124 fxstat 125 xmknod 126 +fmacsys 127 setrlimit 128 getrlimit 129 lchown 130 diff --git a/usr/src/uts/sparc/os/name_to_sysnum b/usr/src/uts/sparc/os/name_to_sysnum --- a/usr/src/uts/sparc/os/name_to_sysnum +++ b/usr/src/uts/sparc/os/name_to_sysnum @@ -112,6 +112,7 @@ lxstat 124 lxstat 124 fxstat 125 xmknod 126 +fmacsys 127 setrlimit 128 getrlimit 129 lchown 130 From Glenn.Faden at Sun.COM Thu Jun 19 11:14:14 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Thu, 19 Jun 2008 11:14:14 -0700 Subject: [fmac-discuss] Zone-specific policies Message-ID: <485AA1F6.3080005@sun.com> I'd like to restart the discussion on Zones and Flask. I think the old thread got too far off topic, so I'm starting a new thread from http://mail.opensolaris.org/pipermail/fmac-discuss/2008-April/000026.html On Wed, 2008-04-16 Stephen Smalley wrote: In Linux, we apply a peer-to-peer check on local socket IPC, the connectto (stream) or sendto (datagram) permission checks. I would expect we could do likewise for door IPC in Solaris, although I'll confess to not having looked at the doors mechanism at all yet. Of course those checks were at process granularity rather than zone/container granularity, but it wouldn't be hard to support both if we assign Flask security contexts to zones in Solaris as well as to processes, likely with an associate check between the zone and process upon process creation to ensure a relationship between the zone context and the contexts of any processes within it. That's all just off the top of my head though and might prove to be problematic in implementation. I don't think that assigning a security context to a zone is sufficient. Zones are not just another type of object. They represent entire virtual instances of Solaris. Since essentially everything in the Solaris kernel is virtualized, this leads to the question of virtualization of the Flask service. For example: Should the policy for a zone be virtualized and loaded when a zone is booted? Should there be an Access Vector Cache per zone? Should the enforcing/permissive/enabled settings per settable on per-zone basis? In my opinion, the answer is yes. Solaris provides per-zone privilege limit sets, per-zone brands with customized access policies, per zone naming services, etc. Solaris also provides options for shared or exclusive network stacks. I think the same options should apply to the FMAC policy. Following the existing model, when a zone is configured, the administrator should be able to specify shared or exclusive policy. The default should be shared, which means all zones have the same policy, although the enforcement mode should be configurable on a per-zone basis. An interesting question is whether a zone which is configured with the exclusive policy setting should be able to customize its own policy from within the zone. I don't think that can be done without compromising the basic zone promise of containment, so I recommend that zones should not be able modificy their policy from within the zone. However, it might turn out that there is a subset of user-land policies that could be safely modified within a zone. I assume that loading per-zone policies on the fly introduces the risk that a new zone's policy conflicts in some way with existing policies. However, this is consistent with existing Solaris zone implementation. We currently validate each new zone against all running zones before allowing it to be booted. --Glenn From sds at tycho.nsa.gov Fri Jun 20 06:08:57 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Fri, 20 Jun 2008 09:08:57 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485AA1F6.3080005@sun.com> References: <485AA1F6.3080005@sun.com> Message-ID: <1213967337.32066.347.camel@moss-spartans.epoch.ncsc.mil> On Thu, 2008-06-19 at 11:14 -0700, Glenn Faden wrote: > I'd like to restart the discussion on Zones and Flask. I think the old > thread got too far off topic, so I'm starting a new thread from > http://mail.opensolaris.org/pipermail/fmac-discuss/2008-April/000026.html > > > On Wed, 2008-04-16 Stephen Smalley wrote: > > In Linux, we apply a peer-to-peer check on local socket IPC, the > connectto (stream) or sendto (datagram) permission checks. I would > expect we could do likewise for door IPC in Solaris, although I'll > confess to not having looked at the doors mechanism at all yet. Of > course those checks were at process granularity rather than > zone/container granularity, but it wouldn't be hard to support both if > we assign Flask security contexts to zones in Solaris as well as to > processes, likely with an associate check between the zone and process > upon process creation to ensure a relationship between the zone context > and the contexts of any processes within it. That's all just off the > top of my head though and might prove to be problematic in > implementation. > > I don't think that assigning a security context to a zone is sufficient. > Zones are not just another type of object. They represent entire virtual > instances of Solaris. Since essentially everything in the Solaris kernel > is virtualized, this leads to the question of virtualization of the > Flask service. For example: > > Should the policy for a zone be virtualized and loaded when a zone > is booted? > > Should there be an Access Vector Cache per zone? > > Should the enforcing/permissive/enabled settings per settable on > per-zone basis? > > In my opinion, the answer is yes. Solaris provides per-zone privilege > limit sets, per-zone brands with customized access policies, per zone > naming services, etc. Solaris also provides options for shared or > exclusive network stacks. I think the same options should apply to the > FMAC policy. Following the existing model, when a zone is configured, > the administrator should be able to specify shared or exclusive policy. > The default should be shared, which means all zones have the same > policy, although the enforcement mode should be configurable on a > per-zone basis. > > An interesting question is whether a zone which is configured with the > exclusive policy setting should be able to customize its own policy from > within the zone. I don't think that can be done without compromising the > basic zone promise of containment, so I recommend that zones should not > be able modificy their policy from within the zone. However, it might > turn out that there is a subset of user-land policies that could be > safely modified within a zone. > > I assume that loading per-zone policies on the fly introduces the risk > that a new zone's policy conflicts in some way with existing policies. > However, this is consistent with existing Solaris zone implementation. > We currently validate each new zone against all running zones before > allowing it to be booted. I'm not clear that this is a safe approach if we want to be able to use FMAC for controlling of cross-zone channels (as previously discussed) in addition to using it for intra-zone fine-grained protection and hardening of the global zone. Keep in mind that in FMAC/Flask, the labels themselves are defined and interpreted relative to a policy, and a label defined in one policy may not be defined or may have a completely different semantic meaning in another policy. When crossing a network boundary, applying policy negotiation and label translation makes sense, but doing likewise within a single operating system when crossing zones seems a high cost to impose in complexity and overhead for relatively little gain. When two processes communicate via IPC across zone boundaries, we need to be able to interpret their labels and check permissions relative to a single policy. Likewise, when a process accesses an object which may be visible in multiple zones, we need to be able to interpret the process and file label and check permissions relative to a single policy. Defining a hierarchical relationship among labels within a single policy such that one can decompose subsets of the policy and delegate control of parts of the policy safely is something that has been explored within SELinux (c.f. type hierarchy and policy management server), and we might investigate that within FMAC as well when we are further along with the core support. But that retains a notion of a single policy rooted in a common set of definitions. -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Fri Jun 20 06:22:42 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Fri, 20 Jun 2008 09:22:42 -0400 Subject: [fmac-discuss] [PATCH] First FMAC System Calls In-Reply-To: <4859861D.2080505@sun.com> References: <4859861D.2080505@sun.com> Message-ID: <1213968162.32066.360.camel@moss-spartans.epoch.ncsc.mil> On Wed, 2008-06-18 at 15:03 -0700, John Weeks wrote: > This patch includes the first FMAC related system calls, a new utility > (loadpolicy) and policy boot parameters. Other related FMAC policy control > changes are also included. Thanks, this looks like a good step forward for FMAC. > > New Utilities: > > loadpolicy - load FMAC policy file > > loadpolicy file > > New System Calls: > > #include > > int security_load_policy(char *path); > > int security_compute_av(security_context_t scontext, > security_context_t tcontext, security_class_t tclass, > access_vector_t request, struct av_decision *avd); > > int security_check_context(security_context_t scontext); > > int security_getenforce(void); > > int security_setenforce(int mode); > > int is_fmac_enabled(void); > > The system calls above are modeled after their SELinux counterparts. > > I would have provided manpages for the interfaces, but I'm still > waiting for an inbound source review of libselinux where the > manpage sources for the interfaces resides. > > truss(1) was modified to accommodate the new systems calls. > Additional work to translate class, permission, and > AVC return values will be done when we have equivalent > libselinux translation functions available. > > Normally I would not introduce "dead" code into the kernel, but I > have included the following stub functions in uts/common/syscall/fmacsys.c > for the next round of system call development: > > int getcon(security_context_t scontext) > int getpidcon(pid_t pid, security_context_t scontext) > int fmacsys_getexeccon(security_context_t scontext) > int fmacsys_setexeccon(security_context_t scontext) > int getfilecon(const char *path, security_context_t *con) > int lgetfilecon(const char *path, security_context_t *con) > int fgetfilecon(int fd, security_context_t *con) > int setfilecon(const char *path, security_context_t con) > int fsetfilecon(int fd, security_context_t con) > int lsetfilecon(const char *path, security_context_t con) > > My original plan was to share existing labelsys() system call, > but I wasn't happy with the resulting implementation. So, I > created an FMAC specific syscall #127 fmacsys(). This also > simplified the truss enhancements for the new system calls. That does seem like the better approach. > FMAC Kernel Policy Defaults: > > int fmac_enabled = 1; /* enforcing */ > int fmac_enforcing = 0; /* permissive */ You have this right further down below and in the code, but just to clarify: fmac_enabled should control whether FMAC is enabled at all (i.e. does anything, including loading policy, labeling processes and objects, applying permission checks), while fmac_enforcing should control whether FMAC permission denials are enforced (1/enforcing) or merely logged (0/permissive). Permissive mode is a useful tool for policy development, particularly for bootstrapping a policy from scratch. SELinux has also recently introduced per-domain permissive mode, which might be helpful to investigate later in FMAC. > The defaults above will probably change as the project > progresses. > > If fmac_enabled is set to 1 and the kernel can't load or parse the > policy file, the system will now panic (a security feature). You have this right in the code, but to clarify: it should only panic if fmac_enforcing is set to 1 as well. Otherwise it should just come up in permissive mode with no policy loaded. > New FMAC Boot Arguments (-p policy flags): > > -p [disabled|enforcing|permissive] The code supports lists of flags, which might be useful in the future. But at present it will accept conflicting flags, with the last one winning, if I read it correctly. So we might want to tighten that up in a subsequent patch. > > Since these are boot arguments, I decided not to prefix > the names with fmac since it just makes them longer. If we > run into collisions, we can always adjust as necessary. > > It's possible to boot single user with polity disabled to diagnose a > policy load panic situation: > > -p disabled -m milestone=single-user > > Argument translation to internal control variables: > > disabled: fmac_enabled = 0; > enforcing: fmac_enabled = 1; fmac_enforcing = 1; > permissive: fmac_enabled = 1; fmac_enforcing = 0; > > Policy boot arguments take precedence over defaults and > /etc/system overrides. > > /etc/system Policy Overrides: > > set fmac_enabled = 0 /* disabled */ > set fmac_enabled = 1 /* enabled */ > set fmac_enforcing = 0 /* permissive */ > set fmac_enforcing = 1 /* enforcing */ > set fmac_default_policy_file = "/ss_policy" > > Webrev: http://cr.opensolaris.org/~jweeks/first_fmac_syscalls/ Looks good to me. Thanks. Acked-by: Stephen Smalley -- Stephen Smalley National Security Agency From Glenn.Faden at Sun.COM Fri Jun 20 11:31:30 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Fri, 20 Jun 2008 11:31:30 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1213967337.32066.347.camel@moss-spartans.epoch.ncsc.mil> References: <485AA1F6.3080005@sun.com> <1213967337.32066.347.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <485BF782.9050802@sun.com> Stephen Smalley wrote: > On Thu, 2008-06-19 at 11:14 -0700, Glenn Faden wrote: > >> I'd like to restart the discussion on Zones and Flask. I think the old >> thread got too far off topic, so I'm starting a new thread from >> http://mail.opensolaris.org/pipermail/fmac-discuss/2008-April/000026.html >> >> >> On Wed, 2008-04-16 Stephen Smalley wrote: >> >> In Linux, we apply a peer-to-peer check on local socket IPC, the >> connectto (stream) or sendto (datagram) permission checks. I would >> expect we could do likewise for door IPC in Solaris, although I'll >> confess to not having looked at the doors mechanism at all yet. Of >> course those checks were at process granularity rather than >> zone/container granularity, but it wouldn't be hard to support both if >> we assign Flask security contexts to zones in Solaris as well as to >> processes, likely with an associate check between the zone and process >> upon process creation to ensure a relationship between the zone context >> and the contexts of any processes within it. That's all just off the >> top of my head though and might prove to be problematic in >> implementation. >> >> I don't think that assigning a security context to a zone is sufficient. >> Zones are not just another type of object. They represent entire virtual >> instances of Solaris. Since essentially everything in the Solaris kernel >> is virtualized, this leads to the question of virtualization of the >> Flask service. For example: >> >> Should the policy for a zone be virtualized and loaded when a zone >> is booted? >> >> Should there be an Access Vector Cache per zone? >> >> Should the enforcing/permissive/enabled settings per settable on >> per-zone basis? >> >> In my opinion, the answer is yes. Solaris provides per-zone privilege >> limit sets, per-zone brands with customized access policies, per zone >> naming services, etc. Solaris also provides options for shared or >> exclusive network stacks. I think the same options should apply to the >> FMAC policy. Following the existing model, when a zone is configured, >> the administrator should be able to specify shared or exclusive policy. >> The default should be shared, which means all zones have the same >> policy, although the enforcement mode should be configurable on a >> per-zone basis. >> >> An interesting question is whether a zone which is configured with the >> exclusive policy setting should be able to customize its own policy from >> within the zone. I don't think that can be done without compromising the >> basic zone promise of containment, so I recommend that zones should not >> be able modificy their policy from within the zone. However, it might >> turn out that there is a subset of user-land policies that could be >> safely modified within a zone. >> >> I assume that loading per-zone policies on the fly introduces the risk >> that a new zone's policy conflicts in some way with existing policies. >> However, this is consistent with existing Solaris zone implementation. >> We currently validate each new zone against all running zones before >> allowing it to be booted. >> > > I'm not clear that this is a safe approach if we want to be able to use > FMAC for controlling of cross-zone channels (as previously discussed) in > addition to using it for intra-zone fine-grained protection and > hardening of the global zone. > > Keep in mind that in FMAC/Flask, the labels themselves are defined and > interpreted relative to a policy, and a label defined in one policy may > not be defined or may have a completely different semantic meaning in > another policy. When crossing a network boundary, applying policy > negotiation and label translation makes sense, but doing likewise within > a single operating system when crossing zones seems a high cost to > impose in complexity and overhead for relatively little gain. > > When two processes communicate via IPC across zone boundaries, we need > to be able to interpret their labels and check permissions relative to a > single policy. Likewise, when a process accesses an object which may be > visible in multiple zones, we need to be able to interpret the process > and file label and check permissions relative to a single policy. > > Defining a hierarchical relationship among labels within a single policy > such that one can decompose subsets of the policy and delegate control > of parts of the policy safely is something that has been explored within > SELinux (c.f. type hierarchy and policy management server), and we might > investigate that within FMAC as well when we are further along with the > core support. But that retains a notion of a single policy rooted in a > common set of definitions. > > Stephen, I see your point about the problem of mapping security contexts between zones, especially for file systems that are labeled and shared between zones. However, in a whole root zone with an exclusive network stack, there are no shared files or network objects. Since Sun Marketing makes claims that our zone separation is as good as running instances of Solaris on separate machines, I think there are environments were zones should have individual policies. While I'm sympathetic to avoiding unnecessary complexity, I think we should be focusing more in terms of requirements than implementation details at this stage of the project. Do you agree with the goal of customized policy for specific zones? If so, do you have plans for expressing conditional zone-specific policy? Do you agree that it should be possible to specify whether a particular zone is running in enforcing or permissive mode? That would provide a sandbox environment for developing new policies. I also have a general question about Flask permitting cross-zone IPC. How can Flask permit something that is never allowed in the base OS? From what I've seen in SELinux, disabling enforcing mode should not introduce new vulnerabilities in the base OS. From sds at tycho.nsa.gov Fri Jun 20 13:00:54 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Fri, 20 Jun 2008 16:00:54 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485BF782.9050802@sun.com> References: <485AA1F6.3080005@sun.com> <1213967337.32066.347.camel@moss-spartans.epoch.ncsc.mil> <485BF782.9050802@sun.com> Message-ID: <1213992054.32066.464.camel@moss-spartans.epoch.ncsc.mil> On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: > Stephen Smalley wrote: > > On Thu, 2008-06-19 at 11:14 -0700, Glenn Faden wrote: > > > >> I'd like to restart the discussion on Zones and Flask. I think the old > >> thread got too far off topic, so I'm starting a new thread from > >> http://mail.opensolaris.org/pipermail/fmac-discuss/2008-April/000026.html > >> > >> > >> On Wed, 2008-04-16 Stephen Smalley wrote: > >> > >> In Linux, we apply a peer-to-peer check on local socket IPC, the > >> connectto (stream) or sendto (datagram) permission checks. I would > >> expect we could do likewise for door IPC in Solaris, although I'll > >> confess to not having looked at the doors mechanism at all yet. Of > >> course those checks were at process granularity rather than > >> zone/container granularity, but it wouldn't be hard to support both if > >> we assign Flask security contexts to zones in Solaris as well as to > >> processes, likely with an associate check between the zone and process > >> upon process creation to ensure a relationship between the zone context > >> and the contexts of any processes within it. That's all just off the > >> top of my head though and might prove to be problematic in > >> implementation. > >> > >> I don't think that assigning a security context to a zone is sufficient. > >> Zones are not just another type of object. They represent entire virtual > >> instances of Solaris. Since essentially everything in the Solaris kernel > >> is virtualized, this leads to the question of virtualization of the > >> Flask service. For example: > >> > >> Should the policy for a zone be virtualized and loaded when a zone > >> is booted? > >> > >> Should there be an Access Vector Cache per zone? > >> > >> Should the enforcing/permissive/enabled settings per settable on > >> per-zone basis? > >> > >> In my opinion, the answer is yes. Solaris provides per-zone privilege > >> limit sets, per-zone brands with customized access policies, per zone > >> naming services, etc. Solaris also provides options for shared or > >> exclusive network stacks. I think the same options should apply to the > >> FMAC policy. Following the existing model, when a zone is configured, > >> the administrator should be able to specify shared or exclusive policy. > >> The default should be shared, which means all zones have the same > >> policy, although the enforcement mode should be configurable on a > >> per-zone basis. > >> > >> An interesting question is whether a zone which is configured with the > >> exclusive policy setting should be able to customize its own policy from > >> within the zone. I don't think that can be done without compromising the > >> basic zone promise of containment, so I recommend that zones should not > >> be able modificy their policy from within the zone. However, it might > >> turn out that there is a subset of user-land policies that could be > >> safely modified within a zone. > >> > >> I assume that loading per-zone policies on the fly introduces the risk > >> that a new zone's policy conflicts in some way with existing policies. > >> However, this is consistent with existing Solaris zone implementation. > >> We currently validate each new zone against all running zones before > >> allowing it to be booted. > >> > > > > I'm not clear that this is a safe approach if we want to be able to use > > FMAC for controlling of cross-zone channels (as previously discussed) in > > addition to using it for intra-zone fine-grained protection and > > hardening of the global zone. > > > > Keep in mind that in FMAC/Flask, the labels themselves are defined and > > interpreted relative to a policy, and a label defined in one policy may > > not be defined or may have a completely different semantic meaning in > > another policy. When crossing a network boundary, applying policy > > negotiation and label translation makes sense, but doing likewise within > > a single operating system when crossing zones seems a high cost to > > impose in complexity and overhead for relatively little gain. > > > > When two processes communicate via IPC across zone boundaries, we need > > to be able to interpret their labels and check permissions relative to a > > single policy. Likewise, when a process accesses an object which may be > > visible in multiple zones, we need to be able to interpret the process > > and file label and check permissions relative to a single policy. > > > > Defining a hierarchical relationship among labels within a single policy > > such that one can decompose subsets of the policy and delegate control > > of parts of the policy safely is something that has been explored within > > SELinux (c.f. type hierarchy and policy management server), and we might > > investigate that within FMAC as well when we are further along with the > > core support. But that retains a notion of a single policy rooted in a > > common set of definitions. > > > > > Stephen, > > I see your point about the problem of mapping security contexts between > zones, especially for file systems that are labeled and shared between > zones. However, in a whole root zone with an exclusive network stack, > there are no shared files or network objects. Since Sun Marketing makes > claims that our zone separation is as good as running instances of > Solaris on separate machines, I think there are environments were zones > should have individual policies. Ah, marketing. > While I'm sympathetic to avoiding unnecessary complexity, I think we > should be focusing more in terms of requirements than implementation > details at this stage of the project. Do you agree with the goal of > customized policy for specific zones? If so, do you have plans for > expressing conditional zone-specific policy? I believe we can express customized policy for specific zones without supporting separate per-zone policy. It just requires decomposing subsets of the policy and applying different subsets to different zones through the definition and assignment of types. It doesn't actually require being able to load separate policies into separate zones. And the kernel mechanism is much cleaner as a result. > Do you agree that it should be possible to specify whether a particular > zone is running in enforcing or permissive mode? That would provide a > sandbox environment for developing new policies. SELinux has recently introduced per-domain permissive mode, which lets you apply it at whatever granularity you want, all the way down to per-process if you like. We could do the same in FMAC - that's not hard, and it doesn't require any special handling of zones. > I also have a general question about Flask permitting cross-zone IPC. > How can Flask permit something that is never allowed in the base OS? > From what I've seen in SELinux, disabling enforcing mode should not > introduce new vulnerabilities in the base OS. You mentioned that in the original thread too, and Darren gave an example. Flask/FMAC could provide further, more direct control over controlled channels among zones, reducing the trust you are presently placing in the proxies in the global zone and potentially providing more flexibility there as well, although I haven't looked into the details yet. -- Stephen Smalley National Security Agency From William.Young at Sun.COM Fri Jun 20 13:22:37 2008 From: William.Young at Sun.COM (Will Young) Date: Fri, 20 Jun 2008 16:22:37 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1213992054.32066.464.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> Message-ID: <485C118D.8030007@sun.com> Stephen Smalley wrote: > On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: > > >> I also have a general question about Flask permitting cross-zone IPC. >> How can Flask permit something that is never allowed in the base OS? >> From what I've seen in SELinux, disabling enforcing mode should not >> introduce new vulnerabilities in the base OS. >> > > You mentioned that in the original thread too, and Darren gave an > example. Flask/FMAC could provide further, more direct control over > controlled channels among zones, reducing the trust you are presently > placing in the proxies in the global zone and potentially providing more > flexibility there as well, although I haven't looked into the details > yet. > I had responded to Darren in the original thread that it is necessary that the OS without MAC has existing semantics and a reasonable DAC policy for controlling them. As far as I know we were in rough agreement that the current cross zones doors should probably be a RBAC controlled solaris feature that TX further restricts and the reason it is not is one of resources, not design. -Will From sds at tycho.nsa.gov Fri Jun 20 13:32:27 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Fri, 20 Jun 2008 16:32:27 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485C118D.8030007@sun.com> 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> <485C118D.8030007@sun.com> Message-ID: <1213993947.32066.467.camel@moss-spartans.epoch.ncsc.mil> On Fri, 2008-06-20 at 16:22 -0400, Will Young wrote: > Stephen Smalley wrote: > > On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: > > > > > >> I also have a general question about Flask permitting cross-zone IPC. > >> How can Flask permit something that is never allowed in the base OS? > >> From what I've seen in SELinux, disabling enforcing mode should not > >> introduce new vulnerabilities in the base OS. > >> > > > > You mentioned that in the original thread too, and Darren gave an > > example. Flask/FMAC could provide further, more direct control over > > controlled channels among zones, reducing the trust you are presently > > placing in the proxies in the global zone and potentially providing more > > flexibility there as well, although I haven't looked into the details > > yet. > > > > I had responded to Darren in the original thread that it is > necessary that the OS without MAC has existing semantics and a > reasonable DAC policy for controlling them. As far as I know we were in > rough agreement that the current cross zones doors should probably be a > RBAC controlled solaris feature that TX further restricts and the reason > it is not is one of resources, not design. Does that contradict what I said? If cross zone doors are possible at all, then it makes sense for Flask/FMAC to be able to control them. And even apart from doors, if there is potential for information flow between zones via shared filesystems or any other mechanism, then we want to be able to control that via Flask/FMAC. Which means we have to deal with access checks that cross zone boundaries regardless. -- Stephen Smalley National Security Agency From Glenn.Faden at Sun.COM Fri Jun 20 13:34:22 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Fri, 20 Jun 2008 13:34:22 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1213992054.32066.464.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> Message-ID: <485C144E.5010204@sun.com> Stephen Smalley wrote: > On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: > >> While I'm sympathetic to avoiding unnecessary complexity, I think we >> should be focusing more in terms of requirements than implementation >> details at this stage of the project. Do you agree with the goal of >> customized policy for specific zones? If so, do you have plans for >> expressing conditional zone-specific policy? >> > > I believe we can express customized policy for specific zones without > supporting separate per-zone policy. It just requires decomposing > subsets of the policy and applying different subsets to different zones > through the definition and assignment of types. It doesn't actually > require being able to load separate policies into separate zones. And > the kernel mechanism is much cleaner as a result. > That sounds good. I'm curious how this would be done. I have a vague idea that each zone would have a unique security context and that inter-zone access checks could be specified in the policy based on type and mls label. But I don't understand how an existing policy file would accommodate zone-specific behavior. Is there an example in SELinux policy that you could point to? > >> Do you agree that it should be possible to specify whether a particular >> zone is running in enforcing or permissive mode? That would provide a >> sandbox environment for developing new policies. >> > > SELinux has recently introduced per-domain permissive mode, which lets > you apply it at whatever granularity you want, all the way down to > per-process if you like. We could do the same in FMAC - that's not > hard, and it doesn't require any special handling of zones. > That sounds good, too. Could this apply to all processes in the zone, or only for cross-zone operations? > >> I also have a general question about Flask permitting cross-zone IPC. >> How can Flask permit something that is never allowed in the base OS? >> From what I've seen in SELinux, disabling enforcing mode should not >> introduce new vulnerabilities in the base OS. >> > > You mentioned that in the original thread too, and Darren gave an > example. Flask/FMAC could provide further, more direct control over > controlled channels among zones, reducing the trust you are presently > placing in the proxies in the global zone and potentially providing more > flexibility there as well, although I haven't looked into the details > yet. > As Will posted, we would first need to invent some non-Flask mechanism to permit such access before allowing Flask to mediate the access. --Glenn From Glenn.Faden at Sun.COM Fri Jun 20 13:46:03 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Fri, 20 Jun 2008 13:46:03 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1213993947.32066.467.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> <485C118D.8030007@sun.com> <1213993947.32066.467.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <485C170B.8080400@sun.com> Stephen Smalley wrote: > On Fri, 2008-06-20 at 16:22 -0400, Will Young wrote: > >> Stephen Smalley wrote: >> >>> >>> >>> >> I had responded to Darren in the original thread that it is >> necessary that the OS without MAC has existing semantics and a >> reasonable DAC policy for controlling them. As far as I know we were in >> rough agreement that the current cross zones doors should probably be a >> RBAC controlled solaris feature that TX further restricts and the reason >> it is not is one of resources, not design. >> > > Does that contradict what I said? If cross zone doors are possible at > all, then it makes sense for Flask/FMAC to be able to control them. > > And even apart from doors, if there is potential for information flow > between zones via shared filesystems or any other mechanism, then we > want to be able to control that via Flask/FMAC. Which means we have to > deal with access checks that cross zone boundaries regardless. > I was referring to System V IPC, not doors or shared filesystems. In both standard Solaris and in TX, we don't permit any use of Sys V IPC across non-global zones, so we would first need to support it before we could restrict it. FYI, in TX we have MAC policies for cross-zone doors and shared filesystems that apply to what the global zone admin can do, but these restrictions are bypassed in standard Solaris. From alan.duboff at sun.com Fri Jun 20 15:32:17 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Fri, 20 Jun 2008 15:32:17 -0700 (PDT) Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1213992054.32066.464.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> Message-ID: On Fri, 20 Jun 2008, Stephen Smalley wrote: > I believe we can express customized policy for specific zones without > supporting separate per-zone policy. It just requires decomposing > subsets of the policy and applying different subsets to different zones > through the definition and assignment of types. It doesn't actually > require being able to load separate policies into separate zones. And > the kernel mechanism is much cleaner as a result. I agree with this. But Glenn makes a good point about networks crossing boundries. Some consideration probably is in order there, if nothing else but to think things out. It's not clear to me how Glenn would use that issolation, but for me it seems we will eventually get back to a point where we traverse a set of policies in actual operation, and that additional layer doesn't seem needed. Rather, I see a distinction between labels and fmac, and want all policy for fmac to be one and the same, as I do the labels. Virtual Software seems to merit both of those technology within them. We still have policy inside the containers, certainly, but I see no reason that shouldn't be a system global type of operation. > SELinux has recently introduced per-domain permissive mode, which lets > you apply it at whatever granularity you want, all the way down to > per-process if you like. We could do the same in FMAC - that's not > hard, and it doesn't require any special handling of zones. No it doesn't, but zones offer us an additional resource to leverage and being able to tie all of it together is helpful, IMO. I know this is blue sky, but I would like to see several things met with the FMAC project. 1) The code is truely open and free, and anyone can use it no matter what platform they're on. Aside from architecture specific code, which wouldn't fall in this category, I'm referring to software worked on with this project, such as a policy manipulator of such, where the SELinux community can use the code and be able to re-use it also. 2) Preserve and be able to co-exist with what is in place today on OpenSolaris, the labels. Currently this is certainly the prefered way to have any type of secure control within OpenSolaris, it is implemented and works today and FMAC is only being developed, let alone implemented. Somehow to me this is important, and in the global zone on OpenSolaris, I want to have control over both the labels and fmac. 3) Strive to be the best solution for Mandatory Access Control over any other platform. To have the best policy administration, configuration, and usable system. Today when I speak at Linux groups, I have yet to attend one meeting that didn't have more folks with poor taste in their mouth over SELinux, than they had good. Even though SELinux has become a useable system, IMO, the bitterness is not gone. I hope we can come up with a nice system, and I have tossed some ideas around with John Weeks about this recently. I'll be posting some here soon. With those points said, I want policy to be encompassed for all zones, in the same way (i.e., global vs. container). A container will still need access to get any data outside the container, but that it is one and the same in the sense of the system. By issolating the zone to specific policy, which is what it sounded like to me, would only make the interfaces that much more complex. We can still have policy between containers, on the same system. Another consideration is that today we have the ability to create secure tunnels between containers. This can be done in Virtual Box for instance by creating 2 VMs, and tunneling through. This could be a stop gap solution for folks until true IPC could be used between the containers. Maybe we could use FMAC for that. I wouldn't mind seeing the ability to have a type of shared memory between virtual containers, in the same way we do on a local machine today using shared memory between processes, but to extend that out to the network. FMAC could be a way to manage that between the containers, maybe through Xen, not sure...seems there has been some work on Xen to incorporate some flask and/or type enforcement, but not 100 percent sure about that. My interest is in the policy configuration and/or management of those policies, even to document the policies that are there today if needed, it seems some of those documents might not exist. Maybe we could leverage some of the docs/pubs folks to help with that, I know a couple of them. -- Alan DuBoff - Solaris x86 IHV/OEM Group From alan.duboff at sun.com Fri Jun 20 15:35:31 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Fri, 20 Jun 2008 15:35:31 -0700 (PDT) Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485C144E.5010204@sun.com> 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> <485C144E.5010204@sun.com> Message-ID: On Fri, 20 Jun 2008, Glenn Faden wrote: > That sounds good. I'm curious how this would be done. I have a vague > idea that each zone would have a unique security context and that > inter-zone access checks could be specified in the policy based on type > and mls label. Yes, but why would this need to be seperate and/or unique from the rest of the system? I think we can have just that, and incorporate it into the bigger picture on the system, where they are not required to be unique. -- Alan DuBoff - Solaris x86 IHV/OEM Group From William.Young at Sun.COM Fri Jun 20 15:36:46 2008 From: William.Young at Sun.COM (Will Young) Date: Fri, 20 Jun 2008 18:36:46 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1213993947.32066.467.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> <485C118D.8030007@sun.com> <1213993947.32066.467.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <485C30FE.2070509@sun.com> Stephen Smalley wrote: > On Fri, 2008-06-20 at 16:22 -0400, Will Young wrote: > >> Stephen Smalley wrote: >> >>> On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: >>> >>> >>> >>>> I also have a general question about Flask permitting cross-zone IPC. >>>> How can Flask permit something that is never allowed in the base OS? >>>> From what I've seen in SELinux, disabling enforcing mode should not >>>> introduce new vulnerabilities in the base OS. >>>> >>>> >>> You mentioned that in the original thread too, and Darren gave an >>> example. Flask/FMAC could provide further, more direct control over >>> controlled channels among zones, reducing the trust you are presently >>> placing in the proxies in the global zone and potentially providing more >>> flexibility there as well, although I haven't looked into the details >>> yet. >>> >>> >> I had responded to Darren in the original thread that it is >> necessary that the OS without MAC has existing semantics and a >> reasonable DAC policy for controlling them. As far as I know we were in >> rough agreement that the current cross zones doors should probably be a >> RBAC controlled solaris feature that TX further restricts and the reason >> it is not is one of resources, not design. >> > > Does that contradict what I said? If cross zone doors are possible at > all, then it makes sense for Flask/FMAC to be able to control them. > Yes cross zone doors are introduced by TX, and should be controlled. It did not seem to answer Glenn's question of why IPC was being added, so my interpretation was that TX adding cross zone doors was an example of why Flask should add and then restrict additional IPC. > And even apart from doors, if there is potential for information flow > between zones via shared filesystems or any other mechanism, then we > want to be able to control that via Flask/FMAC. Which means we have to > deal with access checks that cross zone boundaries regardless. > > This returns to the question of flexibility. One can have a global policy that is aware of all zones or one can have a policy for each zone that is aware of the existence of other zones and has a policy for dealing with them. To be able to support both a TX like and solaris like use of zones requires being able to treat zones as under the same policy or as an outside entity with only one label. This implies always enforcing a globally managed policy which sometimes looks into creds with non-gz zoneid and sometimes stops at the zoneid and a (possibly null) local policy which always stops at the zoneid for other zone credentials. -Will From Glenn.Faden at Sun.COM Fri Jun 20 16:31:20 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Fri, 20 Jun 2008 16:31:20 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: 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> Message-ID: <485C3DC8.2060502@sun.com> Alan DuBoff wrote: > On Fri, 20 Jun 2008, Stephen Smalley wrote: > >> I believe we can express customized policy for specific zones without >> supporting separate per-zone policy. It just requires decomposing >> subsets of the policy and applying different subsets to different zones >> through the definition and assignment of types. It doesn't actually >> require being able to load separate policies into separate zones. And >> the kernel mechanism is much cleaner as a result. > > I agree with this. But Glenn makes a good point about networks > crossing boundries. Some consideration probably is in order there, if > nothing else but to think things out. > > It's not clear to me how Glenn would use that issolation, but for me > it seems we will eventually get back to a point where we traverse a > set of policies in actual operation, and that additional layer doesn't > seem needed. Zones provide most of the semantics of virtual machines. The degree to which they are locked down should depend on their intended use. So requiring them all to be identical with respect to FMAC policy seems like an undesirable constraint. I'm not advocating a particular implementation, just some functionality and goals. > > Rather, I see a distinction between labels and fmac, and want all > policy for fmac to be one and the same, as I do the labels. Virtual > Software seems to merit both of those technology within them. We still > have policy inside the containers, certainly, but I see no reason that > shouldn't be a system global type of operation. I think we need to be more precise when we use the word label. An MLS label is a component of a security context which is itself sometimes called a label (it has a textual representation). So I don't understand your comment about a distinction between labels and FMAC. Types and MLS labels are distinct, but they are both components of a security context. We need to support environments where the security contexts of zones may differ. I completely agree that FMAC must be global, since there is only one kernel. My point was that the global policy should take into account that zones may be provisioned for different purposes, so there should be hooks in the policy to support that. From sds at tycho.nsa.gov Mon Jun 23 06:54:21 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 23 Jun 2008 09:54:21 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485C144E.5010204@sun.com> 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> <485C144E.5010204@sun.com> Message-ID: <1214229261.32762.10.camel@moss-spartans.epoch.ncsc.mil> On Fri, 2008-06-20 at 13:34 -0700, Glenn Faden wrote: > Stephen Smalley wrote: > > On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: > > > >> While I'm sympathetic to avoiding unnecessary complexity, I think we > >> should be focusing more in terms of requirements than implementation > >> details at this stage of the project. Do you agree with the goal of > >> customized policy for specific zones? If so, do you have plans for > >> expressing conditional zone-specific policy? > >> > > > > I believe we can express customized policy for specific zones without > > supporting separate per-zone policy. It just requires decomposing > > subsets of the policy and applying different subsets to different zones > > through the definition and assignment of types. It doesn't actually > > require being able to load separate policies into separate zones. And > > the kernel mechanism is much cleaner as a result. > > > That sounds good. I'm curious how this would be done. I have a vague > idea that each zone would have a unique security context and that > inter-zone access checks could be specified in the policy based on type > and mls label. But I don't understand how an existing policy file would > accommodate zone-specific behavior. Is there an example in SELinux > policy that you could point to? If we treat zones as just another instance of an object class in Flask, then we can assign security contexts to them and apply a set of permission checks relevant to that object class, including e.g. an associate check between any process label that runs within the zone and the zone label itself. Then it is just a matter of authorizing different process security contexts for different zones, and defining the policy rules for each of those process security contexts. > > > >> Do you agree that it should be possible to specify whether a particular > >> zone is running in enforcing or permissive mode? That would provide a > >> sandbox environment for developing new policies. > >> > > > > SELinux has recently introduced per-domain permissive mode, which lets > > you apply it at whatever granularity you want, all the way down to > > per-process if you like. We could do the same in FMAC - that's not > > hard, and it doesn't require any special handling of zones. > > > That sounds good, too. Could this apply to all processes in the zone, or > only for cross-zone operations? It would still be per-domain, and thus one could choose to apply it to selected processes within a zone or to all processes authorized to run within a given zone. > > > >> I also have a general question about Flask permitting cross-zone IPC. > >> How can Flask permit something that is never allowed in the base OS? > >> From what I've seen in SELinux, disabling enforcing mode should not > >> introduce new vulnerabilities in the base OS. > >> > > > > You mentioned that in the original thread too, and Darren gave an > > example. Flask/FMAC could provide further, more direct control over > > controlled channels among zones, reducing the trust you are presently > > placing in the proxies in the global zone and potentially providing more > > flexibility there as well, although I haven't looked into the details > > yet. > > > As Will posted, we would first need to invent some non-Flask mechanism > to permit such access before allowing Flask to mediate the access. Ok, but I think it is safe to say that there are mechanisms for information flow between zones already, and thus providing Flask control over them makes sense. -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Mon Jun 23 07:30:02 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 23 Jun 2008 10:30:02 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485C30FE.2070509@sun.com> 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> <485C118D.8030007@sun.com> <1213993947.32066.467.camel@moss-spartans.epoch.ncsc.mil> <485C30FE.2070509@sun.com> Message-ID: <1214231402.32762.30.camel@moss-spartans.epoch.ncsc.mil> On Fri, 2008-06-20 at 18:36 -0400, Will Young wrote: > Stephen Smalley wrote: > > On Fri, 2008-06-20 at 16:22 -0400, Will Young wrote: > > > >> Stephen Smalley wrote: > >> > >>> On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: > >>> > >>> > >>> > >>>> I also have a general question about Flask permitting cross-zone IPC. > >>>> How can Flask permit something that is never allowed in the base OS? > >>>> From what I've seen in SELinux, disabling enforcing mode should not > >>>> introduce new vulnerabilities in the base OS. > >>>> > >>>> > >>> You mentioned that in the original thread too, and Darren gave an > >>> example. Flask/FMAC could provide further, more direct control over > >>> controlled channels among zones, reducing the trust you are presently > >>> placing in the proxies in the global zone and potentially providing more > >>> flexibility there as well, although I haven't looked into the details > >>> yet. > >>> > >>> > >> I had responded to Darren in the original thread that it is > >> necessary that the OS without MAC has existing semantics and a > >> reasonable DAC policy for controlling them. As far as I know we were in > >> rough agreement that the current cross zones doors should probably be a > >> RBAC controlled solaris feature that TX further restricts and the reason > >> it is not is one of resources, not design. > >> > > > > Does that contradict what I said? If cross zone doors are possible at > > all, then it makes sense for Flask/FMAC to be able to control them. > > > Yes cross zone doors are introduced by TX, and should be controlled. It > did not seem to answer Glenn's question of why IPC was being added, so > my interpretation was that TX adding cross zone doors was an example of > why Flask should add and then restrict additional IPC. Ok, thanks for clarifying. > > And even apart from doors, if there is potential for information flow > > between zones via shared filesystems or any other mechanism, then we > > want to be able to control that via Flask/FMAC. Which means we have to > > deal with access checks that cross zone boundaries regardless. > > > > > This returns to the question of flexibility. One can have a global > policy that is aware of all zones or one can have a policy for each zone > that is aware of the existence of other zones and has a policy for > dealing with them. > > To be able to support both a TX like and solaris like use of zones > requires being able to treat zones as under the same policy or as an > outside entity with only one label. > > This implies always enforcing a globally managed policy which sometimes > looks into creds with non-gz zoneid and sometimes stops at the zoneid > and a (possibly null) local policy which always stops at the zoneid for > other zone credentials. We would typically handle this by controlling the relationship between zones and the processes that run within them (an "associate" permission check between their respective labels) and then controlling what is allowed to the process labels authorized to run within a given zone. Without ever directly using the zone id in policy. Zones would just be another object class in Flask. -- Stephen Smalley National Security Agency From Cathleen.Reiher at Sun.COM Mon Jun 23 09:16:43 2008 From: Cathleen.Reiher at Sun.COM (Cathleen Reiher) Date: Mon, 23 Jun 2008 09:16:43 -0700 Subject: [fmac-discuss] [PATCH] First FMAC System Calls In-Reply-To: <1213968162.32066.360.camel@moss-spartans.epoch.ncsc.mil> References: <4859861D.2080505@sun.com> <1213968162.32066.360.camel@moss-spartans.epoch.ncsc.mil> Message-ID: John, do we have a draft man page for the loadpolicy utility available? Let me know whether I can help to create one and post it to the project page. Also, where do we want to document the new FMAC boot arguments? Is there an existing OpenSolaris man page that would be appropriate? Thanks. Cathleen. From sds at tycho.nsa.gov Mon Jun 23 09:52:15 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 23 Jun 2008 12:52:15 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: 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> Message-ID: <1214239935.32762.103.camel@moss-spartans.epoch.ncsc.mil> On Fri, 2008-06-20 at 15:32 -0700, Alan DuBoff wrote: > On Fri, 20 Jun 2008, Stephen Smalley wrote: > > SELinux has recently introduced per-domain permissive mode, which lets > > you apply it at whatever granularity you want, all the way down to > > per-process if you like. We could do the same in FMAC - that's not > > hard, and it doesn't require any special handling of zones. > > No it doesn't, but zones offer us an additional resource to leverage and > being able to tie all of it together is helpful, IMO. Yes, I think we can achieve that by treating zones as an object class in Flask and controlling the relationship between them and the processes that run within them. > I know this is blue sky, but I would like to see several things met with > the FMAC project. > > 1) The code is truely open and free, and anyone can use it no matter what > platform they're on. Aside from architecture specific code, which wouldn't > fall in this category, I'm referring to software worked on with this > project, such as a policy manipulator of such, where the SELinux community > can use the code and be able to re-use it also. As long as it is open source and in userspace, I wouldn't expect this to be a problem. > 2) Preserve and be able to co-exist with what is in place today on > OpenSolaris, the labels. Currently this is certainly the prefered way to > have any type of secure control within OpenSolaris, it is implemented and > works today and FMAC is only being developed, let alone implemented. > Somehow to me this is important, and in the global zone on OpenSolaris, I > want to have control over both the labels and fmac. I assume you mean TX and FMAC? I think they can complement one another, with the former providing coarse-grained isolation and namespace separation and the latter providing fine-grained intra-zone protection, hardening of the global zone, flexible control of cross-zone channels (where channel includes any mechanism for information flow), and scaling to large numbers of discrete labels. > 3) Strive to be the best solution for Mandatory Access Control over any > other platform. To have the best policy administration, configuration, and > usable system. Today when I speak at Linux groups, I have yet to attend > one meeting that didn't have more folks with poor taste in their mouth > over SELinux, than they had good. Even though SELinux has become a useable > system, IMO, the bitterness is not gone. I hope we can come up with a nice > system, and I have tossed some ideas around with John Weeks about this > recently. I'll be posting some here soon. You should certainly look at the advances in SELinux over the past few years, as there has been a major technology leap in policy and policy infrastructure and significant advances in usability in addition to enhancements in security functionality, performance and scalability. We have seen growing adoption and use as a result of those advances, and most Fedora users seem to be leaving SELinux enabled these days. The main issue there is whether you can easily leverage those advances or have to re-invent them independently. > With those points said, I want policy to be encompassed for all zones, in > the same way (i.e., global vs. container). A container will still need > access to get any data outside the container, but that it is one and the > same in the sense of the system. By issolating the zone to specific > policy, which is what it sounded like to me, would only make the > interfaces that much more complex. We can still have policy between > containers, on the same system. > > Another consideration is that today we have the ability to create secure > tunnels between containers. This can be done in Virtual Box for instance > by creating 2 VMs, and tunneling through. This could be a stop gap > solution for folks until true IPC could be used between the containers. > Maybe we could use FMAC for that. I wouldn't mind seeing the ability to > have a type of shared memory between virtual containers, in the same way > we do on a local machine today using shared memory between processes, but > to extend that out to the network. FMAC could be a way to manage that > between the containers, maybe through Xen, not sure...seems there has been > some work on Xen to incorporate some flask and/or type enforcement, but > not 100 percent sure about that. Yes, there is a port of Flask to Xen (in 3.2). > My interest is in the policy configuration and/or management of those > policies, even to document the policies that are there today if needed, it > seems some of those documents might not exist. Maybe we could leverage > some of the docs/pubs folks to help with that, I know a couple of them. -- Stephen Smalley National Security Agency From William.Young at Sun.COM Mon Jun 23 11:14:46 2008 From: William.Young at Sun.COM (Will Young) Date: Mon, 23 Jun 2008 14:14:46 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214231402.32762.30.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> <485C118D.8030007@sun.com> <1213993947.32066.467.camel@moss-spartans.epoch.ncsc.mil> <485C30FE.2070509@sun.com> <1214231402.32762.30.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <485FE816.2050700@sun.com> Stephen Smalley wrote: > On Fri, 2008-06-20 at 18:36 -0400, Will Young wrote: > >> Stephen Smalley wrote: >> >>> On Fri, 2008-06-20 at 16:22 -0400, Will Young wrote: >>> >>> >>>> Stephen Smalley wrote: >>>> >>>> >>>>> On Fri, 2008-06-20 at 11:31 -0700, Glenn Faden wrote: >>>>> >>>>> >>>>> >>>>> >>>>>> I also have a general question about Flask permitting cross-zone IPC. >>>>>> How can Flask permit something that is never allowed in the base OS? >>>>>> From what I've seen in SELinux, disabling enforcing mode should not >>>>>> introduce new vulnerabilities in the base OS. >>>>>> >>>>>> >>>>>> >>>>> You mentioned that in the original thread too, and Darren gave an >>>>> example. Flask/FMAC could provide further, more direct control over >>>>> controlled channels among zones, reducing the trust you are presently >>>>> placing in the proxies in the global zone and potentially providing more >>>>> flexibility there as well, although I haven't looked into the details >>>>> yet. >>>>> >>>>> >>>>> >>>> I had responded to Darren in the original thread that it is >>>> necessary that the OS without MAC has existing semantics and a >>>> reasonable DAC policy for controlling them. As far as I know we were in >>>> rough agreement that the current cross zones doors should probably be a >>>> RBAC controlled solaris feature that TX further restricts and the reason >>>> it is not is one of resources, not design. >>>> >>>> >>> Does that contradict what I said? If cross zone doors are possible at >>> all, then it makes sense for Flask/FMAC to be able to control them. >>> >>> >> Yes cross zone doors are introduced by TX, and should be controlled. It >> did not seem to answer Glenn's question of why IPC was being added, so >> my interpretation was that TX adding cross zone doors was an example of >> why Flask should add and then restrict additional IPC. >> > > Ok, thanks for clarifying. > > >>> And even apart from doors, if there is potential for information flow >>> between zones via shared filesystems or any other mechanism, then we >>> want to be able to control that via Flask/FMAC. Which means we have to >>> deal with access checks that cross zone boundaries regardless. >>> >>> >>> >> This returns to the question of flexibility. One can have a global >> policy that is aware of all zones or one can have a policy for each zone >> that is aware of the existence of other zones and has a policy for >> dealing with them. >> >> To be able to support both a TX like and solaris like use of zones >> requires being able to treat zones as under the same policy or as an >> outside entity with only one label. >> >> This implies always enforcing a globally managed policy which sometimes >> looks into creds with non-gz zoneid and sometimes stops at the zoneid >> and a (possibly null) local policy which always stops at the zoneid for >> other zone credentials. >> > > We would typically handle this by controlling the relationship between > zones and the processes that run within them (an "associate" permission > check between their respective labels) and then controlling what is > allowed to the process labels authorized to run within a given zone. > Without ever directly using the zone id in policy. Zones would just be > another object class in Flask. > That is only half the equation. I am asking that: fmacsys_security_load_policy->fmac_load_policy attach the policy to the zone_t of the (privileged) caller, not reject non-GZ callers with otherwise appropriate credentials. In any situation where one is applying MAC one should have a combination of 2 cred or generic resources. One must apply the global policy in relation to these and then apply the local policy of the target object (crgetzone(targ_cr)->fmac_policy) if it is not a resource/global zone cred. -Will From alan.duboff at sun.com Mon Jun 23 13:48:11 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Mon, 23 Jun 2008 13:48:11 -0700 (PDT) Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <485C3DC8.2060502@sun.com> 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> Message-ID: On Fri, 20 Jun 2008, Glenn Faden wrote: >> It's not clear to me how Glenn would use that issolation, but for me it >> seems we will eventually get back to a point where we traverse a set of >> policies in actual operation, and that additional layer doesn't seem >> needed. > Zones provide most of the semantics of virtual machines. The degree to which > they are locked down should depend on their intended use. So requiring them > all to be identical with respect to FMAC policy seems like an undesirable > constraint. I'm not advocating a particular implementation, just some > functionality and goals. Is there any advantage to having those policies separated? IOW, why wouldn't those policies be a part of the system policy, but have some designation to the zone/vm itself? One of our advantages today is the fact that we do have a label on a container, but how the finer granularity is broken up in the future doesn't seem to be a consensus by anyone. > I think we need to be more precise when we use the word label. An MLS label > is a component of a security context which is itself sometimes called a label > (it has a textual representation). So I don't understand your comment about a > distinction between labels and FMAC. I don't expect any of the current policy to work with FMAC, nor would I expect FMAC to manage policy on the MLS labels. Currently we have a similar problem in trying to manage policy on MLS labels. I would like to see a single policy program that could manage both sets of policies, but don't expect either of those policies to cross over to the other technology. Possible have the ability to work with each other, but not to be able to encompass the policy completely. > Types and MLS labels are distinct, but > they are both components of a security context. We need to support > environments where the security contexts of zones may differ. I completely > agree that FMAC must be global, since there is only one kernel. My point was > that the global policy should take into account that zones may be provisioned > for different purposes, so there should be hooks in the policy to support > that. We have this ability today with a container, and there doesn't seem reason to change it. Both existing and new technology (MLS vs FMAC) should function and operate with each other, and no reason not to use something in place that functions today. Could you elaborate on the "different purpose", possibly giving an example? -- Alan DuBoff - Solaris x86 IHV/OEM Group From alan.duboff at sun.com Mon Jun 23 13:53:28 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Mon, 23 Jun 2008 13:53:28 -0700 (PDT) Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214229261.32762.10.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> <485C144E.5010204@sun.com> <1214229261.32762.10.camel@moss-spartans.epoch.ncsc.mil> Message-ID: On Mon, 23 Jun 2008, Stephen Smalley wrote: > Ok, but I think it is safe to say that there are mechanisms for > information flow between zones already, and thus providing Flask control > over them makes sense. Yes it makes sense, but I would like to see the current technology leveraged, if possible, for that purpose. IOW, where FMAC can leverage the MLS components in place, so that work doesn't need to be completely developed. I would also like to see the FMAC code to be usable for flask/te if possible, so that SELinux could reuse some of the development we've done. Since SELinux doesn't have a notion of a container like we do on OpenSolaris, would there be an advantage to reinventing the same wheel? Interoperability seems key, IMO. -- Alan DuBoff - Solaris x86 IHV/OEM Group From alan.duboff at sun.com Mon Jun 23 14:00:50 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Mon, 23 Jun 2008 14:00:50 -0700 (PDT) Subject: [fmac-discuss] Zones and Flask In-Reply-To: <480291B3.7090602@sun.com> References: <480291B3.7090602@sun.com> Message-ID: On Sun, 13 Apr 2008, Glenn Faden wrote: > I'd like to get a discussion going about how Solaris zones should be > treated by Flask. Since all zones share a single kernel it is natural to > assume that they will share the same security server. But the Solaris > kernel has zone-awareness built in, and individual zones can act like > virtual machines, so Flask should support some notion of zone-awareness, > as well. I'd like to see this discussion also. As I posted, I would like to leverage any technology that we have today in place, and today we have access control on zones through TX. > There is the related issue of flexibility. Zones provide strong but > coarse separation, and providing flexibility of cross-zone policies is > generally a bad thing. The major premise of the Solaris zone model is > that no process in a non-global zone (even running with all the zone's > privileges) can cause damage to any other zone including the global > zone. In Trusted Extensions we've gone even further to prevent any > communication between processes in different zones, including via the > filesystem or the network. I would like to see this left as-is, and have FMAC drop in to add other functionality that we don't have. While we could create the same functionality with FMAC and have it manage access to containers, I am not sure I see the advantage of that from what we have today. > One could argue that Flask could be used to provide a more flexible > cross-zone access control, but I think this would be a mistake. I agree, since we have that in place today between containers. > I think the value of Flask is its ability to provide fine-grained access > within each zone, especially within the global zone. Since the global > zone is special, it may need to have unique policy rules from non-global > zones. But rather than special-case the global zone, we should consider > per-zone attributes as part of the policy specification. Yes, I agree. > One more issue is the fact that user IDs in different zones may > correspond to the same user (as they do with Trusted Extensions) or may > be unrelated, as in the more general consolidation model. In the latter > case, it is likely that users would be assigned different initial > security contexts since they represent different individuals. But we may > want to do that in either case since the MLS component of the security > context, for example, would be different in each zone. Wether they correspond to the same user or not, the MAC is enforced on the ID. At the end of the day does it matter if they're the same user? -- Alan DuBoff - Solaris x86 IHV/OEM Group From john.weeks at sun.com Mon Jun 23 16:01:17 2008 From: john.weeks at sun.com (John Weeks) Date: Mon, 23 Jun 2008 16:01:17 -0700 Subject: [fmac-discuss] [PATCH] First FMAC System Calls In-Reply-To: References: <4859861D.2080505@sun.com> <1213968162.32066.360.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <48602B3D.60607@sun.com> Cathleen Reiher wrote: > John, do we have a draft man page > for the loadpolicy utility available? > Let me know whether I can help to > create one and post it to the project > page. Other than the comments in the patch, we don't have one yet. If you would like to generate a first draft that would be great :-) > > Also, where do we want to document > the new FMAC boot arguments? Is > there an existing OpenSolaris man > page that would be appropriate? Take a look at kernel(1M). > > Thanks. > > Cathleen. > From Glenn.Faden at Sun.COM Mon Jun 23 16:07:49 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Mon, 23 Jun 2008 16:07:49 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: 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> Message-ID: <48602CC5.3090107@sun.com> Alan DuBoff wrote: > On Fri, 20 Jun 2008, Glenn Faden wrote: > > Could you elaborate on the "different purpose", possibly giving an > example? > > You might have a zone for software developers to do debugging, and another zone which acts as a web server. If these are sparse zones then the files in the lofs mounted file systems would have to have the same security contexts stored in their extended attributes, but we might want to allow the prstat(1) program in the developer zone to be able to observe everything, but only show processes with the web-related types in the web-server zone. If the two zones are whole-root zones, then their instances of prtsat(1) would actually have separate pathnames, and could potentially have different security contexts stored in their respective extended attributes. This brings up the issue of specifying pathnames in the various policy files. When and how would the file systems in zones get their security contexts applied? I think this would have to be done for each zone when it is initially booted, and potentially verified on each zone reboot. --Glenn From Glenn.Faden at Sun.COM Mon Jun 23 16:23:33 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Mon, 23 Jun 2008 16:23:33 -0700 Subject: [fmac-discuss] Zones and Flask In-Reply-To: References: <480291B3.7090602@sun.com> Message-ID: <48603075.3040104@sun.com> Alan DuBoff wrote: > On Sun, 13 Apr 2008, Glenn Faden wrote: > > >> One more issue is the fact that user IDs in different zones may >> correspond to the same user (as they do with Trusted Extensions) or may >> be unrelated, as in the more general consolidation model. In the latter >> case, it is likely that users would be assigned different initial >> security contexts since they represent different individuals. But we may >> want to do that in either case since the MLS component of the security >> context, for example, would be different in each zone. >> > > Wether they correspond to the same user or not, the MAC is enforced on the > ID. At the end of the day does it matter if they're the same user? > MAC enforcement is not based on user IDs. I was trying to point out that the assignment of the initial security context to a user needed to be based on what zone they were running in. The same is currently true for attributes like default and limit privileges because there is an instance of /etc/user_attr in each zone. These attributes are assigned to the user's credential as part of the per-zone PAM authentication. --Glenn From sds at tycho.nsa.gov Tue Jun 24 05:10:46 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 24 Jun 2008 08:10:46 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <48602CC5.3090107@sun.com> 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> Message-ID: <1214309446.32762.162.camel@moss-spartans.epoch.ncsc.mil> On Mon, 2008-06-23 at 16:07 -0700, Glenn Faden wrote: > Alan DuBoff wrote: > > On Fri, 20 Jun 2008, Glenn Faden wrote: > > > > Could you elaborate on the "different purpose", possibly giving an > > example? > > > > > You might have a zone for software developers to do debugging, and > another zone which acts as a web server. If these are sparse zones then > the files in the lofs mounted file systems would have to have the same > security contexts stored in their extended attributes, but we might want > to allow the prstat(1) program in the developer zone to be able to > observe everything, but only show processes with the web-related types > in the web-server zone. > > If the two zones are whole-root zones, then their instances of prtsat(1) > would actually have separate pathnames, and could potentially have > different security contexts stored in their respective extended attributes. > > This brings up the issue of specifying pathnames in the various policy > files. When and how would the file systems in zones get their security > contexts applied? I think this would have to be done for each zone when > it is initially booted, and potentially verified on each zone reboot. Filesystems should be labeled when they are first populated (e.g. zone creation). At boot, if we have reason to believe that an inconsistency has arisen (e.g. prior boot with FMAC disabled), we can initiate an automatic relabel, but that is a time consuming process and not something we want to do on every boot (plus it defeats the purpose of having persistent labels in the first place, as the initial file contexts configuration is only to specify the initial state and then we want any runtime-created files to be labeled in accordance with their runtime security properties). -- Stephen Smalley National Security Agency From Darren.Moffat at Sun.COM Tue Jun 24 06:26:45 2008 From: Darren.Moffat at Sun.COM (Darren J Moffat) Date: Tue, 24 Jun 2008 14:26:45 +0100 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214309446.32762.162.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> Message-ID: <4860F615.5030302@Sun.COM> Stephen Smalley wrote: > Filesystems should be labeled when they are first populated (e.g. zone > creation). At boot, if we have reason to believe that an inconsistency > has arisen (e.g. prior boot with FMAC disabled), we can initiate an > automatic relabel, but that is a time consuming process and not > something we want to do on every boot (plus it defeats the purpose of > having persistent labels in the first place, as the initial file > contexts configuration is only to specify the initial state and then we > want any runtime-created files to be labeled in accordance with their > runtime security properties). When you mention persistent labels do you mean explicit per file labels stored in side the filesystem, say as extended attributes ? -- Darren J Moffat From sds at tycho.nsa.gov Tue Jun 24 06:31:37 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 24 Jun 2008 09:31:37 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <4860F615.5030302@Sun.COM> 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> Message-ID: <1214314297.32762.201.camel@moss-spartans.epoch.ncsc.mil> On Tue, 2008-06-24 at 14:26 +0100, Darren J Moffat wrote: > Stephen Smalley wrote: > > Filesystems should be labeled when they are first populated (e.g. zone > > creation). At boot, if we have reason to believe that an inconsistency > > has arisen (e.g. prior boot with FMAC disabled), we can initiate an > > automatic relabel, but that is a time consuming process and not > > something we want to do on every boot (plus it defeats the purpose of > > having persistent labels in the first place, as the initial file > > contexts configuration is only to specify the initial state and then we > > want any runtime-created files to be labeled in accordance with their > > runtime security properties). > > When you mention persistent labels do you mean explicit per file labels > stored in side the filesystem, say as extended attributes ? Correct. That is what is done in SELinux, and is important for supporting fine-grained protection (as was true even of Trusted Solaris prior to TX). -- Stephen Smalley National Security Agency From Glenn.Faden at Sun.COM Tue Jun 24 09:11:13 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Tue, 24 Jun 2008 09:11:13 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214309446.32762.162.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> Message-ID: <48611CA1.1010802@sun.com> Stephen Smalley wrote: > Filesystems should be labeled when they are first populated (e.g. zone > creation). At boot, if we have reason to believe that an inconsistency > has arisen (e.g. prior boot with FMAC disabled), we can initiate an > automatic relabel, but that is a time consuming process and not > something we want to do on every boot (plus it defeats the purpose of > having persistent labels in the first place, as the initial file > contexts configuration is only to specify the initial state and then we > want any runtime-created files to be labeled in accordance with their > runtime security properties). > I see your point about labeling the zone when it is first installed, but there are also advantages to waiting until first boot. Today we take advantage of ZFS snapshots to quickly clone zones. However, cloning a zone whose filesystem has explicit security contexts for each file will not be appropriate in MLS environments unless the new zone is relabeled after cloning. It may be more efficient to defer labeling the zone's fileystems until a snapshot can be taken. Then the clones could be labeled either at first boot or via another intermediate step. By the way, we will face a similar issue with encrypted ZFS datasets. Once a zone's dataset is encrypted with a uniqe key (e.g. based on its MLS label) then it can't be used as a snapshot for cloning at another label. From a disk usage standpoint, it probably makes no sense to clone datasets that are going to be encrypted since there is no sharing of the underlying storage. However, in the FMAC case, with copy-on-write, clones would still share most of their data blocks even after labeling, since only the extended attribute blocks would be different. From sds at tycho.nsa.gov Tue Jun 24 10:06:48 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 24 Jun 2008 13:06:48 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <48611CA1.1010802@sun.com> 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> <48611CA1.1010802@sun.com> Message-ID: <1214327208.32762.270.camel@moss-spartans.epoch.ncsc.mil> On Tue, 2008-06-24 at 09:11 -0700, Glenn Faden wrote: > Stephen Smalley wrote: > > Filesystems should be labeled when they are first populated (e.g. zone > > creation). At boot, if we have reason to believe that an inconsistency > > has arisen (e.g. prior boot with FMAC disabled), we can initiate an > > automatic relabel, but that is a time consuming process and not > > something we want to do on every boot (plus it defeats the purpose of > > having persistent labels in the first place, as the initial file > > contexts configuration is only to specify the initial state and then we > > want any runtime-created files to be labeled in accordance with their > > runtime security properties). > > > I see your point about labeling the zone when it is first installed, but > there are also advantages to waiting until first boot. Today we take > advantage of ZFS snapshots to quickly clone zones. However, cloning a > zone whose filesystem has explicit security contexts for each file will > not be appropriate in MLS environments unless the new zone is relabeled > after cloning. It may be more efficient to defer labeling the zone's > fileystems until a snapshot can be taken. Then the clones could be > labeled either at first boot or via another intermediate step. In the case of Linux, what is done is that in addition to install-time labeling of files (integrated into the package management software), the system init scripts check for a flag file (/.autorelabel) at boot to see whether a full relabel is required, and if so, initiate a full relabel and remove the flag file. The flag file is automatically created by the system init scripts if you ever boot with SELinux disabled such that the next time you boot with it enabled, you'll get a full relabel. And there is an "autorelabel" boot parameter that can be specified that will force a full relabel by the system init scripts regardless of whether the flag file exists. > By the way, we will face a similar issue with encrypted ZFS datasets. > Once a zone's dataset is encrypted with a uniqe key (e.g. based on its > MLS label) then it can't be used as a snapshot for cloning at another label. > > From a disk usage standpoint, it probably makes no sense to clone > datasets that are going to be encrypted since there is no sharing of the > underlying storage. However, in the FMAC case, with copy-on-write, > clones would still share most of their data blocks even after labeling, > since only the extended attribute blocks would be different. -- Stephen Smalley National Security Agency From Glenn.Faden at Sun.COM Tue Jun 24 10:34:48 2008 From: Glenn.Faden at Sun.COM (Glenn Faden) Date: Tue, 24 Jun 2008 10:34:48 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214327208.32762.270.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> <48611CA1.1010802@sun.com> <1214327208.32762.270.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <48613038.60404@sun.com> Stephen Smalley wrote: > > > In the case of Linux, what is done is that in addition to install-time > labeling of files (integrated into the package management software), the > system init scripts check for a flag file (/.autorelabel) at boot to see > whether a full relabel is required, and if so, initiate a full relabel > and remove the flag file. The flag file is automatically created by the > system init scripts if you ever boot with SELinux disabled such that the > next time you boot with it enabled, you'll get a full relabel. And > there is an "autorelabel" boot parameter that can be specified that will > force a full relabel by the system init scripts regardless of whether > the flag file exists. > > The new Image Packaging System (IPS) currently doesn't support ACLs or extended attributes (see http://opensolaris.org/sc/src/pkg/gate/src/man/pkg.5.txt ), but it is obviously in active developement. I've been following the discussions on the selinux alias about dealing with types defined in RPMs that aren't currently defined in the policy. So we need to factor that into any plans to extend IPS. From sds at tycho.nsa.gov Tue Jun 24 12:16:28 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 24 Jun 2008 15:16:28 -0400 Subject: [fmac-discuss] [PATCH] Add [gs]etenforce utilities Message-ID: <1214334988.32762.311.camel@moss-spartans.epoch.ncsc.mil> This patch adds getenforce and setenforce utility programs that in turn call the corresponding FMAC system calls. getenforce takes no arguments, outputs the current status, and exits with a corresponding exit code. setenforce takes a single argument indicating the desired status as follows: setenforce [0|1|permissive|enforcing] where 0 is the same as permissive and 1 is the same as enforcing. 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 @@ -29,7 +29,9 @@ include ../Makefile.cmd SUBDIR_CMD = checkpolicy \ setfiles \ - loadpolicy + loadpolicy \ + setenforce \ + getenforce SUBDIR_POLICY = \ policy diff --git a/usr/src/cmd/fmac/getenforce/Makefile b/usr/src/cmd/fmac/getenforce/Makefile new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/getenforce/Makefile @@ -0,0 +1,44 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= getenforce + +include ../../Makefile.cmd + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTSBINPROG) + +clean: + +lint: lint_PROG + +include ../../Makefile.targ diff --git a/usr/src/cmd/fmac/getenforce/getenforce.c b/usr/src/cmd/fmac/getenforce/getenforce.c new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/getenforce/getenforce.c @@ -0,0 +1,81 @@ +/* + * 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. + */ + +/* + * Get and display FMAC enforcing status. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int errflg = 0; + int c; + int mode; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + (void) textdomain(TEXT_DOMAIN); + + while ((c = getopt(argc, argv, "")) != EOF) { + switch (c) { + case '?': + errflg++; + break; + } + } + + if (errflg || argc != 1) { + (void) fprintf(stderr, + gettext("usage: getenforce\n")); + return (1); + } + + mode = security_getenforce(); + if (mode == 1) + printf("enforcing\n"); + else if (mode == 0) + printf("permissive\n"); + else if (mode < 0 && errno == ENOSYS) + printf("disabled\n"); + else { + (void) fprintf(stderr, + gettext("getenforce: getting status failed: %s\n"), + strerror(errno)); + } + + return (mode); +} diff --git a/usr/src/cmd/fmac/setenforce/Makefile b/usr/src/cmd/fmac/setenforce/Makefile new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/setenforce/Makefile @@ -0,0 +1,44 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= setenforce + +include ../../Makefile.cmd + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTSBINPROG) + +clean: + +lint: lint_PROG + +include ../../Makefile.targ diff --git a/usr/src/cmd/fmac/setenforce/setenforce.c b/usr/src/cmd/fmac/setenforce/setenforce.c new file mode 100644 --- /dev/null +++ b/usr/src/cmd/fmac/setenforce/setenforce.c @@ -0,0 +1,88 @@ +/* + * 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. + */ + +/* + * Set FMAC enforcing status to permissive or enforcing. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char *status; + int errflg = 0; + int c; + int mode; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ +#endif + (void) textdomain(TEXT_DOMAIN); + + while ((c = getopt(argc, argv, "")) != EOF) { + switch (c) { + case '?': + errflg++; + break; + } + } + + if (errflg || argc != 2) { + (void) fprintf(stderr, + gettext("usage: setenforce [0|1|permissive|enforcing]\n")); + return (1); + } + + status = *++argv; + if (strcasecmp(status, "permissive") == 0 || strcmp(status, "0") == 0) + mode = 0; + else if (strcasecmp(status, "enforcing") == 0 || + strcmp(status, "1") == 0) + mode = 1; + else { + (void) fprintf(stderr, + gettext("usage: setenforce [0|1|permissive|enforcing]\n")); + return (1); + } + + if (security_setenforce(mode)) { + (void) fprintf(stderr, + gettext("setenforce: setting status to %s failed: %s\n"), + status, strerror(errno)); + return (1); + } + + return (0); +} diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com --- a/usr/src/pkgdefs/SUNWcsr/prototype_com +++ b/usr/src/pkgdefs/SUNWcsr/prototype_com @@ -407,6 +407,8 @@ f none sbin/ifparse 555 root bin f none sbin/ifparse 555 root bin s none sbin/in.mpathd=../usr/lib/inet/in.mpathd f none sbin/loadpolicy 555 root bin +f none sbin/setenforce 555 root bin +f none sbin/getenforce 555 root bin f none sbin/soconfig 555 root bin f none sbin/init 555 root sys s none sbin/jsh=sh -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Tue Jun 24 12:21:35 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Tue, 24 Jun 2008 15:21:35 -0400 Subject: [fmac-discuss] [PATCH] Check for fmac_enabled, reset AVC Message-ID: <1214335295.32762.318.camel@moss-spartans.epoch.ncsc.mil> Return immediately from the other FMAC syscalls if !fmac_enabled, and reset the access vector cache when switching to enforcing mode to flush permissions granted while permissive. 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 @@ -38,11 +38,15 @@ #include #include #include +#include +#include static int fmacsys_getenforce() { - if (fmac_enforcing) + if (!fmac_enabled) + return (set_errno(ENOSYS)); + else if (fmac_enforcing) return (1); else return (0); @@ -52,6 +56,11 @@ fmacsys_setenforce(int mode) fmacsys_setenforce(int mode) { int err = 0; + + if (!fmac_enabled) { + err = ENOSYS; + goto done; + } if (!INGLOBALZONE(curproc)) { err = EINVAL; @@ -67,6 +76,8 @@ fmacsys_setenforce(int mode) case 0: case 1: fmac_enforcing = mode; + if (fmac_enforcing) + avc_ss_reset(0); break; default: err = EINVAL; @@ -146,6 +157,9 @@ 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); @@ -189,6 +203,9 @@ 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); -- Stephen Smalley National Security Agency From darrenm at opensolaris.org Tue Jun 24 13:27:34 2008 From: darrenm at opensolaris.org (Darren J Moffat) Date: Tue, 24 Jun 2008 21:27:34 +0100 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <48611CA1.1010802@sun.com> 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> <48611CA1.1010802@sun.com> Message-ID: <486158B6.9020608@opensolaris.org> Glenn Faden wrote: > By the way, we will face a similar issue with encrypted ZFS datasets. > Once a zone's dataset is encrypted with a uniqe key (e.g. based on its > MLS label) then it can't be used as a snapshot for cloning at another label. Actually I think it would work, you would clone it and then do a key change. Since you say a key per MLS label that means we would be doing per dataset keying. Note that key change doesn't change the actual encryption key just the wrapping key. -- Darren J Moffat From john.weeks at sun.com Tue Jun 24 17:54:27 2008 From: john.weeks at sun.com (John Weeks) Date: Tue, 24 Jun 2008 17:54:27 -0700 Subject: [fmac-discuss] [PATCH] Add [gs]etenforce utilities In-Reply-To: <1214334988.32762.311.camel@moss-spartans.epoch.ncsc.mil> References: <1214334988.32762.311.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <48619743.5020803@sun.com> Stephen Smalley wrote: > This patch adds getenforce and setenforce utility programs that in turn > call the corresponding FMAC system calls. > > getenforce takes no arguments, outputs the current status, and exits > with a corresponding exit code. > > setenforce takes a single argument indicating the desired status as > follows: > setenforce [0|1|permissive|enforcing] > where 0 is the same as permissive and 1 is the same as enforcing. Thank you for contributing these utilities. Acked-by: John Weeks > > 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 > @@ -29,7 +29,9 @@ include ../Makefile.cmd > > SUBDIR_CMD = checkpolicy \ > setfiles \ > - loadpolicy > + loadpolicy \ > + setenforce \ > + getenforce > > SUBDIR_POLICY = \ > policy > diff --git a/usr/src/cmd/fmac/getenforce/Makefile b/usr/src/cmd/fmac/getenforce/Makefile > new file mode 100644 > --- /dev/null > +++ b/usr/src/cmd/fmac/getenforce/Makefile > @@ -0,0 +1,44 @@ > +# > +# CDDL HEADER START > +# > +# The contents of this file are subject to the terms of the > +# Common Development and Distribution License, Version 1.0 only > +# (the "License"). You may not use this file except in compliance > +# with the License. > +# > +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE > +# or http://www.opensolaris.org/os/licensing. > +# See the License for the specific language governing permissions > +# and limitations under the License. > +# > +# When distributing Covered Code, include this CDDL HEADER in each > +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. > +# If applicable, add the following below this CDDL HEADER, with the > +# fields enclosed by brackets "[]" replaced with your own identifying > +# information: Portions Copyright [yyyy] [name of copyright owner] > +# > +# CDDL HEADER END > +# > +# > +# > +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. > +# Use is subject to license terms. > +# > + > +PROG= getenforce > + > +include ../../Makefile.cmd > + > +CFLAGS += $(CCVERBOSE) > + > +.KEEP_STATE: > + > +all: $(PROG) > + > +install: all $(ROOTSBINPROG) > + > +clean: > + > +lint: lint_PROG > + > +include ../../Makefile.targ > diff --git a/usr/src/cmd/fmac/getenforce/getenforce.c b/usr/src/cmd/fmac/getenforce/getenforce.c > new file mode 100644 > --- /dev/null > +++ b/usr/src/cmd/fmac/getenforce/getenforce.c > @@ -0,0 +1,81 @@ > +/* > + * 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. > + */ > + > +/* > + * Get and display FMAC enforcing status. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +int > +main(int argc, char *argv[]) > +{ > + int errflg = 0; > + int c; > + int mode; > + > + (void) setlocale(LC_ALL, ""); > +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ > +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ > +#endif > + (void) textdomain(TEXT_DOMAIN); > + > + while ((c = getopt(argc, argv, "")) != EOF) { > + switch (c) { > + case '?': > + errflg++; > + break; > + } > + } > + > + if (errflg || argc != 1) { > + (void) fprintf(stderr, > + gettext("usage: getenforce\n")); > + return (1); > + } > + > + mode = security_getenforce(); > + if (mode == 1) > + printf("enforcing\n"); > + else if (mode == 0) > + printf("permissive\n"); > + else if (mode < 0 && errno == ENOSYS) > + printf("disabled\n"); > + else { > + (void) fprintf(stderr, > + gettext("getenforce: getting status failed: %s\n"), > + strerror(errno)); > + } > + > + return (mode); > +} > diff --git a/usr/src/cmd/fmac/setenforce/Makefile b/usr/src/cmd/fmac/setenforce/Makefile > new file mode 100644 > --- /dev/null > +++ b/usr/src/cmd/fmac/setenforce/Makefile > @@ -0,0 +1,44 @@ > +# > +# CDDL HEADER START > +# > +# The contents of this file are subject to the terms of the > +# Common Development and Distribution License, Version 1.0 only > +# (the "License"). You may not use this file except in compliance > +# with the License. > +# > +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE > +# or http://www.opensolaris.org/os/licensing. > +# See the License for the specific language governing permissions > +# and limitations under the License. > +# > +# When distributing Covered Code, include this CDDL HEADER in each > +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. > +# If applicable, add the following below this CDDL HEADER, with the > +# fields enclosed by brackets "[]" replaced with your own identifying > +# information: Portions Copyright [yyyy] [name of copyright owner] > +# > +# CDDL HEADER END > +# > +# > +# > +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. > +# Use is subject to license terms. > +# > + > +PROG= setenforce > + > +include ../../Makefile.cmd > + > +CFLAGS += $(CCVERBOSE) > + > +.KEEP_STATE: > + > +all: $(PROG) > + > +install: all $(ROOTSBINPROG) > + > +clean: > + > +lint: lint_PROG > + > +include ../../Makefile.targ > diff --git a/usr/src/cmd/fmac/setenforce/setenforce.c b/usr/src/cmd/fmac/setenforce/setenforce.c > new file mode 100644 > --- /dev/null > +++ b/usr/src/cmd/fmac/setenforce/setenforce.c > @@ -0,0 +1,88 @@ > +/* > + * 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. > + */ > + > +/* > + * Set FMAC enforcing status to permissive or enforcing. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +int > +main(int argc, char *argv[]) > +{ > + char *status; > + int errflg = 0; > + int c; > + int mode; > + > + (void) setlocale(LC_ALL, ""); > +#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ > +#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ > +#endif > + (void) textdomain(TEXT_DOMAIN); > + > + while ((c = getopt(argc, argv, "")) != EOF) { > + switch (c) { > + case '?': > + errflg++; > + break; > + } > + } > + > + if (errflg || argc != 2) { > + (void) fprintf(stderr, > + gettext("usage: setenforce [0|1|permissive|enforcing]\n")); > + return (1); > + } > + > + status = *++argv; > + if (strcasecmp(status, "permissive") == 0 || strcmp(status, "0") == 0) > + mode = 0; > + else if (strcasecmp(status, "enforcing") == 0 || > + strcmp(status, "1") == 0) > + mode = 1; > + else { > + (void) fprintf(stderr, > + gettext("usage: setenforce [0|1|permissive|enforcing]\n")); > + return (1); > + } > + > + if (security_setenforce(mode)) { > + (void) fprintf(stderr, > + gettext("setenforce: setting status to %s failed: %s\n"), > + status, strerror(errno)); > + return (1); > + } > + > + return (0); > +} > diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com > --- a/usr/src/pkgdefs/SUNWcsr/prototype_com > +++ b/usr/src/pkgdefs/SUNWcsr/prototype_com > @@ -407,6 +407,8 @@ f none sbin/ifparse 555 root bin > f none sbin/ifparse 555 root bin > s none sbin/in.mpathd=../usr/lib/inet/in.mpathd > f none sbin/loadpolicy 555 root bin > +f none sbin/setenforce 555 root bin > +f none sbin/getenforce 555 root bin > f none sbin/soconfig 555 root bin > f none sbin/init 555 root sys > s none sbin/jsh=sh > > > From alan.duboff at sun.com Wed Jun 25 03:57:00 2008 From: alan.duboff at sun.com (Alan DuBoff) Date: Wed, 25 Jun 2008 03:57:00 -0700 (PDT) Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214239935.32762.103.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> <1214239935.32762.103.camel@moss-spartans.epoch.ncsc.mil> Message-ID: On Mon, 23 Jun 2008, Stephen Smalley wrote: > As long as it is open source and in userspace, I wouldn't expect this to > be a problem. If I didn't see so many license conflicts, it wouldn't bother me. I have to admit, how you license your code within the NSA has got me to thinking about licensing and copyright. Somehow being licensed in the public domain with no copyright seems right. If nobody holds any copyright, it makes we wonder who would hold liability...it is open and free code, nobody holds any IP on it, in that regard. This means that Sun needs to have a license that works with the Linux community. This is not so cut and dried with today's license. > I assume you mean TX and FMAC? Yes. > You should certainly look at the advances in SELinux over the past few > years, as there has been a major technology leap in policy and policy > infrastructure and significant advances in usability in addition to > enhancements in security functionality, performance and scalability. Yes, I think it has come a long way. I was just commenting about the response around Silicon Valley at Linux user groups that I have spoken at in the past couple months (BayLISA, SVLUG, EBLUG). I know that most of those folks haven't tried a recent version, which does actually work pretty good, but those folks still have bitterness towards the early verisons they tried and/or heard about. But the bitterness is eroding slowly. At least that is what it seems like to me. > We have seen growing adoption and use as a result of those advances, and > most Fedora users seem to be leaving SELinux enabled these days. The > main issue there is whether you can easily leverage those advances or > have to re-invent them independently. In most cases the question of wether to enable it or not is being able to use your system without a massive amount of configuration. I believe this is the biggest barrier for both TX and SELinux. This must change, because trusted systems will be mandatory in the future for a lot of folks, IMO. -- Alan DuBoff - Solaris x86 IHV/OEM Group From john.weeks at sun.com Wed Jun 25 12:09:26 2008 From: john.weeks at sun.com (John Weeks) Date: Wed, 25 Jun 2008 12:09:26 -0700 Subject: [fmac-discuss] [PATCH] Check for fmac_enabled, reset AVC In-Reply-To: <1214335295.32762.318.camel@moss-spartans.epoch.ncsc.mil> References: <1214335295.32762.318.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <486297E6.5000600@sun.com> Stephen Smalley wrote: > Return immediately from the other FMAC syscalls if !fmac_enabled, and > reset the access vector cache when switching to enforcing mode to flush > permissions granted while permissive. 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 > @@ -38,11 +38,15 @@ > #include > #include > #include > +#include > +#include > > static int > fmacsys_getenforce() > { > - if (fmac_enforcing) > + if (!fmac_enabled) > + return (set_errno(ENOSYS)); > + else if (fmac_enforcing) > return (1); > else > return (0); > @@ -52,6 +56,11 @@ fmacsys_setenforce(int mode) > fmacsys_setenforce(int mode) > { > int err = 0; > + > + if (!fmac_enabled) { > + err = ENOSYS; > + goto done; > + } > > if (!INGLOBALZONE(curproc)) { > err = EINVAL; > @@ -67,6 +76,8 @@ fmacsys_setenforce(int mode) > case 0: > case 1: > fmac_enforcing = mode; > + if (fmac_enforcing) > + avc_ss_reset(0); > break; > default: > err = EINVAL; > @@ -146,6 +157,9 @@ 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); > @@ -189,6 +203,9 @@ 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); > > From Darren.Moffat at Sun.COM Thu Jun 26 04:20:11 2008 From: Darren.Moffat at Sun.COM (Darren J Moffat) Date: Thu, 26 Jun 2008 12:20:11 +0100 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <1214314297.32762.201.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> Message-ID: <48637B6B.7050103@Sun.COM> Stephen Smalley wrote: > On Tue, 2008-06-24 at 14:26 +0100, Darren J Moffat wrote: >> Stephen Smalley wrote: >>> Filesystems should be labeled when they are first populated (e.g. zone >>> creation). At boot, if we have reason to believe that an inconsistency >>> has arisen (e.g. prior boot with FMAC disabled), we can initiate an >>> automatic relabel, but that is a time consuming process and not >>> something we want to do on every boot (plus it defeats the purpose of >>> having persistent labels in the first place, as the initial file >>> contexts configuration is only to specify the initial state and then we >>> want any runtime-created files to be labeled in accordance with their >>> runtime security properties). >> When you mention persistent labels do you mean explicit per file labels >> stored in side the filesystem, say as extended attributes ? > > Correct. That is what is done in SELinux, and is important for > supporting fine-grained protection (as was true even of Trusted Solaris > prior to TX). I'm assuming that the extended attributes we have in ZFS today are not sufficient because these would need to be in a namespace where modification is controlled either by a privilege or by an FMAC policy. -- Darren J Moffat From john.weeks at sun.com Sun Jun 29 23:31:56 2008 From: john.weeks at sun.com (John Weeks) Date: Sun, 29 Jun 2008 23:31:56 -0700 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <48637B6B.7050103@Sun.COM> 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> Message-ID: <48687DDC.1050203@sun.com> Darren J Moffat wrote: > Stephen Smalley wrote: >> On Tue, 2008-06-24 at 14:26 +0100, Darren J Moffat wrote: >>> Stephen Smalley wrote: >>>> Filesystems should be labeled when they are first populated (e.g. zone >>>> creation). At boot, if we have reason to believe that an inconsistency >>>> has arisen (e.g. prior boot with FMAC disabled), we can initiate an >>>> automatic relabel, but that is a time consuming process and not >>>> something we want to do on every boot (plus it defeats the purpose of >>>> having persistent labels in the first place, as the initial file >>>> contexts configuration is only to specify the initial state and then we >>>> want any runtime-created files to be labeled in accordance with their >>>> runtime security properties). >>> When you mention persistent labels do you mean explicit per file labels >>> stored in side the filesystem, say as extended attributes ? >> Correct. That is what is done in SELinux, and is important for >> supporting fine-grained protection (as was true even of Trusted Solaris >> prior to TX). > > I'm assuming that the extended attributes we have in ZFS today are not > sufficient because these would need to be in a namespace where > modification is controlled either by a privilege or by an FMAC policy. > We should be able to intercept extended attribute calls to prevent unauthorized modification of FMAC specific attributes. NFS might be a little tricker, but I would rather use an existing mechanism if we can. In the original prototype, I did use extended attributes to hold the file object context. It's wasn't a complete implementation (files contexts were created with a utility), but I was retrieving the file context when a vnode was opened. From sds at tycho.nsa.gov Mon Jun 30 07:33:48 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 30 Jun 2008 10:33:48 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: 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> <1214239935.32762.103.camel@moss-spartans.epoch.ncsc.mil> Message-ID: <1214836428.22447.92.camel@moss-spartans.epoch.ncsc.mil> On Wed, 2008-06-25 at 03:57 -0700, Alan DuBoff wrote: > On Mon, 23 Jun 2008, Stephen Smalley wrote: > > > As long as it is open source and in userspace, I wouldn't expect this to > > be a problem. > > If I didn't see so many license conflicts, it wouldn't bother me. > > I have to admit, how you license your code within the NSA has got me to > thinking about licensing and copyright. > > Somehow being licensed in the public domain with no copyright seems right. > If nobody holds any copyright, it makes we wonder who would hold > liability...it is open and free code, nobody holds any IP on it, in that > regard. > > This means that Sun needs to have a license that works with the Linux > community. This is not so cut and dried with today's license. > > > I assume you mean TX and FMAC? > > Yes. > > > You should certainly look at the advances in SELinux over the past few > > years, as there has been a major technology leap in policy and policy > > infrastructure and significant advances in usability in addition to > > enhancements in security functionality, performance and scalability. > > Yes, I think it has come a long way. I was just commenting about the > response around Silicon Valley at Linux user groups that I have spoken at > in the past couple months (BayLISA, SVLUG, EBLUG). > > I know that most of those folks haven't tried a recent version, which does > actually work pretty good, but those folks still have bitterness towards > the early verisons they tried and/or heard about. But the bitterness is > eroding slowly. At least that is what it seems like to me. > > > We have seen growing adoption and use as a result of those advances, and > > most Fedora users seem to be leaving SELinux enabled these days. The > > main issue there is whether you can easily leverage those advances or > > have to re-invent them independently. > > In most cases the question of wether to enable it or not is being able to > use your system without a massive amount of configuration. I believe this > is the biggest barrier for both TX and SELinux. > > This must change, because trusted systems will be mandatory in the future > for a lot of folks, IMO. Just to clarify, in typical cases with SELinux today, you can just generate a loadable policy module using audit2allow and/or run a few semanage or system-config-selinux commands and resolve most issues. No "massive amount of configuration" by the users is typically required. Of course we'll need to construct similar tools for FMAC. The amount of configuration required will of course vary depending on the extent to which the user is deviating from a stock system and/or application configuration in the first place; the more the user diverges, the greater the delta between the shipped policy and the way the user's system operates and the more policy customization is required. Life is simpler when you have a stock configuration as in an enterprise environment vs. heavy customization by each individual user (where the latter is more likely something you'd encounter at a LUG I would expect). As you get better integration with the existing system and application configuration tools, you'll encounter fewer issues there - the same tool used to adjust the system or application configuration can adjust policy to fit as well. Also, with regard to your last statement, Flask (whether in SELinux or FMAC) was designed to allow it to be deployed and used in general purpose OSes by generalizing MAC and making it flexible and configurable and by supporting security goals of general interest, which enabled it to break free of the "trusted systems" niche. That is why SELinux is a default enabled security feature. -- Stephen Smalley National Security Agency From sds at tycho.nsa.gov Mon Jun 30 07:45:18 2008 From: sds at tycho.nsa.gov (Stephen Smalley) Date: Mon, 30 Jun 2008 10:45:18 -0400 Subject: [fmac-discuss] Zone-specific policies In-Reply-To: <48687DDC.1050203@sun.com> 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> Message-ID: <1214837118.22447.98.camel@moss-spartans.epoch.ncsc.mil> On Sun, 2008-06-29 at 23:31 -0700, John Weeks wrote: > Darren J Moffat wrote: > > Stephen Smalley wrote: > >> On Tue, 2008-06-24 at 14:26 +0100, Darren J Moffat wrote: > >>> Stephen Smalley wrote: > >>>> Filesystems should be labeled when they are first populated (e.g. zone > >>>> creation). At boot, if we have reason to believe that an inconsistency > >>>> has arisen (e.g. prior boot with FMAC disabled), we can initiate an > >>>> automatic relabel, but that is a time consuming process and not > >>>> something we want to do on every boot (plus it defeats the purpose of > >>>> having persistent labels in the first place, as the initial file > >>>> contexts configuration is only to specify the initial state and then we > >>>> want any runtime-created files to be labeled in accordance with their > >>>> runtime security properties). > >>> When you mention persistent labels do you mean explicit per file labels > >>> stored in side the filesystem, say as extended attributes ? > >> Correct. That is what is done in SELinux, and is important for > >> supporting fine-grained protection (as was true even of Trusted Solaris > >> prior to TX). > > > > I'm assuming that the extended attributes we have in ZFS today are not > > sufficient because these would need to be in a namespace where > > modification is controlled either by a privilege or by an FMAC policy. > > > > We should be able to intercept extended attribute calls to prevent unauthorized modification of FMAC specific attributes. NFS might be a little tricker, but I would rather use an existing mechanism if we can. > > In the original prototype, I did use extended attributes to hold the file object context. It's wasn't a complete implementation (files contexts were created with a utility), but I was retrieving the file context when a vnode was opened. 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. -- Stephen Smalley National Security Agency