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, я перенесу остальные сетевые разрешения.
Я экспериментировал с использованием как макроса option_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 допустимы операторы if в модулях политики, поэтому я действительно в недоумении.
if (`mymodule_use_network'){
optional {
require {
type fonts_t;
}
allow mymodule_t fonts_t:dir getattr;
}
}
Синтаксическая ошибка может быть? Ваши вещи не похожи на то, что задокументировано
Что вам говорит компилятор?
Однако обратите внимание, что не все операторы разрешены в условных выражениях. Например, вам не разрешено объявлять/связывать атрибуты типа в условных выражениях. Убедитесь, что любые интерфейсы, которые вы вызываете в условных выражениях, не объявляют/ассоциируют атрибуты типа (или любые другие вещи, которые не разрешены).
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). Это не то, что политика собственного модуля использует.
Я получаю синтаксическую ошибку в строке, где используется необязательный параметр. Вы можете увидеть все ошибки в моем исходном посте. Я вижу, что в моем примере оператора if я использовал `' вокруг переменной. Я пробовал и без них, но их использование или нет не влияет на вывод ошибок. Кроме того, что вы имеете в виду, говоря, что sysnet_dns_name_resolve()
не является необязательным? Под необязательным я подразумеваю, что если вы посмотрите на определение интерфейса, оно содержит операторы optional_policy
, которые расширяются до необязательных и вызывают мою синтаксическую ошибку.
Я вижу, что в вашей ссылке (и в том, что вы скопировали) этот необязательный элемент не указан как действительный внутри оператора if. Если вы посмотрите на ссылку на необязательный оператор, который я поместил в операцию, он говорит, что он действителен. Так что я думаю, что это просто проблема с документацией.
sysnet_dns_name_resolve() является частью модуля sysnetwork. Если вы отключите этот модуль sysnetwork или удалите его, многие вещи перестанут работать. Таким образом, это означает, что практически интерфейс всегда присутствует, и поэтому нет смысла делать вызовы sysnet_dns_name_resolve() условными, потому что он всегда будет там.
модуль sysnetwork на самом деле может быть частью «базы». см. семодуль -lfull | системная сеть grep. Если вы попытаетесь отключить базовый модуль, то, очевидно, все рухнет. Но даже если модуль sysnetwork не является частью базы, я уверен, что любые попытки отключить или удалить этот модуль приведут к проблемам с зависимостями.
Для моего использования я не пытаюсь отключить модуль sysnetwork, а просто условно использую его интерфейс для своего собственного модуля.
На самом деле, только сейчас здесь начинает доходить до того, что согласно документации «необязательный» оператор не допускается в условных выражениях.
Обходной путь состоит в том, чтобы вместо этого обернуть конструкцию «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))))))
Где написано, что опционально нельзя? В своем обновлении я добавил ссылку, где явно указано, что необязательные операторы допустимы в операторах if. Конечно, я мог неправильно читать документацию. У вас есть ссылка, где написано, что это запрещено?
Также я стараюсь максимально использовать refpolicy. У меня есть обходной путь, который работает на данный момент, но это означает, что мне пришлось копировать/вставлять из интерфейса, который я пытался использовать, что противоречит его цели.
Да, это может быть ошибка в документе. Это как минимум нелогично.
но да, я сам избегаю логических значений, таких как грипп. Они очень ограничены (много вещей не разрешено внутри логического блока)
Если у вас есть вопросы, прежде чем вы сможете дать окончательный ответ, вы должны задать эти вопросы в комментариях и сначала получить ответы.