diff mbox series

scripts/selinux: add basic mls support to mdp

Message ID 20190214191417.1469-1-sds@tycho.nsa.gov (mailing list archive)
State Superseded
Headers show
Series scripts/selinux: add basic mls support to mdp | expand

Commit Message

Stephen Smalley Feb. 14, 2019, 7:14 p.m. UTC
Add basic MLS support to mdp.  Usage:
scripts/selinux/mdp/mdp -m policy.conf file_contexts
checkpolicy -M -o policy policy.conf

Then install the resulting policy and file_contexts as usual.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
---
 scripts/selinux/mdp/mdp.c | 131 ++++++++++++++++++++++++++++++--------
 1 file changed, 103 insertions(+), 28 deletions(-)

Comments

Stephen Smalley Feb. 14, 2019, 7:35 p.m. UTC | #1
On 2/14/19 2:14 PM, Stephen Smalley wrote:
> Add basic MLS support to mdp.  Usage:
> scripts/selinux/mdp/mdp -m policy.conf file_contexts
> checkpolicy -M -o policy policy.conf
> 
> Then install the resulting policy and file_contexts as usual.
> 
> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
> ---
>   scripts/selinux/mdp/mdp.c | 131 ++++++++++++++++++++++++++++++--------
>   1 file changed, 103 insertions(+), 28 deletions(-)
> 
> diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
> index 073fe7537f6c..4672ee5cc1bd 100644
> --- a/scripts/selinux/mdp/mdp.c
> +++ b/scripts/selinux/mdp/mdp.c
> @@ -97,8 +97,19 @@ int main(int argc, char *argv[])
>   
>   	/* NOW PRINT OUT MLS STUFF */
>   	if (mls) {
> -		printf("MLS not yet implemented\n");
> -		exit(1);
> +		fprintf(fout, "sensitivity s0;\n");

Do we want more than one sensitivity for this example?

> +		fprintf(fout, "dominance { s0 }\n"); > +		fprintf(fout, "category c0;\n");
> +		fprintf(fout, "category c1;\n");
> +		fprintf(fout, "level s0:c0.c1;\n\n");
> +		for (i = 0; secclass_map[i].name; i++) {
> +			struct security_class_mapping *map = &secclass_map[i];
> +
> +			fprintf(fout, "mlsconstrain %s {\n", map->name);
> +			for (j = 0; map->perms[j]; j++)
> +				fprintf(fout, "\t%s\n", map->perms[j]);
> +			fprintf(fout, "} (l1 eq l2 and h1 eq h2);\n\n");

This constraint prohibits all permissions between s0:c0.c1 and s0:c0 
(and vice versa) or between s0:c0 and s0 (or vice versa), for example. 
It requires both low and high levels to be identical for any access to 
be granted.  Not very useful.

Alternatively, we could require dominance (dom), in which case s0:c0.c1 
would have all permissions to s0:c0, s0:c1, or just s0, while s0:c0 
would no permissions to s0:c0.c1 or to s0:c1.  A little more interesting 
but still probably not usable for anything.

Or we could split up the constraints into separate constraints on the 
"read" operations versus the "write" operations like MCS or MLS.  But 
that requires manually writing the constraints; we can't auto-generate 
them for all classes/permissions that way without a separate 
specification of which ones are reads and which ones are writes.  And we 
would also likely need/want separate constraints on "create", 
"transition", etc in order to ensure properly handling of the low/high 
relationships.

Also, since there is only one domain/type defined by mdp, we can't have 
some domains/types exempted and others not, so it is all or nothing.

Kind of hard to create a useful mls policy example without a richer TE 
policy for mdp.

> +		}
>   	}
>   
>   	/* types, roles, and allows */
> @@ -108,34 +119,92 @@ int main(int argc, char *argv[])
>   	for (i = 0; secclass_map[i].name; i++)
>   		fprintf(fout, "allow base_t base_t:%s *;\n",
>   			secclass_map[i].name);
> -	fprintf(fout, "user user_u roles { base_r };\n");
> -	fprintf(fout, "\n");
> +	fprintf(fout, "user user_u roles { base_r }");
> +	if (mls)
> +		fprintf(fout, " level s0 range s0 - s0:c0.c1");
> +	fprintf(fout, ";\n");
>   
>   	/* default sids */
> -	for (i = 1; i < initial_sid_to_string_len; i++)
> -		fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
> +	for (i = 1; i < initial_sid_to_string_len; i++) {
> +		fprintf(fout, "sid %s user_u:base_r:base_t",
> +			initial_sid_to_string[i]);
> +		if (mls)
> +			fprintf(fout, ":s0");
> +		fprintf(fout, "\n");
> +	}
>   	fprintf(fout, "\n");
>   
> -	fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
> -
> -	fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
> -
> -	fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
> -	fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
> -
> -	fprintf(fout, "genfscon proc / user_u:base_r:base_t\n");
> +	fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +
> +	fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +
> +	fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +	fprintf(fout, "fs_use_trans shm user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, ";\n");
> +
> +	fprintf(fout, "genfscon proc / user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, "\n");
>   
>   	fclose(fout);
>   
> @@ -144,8 +213,14 @@ int main(int argc, char *argv[])
>   		printf("Wrote policy, but cannot open %s for writing\n", ctxout);
>   		usage(argv[0]);
>   	}
> -	fprintf(fout, "/ user_u:base_r:base_t\n");
> -	fprintf(fout, "/.* user_u:base_r:base_t\n");
> +	fprintf(fout, "/ user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, "\n");
> +	fprintf(fout, "/.* user_u:base_r:base_t");
> +	if (mls)
> +		fprintf(fout, ":s0");
> +	fprintf(fout, "\n");
>   	fclose(fout);
>   
>   	return 0;
>
Stephen Smalley Feb. 14, 2019, 8:22 p.m. UTC | #2
On 2/14/19 2:35 PM, Stephen Smalley wrote:
> On 2/14/19 2:14 PM, Stephen Smalley wrote:
>> Add basic MLS support to mdp.  Usage:
>> scripts/selinux/mdp/mdp -m policy.conf file_contexts
>> checkpolicy -M -o policy policy.conf
>>
>> Then install the resulting policy and file_contexts as usual.
>>
>> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
>> ---
>>   scripts/selinux/mdp/mdp.c | 131 ++++++++++++++++++++++++++++++--------
>>   1 file changed, 103 insertions(+), 28 deletions(-)
>>
>> diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
>> index 073fe7537f6c..4672ee5cc1bd 100644
>> --- a/scripts/selinux/mdp/mdp.c
>> +++ b/scripts/selinux/mdp/mdp.c
>> @@ -97,8 +97,19 @@ int main(int argc, char *argv[])
>>       /* NOW PRINT OUT MLS STUFF */
>>       if (mls) {
>> -        printf("MLS not yet implemented\n");
>> -        exit(1);
>> +        fprintf(fout, "sensitivity s0;\n");
> 
> Do we want more than one sensitivity for this example?
> 
>> +        fprintf(fout, "dominance { s0 }\n"); > +        fprintf(fout, 
>> "category c0;\n");
>> +        fprintf(fout, "category c1;\n");
>> +        fprintf(fout, "level s0:c0.c1;\n\n");
>> +        for (i = 0; secclass_map[i].name; i++) {
>> +            struct security_class_mapping *map = &secclass_map[i];
>> +
>> +            fprintf(fout, "mlsconstrain %s {\n", map->name);
>> +            for (j = 0; map->perms[j]; j++)
>> +                fprintf(fout, "\t%s\n", map->perms[j]);
>> +            fprintf(fout, "} (l1 eq l2 and h1 eq h2);\n\n");
> 
> This constraint prohibits all permissions between s0:c0.c1 and s0:c0 
> (and vice versa) or between s0:c0 and s0 (or vice versa), for example. 
> It requires both low and high levels to be identical for any access to 
> be granted.  Not very useful.
> 
> Alternatively, we could require dominance (dom), in which case s0:c0.c1 
> would have all permissions to s0:c0, s0:c1, or just s0, while s0:c0 
> would no permissions to s0:c0.c1 or to s0:c1.  A little more interesting 
> but still probably not usable for anything.

OTOH, the MCS constraints are almost entirely written using dominance 
only, with a few exceptions.  If we included the highest sensitivity and 
all categories in the kernel initial SID context, then init would 
inherit that context (no domain transitions defined by mdp) and one 
could manually start a process with fewer or no categories via runcon or 
similar to exercise the constraints.  Still not very usable but might 
suffice for demonstration purposes.

> 
> Or we could split up the constraints into separate constraints on the 
> "read" operations versus the "write" operations like MCS or MLS.  But 
> that requires manually writing the constraints; we can't auto-generate 
> them for all classes/permissions that way without a separate 
> specification of which ones are reads and which ones are writes.  And we 
> would also likely need/want separate constraints on "create", 
> "transition", etc in order to ensure properly handling of the low/high 
> relationships.
> 
> Also, since there is only one domain/type defined by mdp, we can't have 
> some domains/types exempted and others not, so it is all or nothing.
> 
> Kind of hard to create a useful mls policy example without a richer TE 
> policy for mdp.
> 
>> +        }
>>       }
>>       /* types, roles, and allows */
>> @@ -108,34 +119,92 @@ int main(int argc, char *argv[])
>>       for (i = 0; secclass_map[i].name; i++)
>>           fprintf(fout, "allow base_t base_t:%s *;\n",
>>               secclass_map[i].name);
>> -    fprintf(fout, "user user_u roles { base_r };\n");
>> -    fprintf(fout, "\n");
>> +    fprintf(fout, "user user_u roles { base_r }");
>> +    if (mls)
>> +        fprintf(fout, " level s0 range s0 - s0:c0.c1");
>> +    fprintf(fout, ";\n");
>>       /* default sids */
>> -    for (i = 1; i < initial_sid_to_string_len; i++)
>> -        fprintf(fout, "sid %s user_u:base_r:base_t\n", 
>> initial_sid_to_string[i]);
>> +    for (i = 1; i < initial_sid_to_string_len; i++) {
>> +        fprintf(fout, "sid %s user_u:base_r:base_t",
>> +            initial_sid_to_string[i]);
>> +        if (mls)
>> +            fprintf(fout, ":s0");
>> +        fprintf(fout, "\n");
>> +    }
>>       fprintf(fout, "\n");
>> -    fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
>> -
>> -    fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
>> -
>> -    fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
>> -    fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
>> -
>> -    fprintf(fout, "genfscon proc / user_u:base_r:base_t\n");
>> +    fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +
>> +    fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +
>> +    fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +    fprintf(fout, "fs_use_trans shm user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, ";\n");
>> +
>> +    fprintf(fout, "genfscon proc / user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, "\n");
>>       fclose(fout);
>> @@ -144,8 +213,14 @@ int main(int argc, char *argv[])
>>           printf("Wrote policy, but cannot open %s for writing\n", 
>> ctxout);
>>           usage(argv[0]);
>>       }
>> -    fprintf(fout, "/ user_u:base_r:base_t\n");
>> -    fprintf(fout, "/.* user_u:base_r:base_t\n");
>> +    fprintf(fout, "/ user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, "\n");
>> +    fprintf(fout, "/.* user_u:base_r:base_t");
>> +    if (mls)
>> +        fprintf(fout, ":s0");
>> +    fprintf(fout, "\n");
>>       fclose(fout);
>>       return 0;
>>
>
diff mbox series

Patch

diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c
index 073fe7537f6c..4672ee5cc1bd 100644
--- a/scripts/selinux/mdp/mdp.c
+++ b/scripts/selinux/mdp/mdp.c
@@ -97,8 +97,19 @@  int main(int argc, char *argv[])
 
 	/* NOW PRINT OUT MLS STUFF */
 	if (mls) {
-		printf("MLS not yet implemented\n");
-		exit(1);
+		fprintf(fout, "sensitivity s0;\n");
+		fprintf(fout, "dominance { s0 }\n");
+		fprintf(fout, "category c0;\n");
+		fprintf(fout, "category c1;\n");
+		fprintf(fout, "level s0:c0.c1;\n\n");
+		for (i = 0; secclass_map[i].name; i++) {
+			struct security_class_mapping *map = &secclass_map[i];
+
+			fprintf(fout, "mlsconstrain %s {\n", map->name);
+			for (j = 0; map->perms[j]; j++)
+				fprintf(fout, "\t%s\n", map->perms[j]);
+			fprintf(fout, "} (l1 eq l2 and h1 eq h2);\n\n");
+		}
 	}
 
 	/* types, roles, and allows */
@@ -108,34 +119,92 @@  int main(int argc, char *argv[])
 	for (i = 0; secclass_map[i].name; i++)
 		fprintf(fout, "allow base_t base_t:%s *;\n",
 			secclass_map[i].name);
-	fprintf(fout, "user user_u roles { base_r };\n");
-	fprintf(fout, "\n");
+	fprintf(fout, "user user_u roles { base_r }");
+	if (mls)
+		fprintf(fout, " level s0 range s0 - s0:c0.c1");
+	fprintf(fout, ";\n");
 
 	/* default sids */
-	for (i = 1; i < initial_sid_to_string_len; i++)
-		fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
+	for (i = 1; i < initial_sid_to_string_len; i++) {
+		fprintf(fout, "sid %s user_u:base_r:base_t",
+			initial_sid_to_string[i]);
+		if (mls)
+			fprintf(fout, ":s0");
+		fprintf(fout, "\n");
+	}
 	fprintf(fout, "\n");
 
-	fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
-
-	fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
-
-	fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
-	fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
-
-	fprintf(fout, "genfscon proc / user_u:base_r:base_t\n");
+	fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+
+	fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+
+	fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+	fprintf(fout, "fs_use_trans shm user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, ";\n");
+
+	fprintf(fout, "genfscon proc / user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, "\n");
 
 	fclose(fout);
 
@@ -144,8 +213,14 @@  int main(int argc, char *argv[])
 		printf("Wrote policy, but cannot open %s for writing\n", ctxout);
 		usage(argv[0]);
 	}
-	fprintf(fout, "/ user_u:base_r:base_t\n");
-	fprintf(fout, "/.* user_u:base_r:base_t\n");
+	fprintf(fout, "/ user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, "\n");
+	fprintf(fout, "/.* user_u:base_r:base_t");
+	if (mls)
+		fprintf(fout, ":s0");
+	fprintf(fout, "\n");
 	fclose(fout);
 
 	return 0;