Мои пользовательские политики selinux, похоже, игнорируются системой Android

У меня возникли проблемы с правильной работой пользовательских политик selinux на Android 7.1.2 на основе AOSP (точнее, на основе дерева открытых устройств Sony).

Моя проблема в том, что журналы аудита постоянно говорят мне об отсутствующих правилах доступа к файлам, которые я на самом деле добавил. Я также скопировал правила, созданные aud2allow, в мои файлы политики, но даже они не работают должным образом.

Итак, давайте углубимся в детали:

Я создал собственный домен с именем vendor_app. Этот домен назначается приложению на основе его подписи. Я добавил запись в mac_permissions.xml, чтобы назначить поставщика поля seinfo. В seapp_contexts я назначаю домен vendor_app следующим образом:

user=_app seinfo=vendor domain=vendor_app type=app_data_file levelFrom=user

Мое приложение правильно запущено в контексте vendor_app:

# ps -Z | grep permissiontest
u:r:vendor_app:s0:c512,c768    u0_a109   4110  508   1620732 79584 SyS_epoll_ 0000000000 S com.vendor.android.permissiontest

Итак, теперь для части, которая не работает вообще. Приложение, работающее в контексте vendor_app, должно получить доступ на чтение / запись к файлам в / persist / vendor. Чтобы создать необходимые правила, я добавил файл с именем vendor.te в папку sepolicy в каталоге устройства со следующим содержимым:

type vendor_app, domain;
type vendor_file, file_type, data_file_type;
# permissive vendor_app;

app_domain(vendor_app)
net_domain(vendor_app)
bluetooth_domain(vendor_app)

allow vendor_app persist_file:dir r_dir_perms;
allow vendor_app vendor_file:dir create_dir_perms;
allow vendor_app vendor_file:file create_file_perms;

allow vendor_app audioserver_service:service_manager find;
allow vendor_app cameraserver_service:service_manager find;
allow vendor_app drmserver_service:service_manager find;
allow vendor_app mediaserver_service:service_manager find;
allow vendor_app mediaextractor_service:service_manager find;
allow vendor_app mediacodec_service:service_manager find;
allow vendor_app mediadrmserver_service:service_manager find;
allow vendor_app persistent_data_block_service:service_manager find;
allow vendor_app radio_service:service_manager find;
allow vendor_app surfaceflinger_service:service_manager find;
allow vendor_app app_api_service:service_manager find;
allow vendor_app system_api_service:service_manager find;
allow vendor_app vr_manager_service:service_manager find;

И я добавил одну запись в конфигурации file_contexts:

###################################
# persist files
#
/persist(/.*)?                                                      u:object_r:persist_file:s0
/persist/vendor(/.*)?                                               u:object_r:vendor_file:s0

В разделе / ​​persist я создал некую структуру каталогов, в которой есть папки с соответствующими разрешениями для добавления туда некоторых файлов.

# ls -Zal /persist/vendor/                                            
total 56
drwxrwxrwx  5 persist   persist   u:object_r:vendor_file:s0  4096 2017-08-03 22:27 .
drwxrwx--x 16 system    system    u:object_r:persist_file:s0 4096 2017-08-01 16:24 ..
drwxrwxrwx  2 profile   profile   u:object_r:vendor_file:s0  4096 2017-08-04 13:34 profile
drwxrwxrwx  2 provision provision u:object_r:vendor_file:s0  4096 2017-08-04 13:34 provisioning
drwxrwxrwx  2 updater   updater   u:object_r:vendor_file:s0  4096 2017-08-04 13:34 updater

Я знаю, что правила поиска для сервисов работают, так как я могу запустить свое приложение в принудительном режиме и не получаю никаких жалоб по этому поводу. Я также могу получить доступ к каталогу / persist для {search}, как это разрешено правилом относительно persist_file: dir.

Как только я пытаюсь записать новый файл, например / persist / vendor / updater / test, в каталог / persist, я получаю сообщения об ошибках от auditd:

08-04 16:34:29.269  4108  4108 W .permissiontest: type=1400 audit(0.0:27): avc: denied { write } for name="updater" dev="mmcblk0p44" ino=55 scontext=u:r:vendor_app:s0:c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=dir permissive=0

Эта ошибка, конечно, преобразуется Audit2allow в следующее правило:

#============= vendor_app ==============
allow vendor_app vendor_file:dir write;

Поскольку write является членом create_dir_perms, он на самом деле должен быть там. Я также попытался добавить строку, созданную audit2allow, в мой vendor.te, но безуспешно.

Обратите внимание, что запись в программу обновления также включает поиск по persist_file и поиск по vendor_file, которые, похоже, работают без проблем.

Кто-нибудь есть совет, как правильно отладить или, может быть, даже какое-либо решение этой проблемы? Я копался в этом в течение двух дней, и это сводит меня с ума.

РЕДАКТИРОВАТЬ:

Ах. / persist, конечно, смонтирован для записи:

# mount | grep persist
/dev/block/bootdevice/by-name/persist on /persist type ext4 (rw,seclabel,nosuid,nodev,relatime,nodelalloc,errors=panic,data=ordered)

РЕДАКТИРОВАТЬ 2:

Как спросил Пол Ратацци, я просканировал файл sepolicy и версию, фактически загруженную в ядро, на наличие моих правил.

$ sesearch -A -s vendor_app -t vendor_file policy 
allow vendor_app vendor_file:dir { rename search setattr read lock create reparent getattr write ioctl rmdir remove_name open add_name };
allow vendor_app vendor_file:file { rename setattr read lock create getattr write ioctl unlink open append };

Таким образом, они правильно развернуты на устройстве.

1 ответ

Решение

Ну, после еще нескольких копаний, похоже, я наконец нашел ответ. Чтобы, возможно, спасти кого-то, кто сталкивается с той же проблемой, в несколько дней, мучительных для мозга, вот решение:

Помимо MAC (Mandatory Access Control) SElinux на android также MLS (многоуровневая безопасность).

Хотя MAC как-то описан в концепциях Android SELinux, информация о MLS упоминается очень кратко и неявно:

В SELinux метка имеет вид: user: role: type:mls_level, где тип является основным компонентом решений о доступе, который может быть изменен другими компонентами разделов, которые составляют метку.

Итак, что происходит, так это то, что мое Android-приложение работает на уровне MLS (обозначен c512,c768), который может читать файлы в /persist, но не записывать их. Итак, что должно произойти, это то, что мое приложение получает уровень MLS для правильного доступа к этим файлам.

Я (на данный момент) заархивировал это, изменив мой пользовательский ярлык на

type vendor_app, domain, mlstrustedsubject;

что делает мое приложение доверенным. Это решает проблему, но предоставляет большой доступ к моему приложению. Таким образом, лучшим вариантом было бы понизить уровень безопасности места назначения до уровня, который предоставляет доступ на чтение и запись к моему приложению.

Так что это в основном решение этой проблемы до сих пор (пока еще не завершено).

Другие вопросы по тегам