在 tunable_policy 宏中使用可选时出现 SELinux 语法错误

SELinux syntax error when optional is used inside a tunable_policy macro

TLDR:我尝试使用的界面包含一些“optional_policy”宏。在 tunable_policy 宏中使用它(或任何形式的“可选”)会导致语法错误。完成此任务的正确方法是什么?请参阅下面的更新。

长版:我是 SELinux 的新手,目前正在开发一个模块来限制 Debian 上的用户应用程序。我想做的一件事是添加一个布尔值来切换网络访问。我使用类似于以下内容的内容创建了一个基本策略模块:

sepolicy generate --application -n mymodule /usr/share/foo/foo

我向生成的模块添加了一个新的可调参数。

gen_tunable(mymodule_use_network,false)

tunable_policy(`mymodule_use_network',`
   sysnet_dns_name_resolve(mymodule_t)
')

上面显示的接口调用是由 sepolicy 生成的,我只是将其移动到 tunable_policy 宏中。一旦我让 DNS 正常工作,我将移动其余的网络权限。

我尝试过直接使用 optional_policy 宏和简单的可选语句。当使用生成的脚本来构建和加载我的模块时,我在所有情况下都会得到以下输出:

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

我注意到定义这些宏的文件有一个关于注释行和 m4 的辅助函数,但我不知道它在做什么。我的问题是这样的吗?作为一种解决方法,我可以将界面的内容复制到我的宏中,但这违背了目的。我在这里错过了什么?这真的是预期的情况,并且参考策略中没有其他可调参数包含嵌套的可选语句吗?

更新:我将其归结为以下 if/optional 语句组合。根据 SELinux Notebook 可选语句在策略模块中的 if 语句中有效,所以我真的很茫然。

if(`mymodule_use_network'){
    optional {
        require {
            type fonts_t;
        }

        allow mymodule_t fonts_t:dir getattr;
    }
}

可能是语法错误?你的东西看起来不像 documented

编译器告诉你什么?

请注意,并非所有语句都允许出现在条件语句中。例如,不允许 declare/associate 在条件中键入属性。确保您在条件中调用的任何接口不 declare/associate 类型属性(或任何其他不允许的东西)

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.

顺便说一下:sysnet_dns_name_resolve() 实际上不是可选的。

这有点令人困惑,因为您本质上是在使用两种策略语言(引用策略抽象和本机模块策略)''特定于引用策略(refpolicies 对 M4 的精确使用)那不是本机模块策略使用的东西。

实际上,根据文档,条件语句中不允许使用“可选”语句,现在才开始明白这一点。

解决方法是用“可选”代替“tunable_policy”、“if”或“booleanif”结构。

本机模块策略,例如:

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

或 refpolicy,类似于:

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;
')
')

或母语通用中间语言:

(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))))))