TLDR: An interface I'm trying to use contains a few "optional_policy" macros. Using it (or any form of "optional") inside a tunable_policy macro results in a syntax error. What is the correct way to accomplish this? See update below.
Long Version: I'm new to SELinux and currently working on a module to constrain a user application on Debian. One of the things I'd like to do is add a boolean to toggle network access. I created a basic policy module using the something similar to the following:
sepolicy generate --application -n mymodule /usr/share/foo/foo
I added a new tunable to the generated module.
gen_tunable(mymodule_use_network,false)
tunable_policy(`mymodule_use_network',`
sysnet_dns_name_resolve(mymodule_t)
')
The interface call shown above was generated by sepolicy and I just moved it into the tunable_policy macro. Once I get the DNS working I'll move the rest of the network permissions in.
I have experimented using both the optional_policy macro and the plain optional statement directly. When using the generated script to build and load my module I get the following output in all cases:
Building and Loading Policy
make -f /usr/share/selinux/devel/Makefile mymodule.pp
Compiling default mymodule module
mymodule.te:65:ERROR 'syntax error' at token 'optional' on line 4858:
optional {
#line 65
/usr/bin/checkmodule: error(s) encountered while parsing configuration
make: *** [/usr/share/selinux/devel/include/Makefile:166: tmp/mymodule.mod] Error 1
exit
I have noticed that the file that defines these macros has a helper function regarding commented lines and m4, but I have no idea what it's doing. Is something like that my issue here? As a workaround I can copy the contents of the interface into my macro but that defeats the purpose. What am I missing here? Is it really the case that this is expected and no other tunable in the reference policy contains a nested optional statement?
Update:I've boiled it down to the following if/optional statement combination. According to the SELinux Notebook optional statements are valid within if statements in policy modules so I'm really at a loss.
if(`mymodule_use_network'){
optional {
require {
type fonts_t;
}
allow mymodule_t fonts_t:dir getattr;
}
}
CodePudding user response:
Syntax error maybe? Your stuff does not look like what is documented
What is the compiler telling you?
Do note though that not all statements are allowed in conditionals. You are for example not allowed to declare/associate type attributes in conditionals. Ensure that any interfaces you call in conditionals do not declare/associate type attributes (or any other things that aren't allowed)
The only statements and rules allowed within the if / else construct are:
allow, auditallow, auditdeny, dontaudit, type_member, type_transition (except file_name_transition), type_change and require.
By the way: sysnet_dns_name_resolve()
is not realistically optional.
It is kind of confusing because you are essentially using two policy languages (the reference policy abstraction and the native module policy) The `' is specific to reference policy (refpolicies' use of M4 to be precise) That is not something that native module policy uses.
CodePudding user response:
Actually, it only now starts to sink in here that according to documentation "optional" statement is not allowed in conditionals.
A workaround is to wrap the "tunable_policy" and/or "if" construct in an optional instead.
Something like:
bool foo true;
type bar;
if (foo) {
require { class process signal; }
allow bar self:process signal;
} else {
dontaudit bar self:process signal;
}
optional {
if (foo) {
require { type baz; class file read; }
allow bar baz:file read;
}
}