skip to Main Content

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;
    }
}

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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","if" or "booleanif" construct with an "optional" instead.

    native module policy, something like:

    module myfoo 1.0;
    bool foo true;
    type bar;
    require { class process signal; }
    if (foo) {
    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;
    }
    }
    

    or refpolicy, something along the lines of:

    policy_module(myfoo, 1.0)
    gen_tunable(foo, true)
    type bar;
    tunable_policy(`foo',`
    allow bar self:process signal;
    ',`
    dontaudit bar self:process signal;
    ')
    optional_policy(`
    tunable_policy(`foo',`
    gen_require(` type baz; ')
    allow bar baz:file read;
    ')
    ')
    

    or native common intermediate language:

    (boolean foo true)
    (type bar)
    (booleanif foo
    (true
    (allow bar self (process (signal))))
    (false
    (dontaudit bar self (process (signal)))))
    (optional foo_optional
    (booleanif foo
    (true
    (allow bar baz (file (read))))))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search