Мои пользовательские политики 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;
что делает мое приложение доверенным. Это решает проблему, но предоставляет большой доступ к моему приложению. Таким образом, лучшим вариантом было бы понизить уровень безопасности места назначения до уровня, который предоставляет доступ на чтение и запись к моему приложению.
Так что это в основном решение этой проблемы до сих пор (пока еще не завершено).