SELinux настроен на запрет по умолчанию, что означает, что любой доступ, для которого есть хук в ядре, должен быть явно разрешён политикой. Это означает, что файл политики содержит большой объём информации о правилах, типах, классах, разрешениях и т.д. Полное рассмотрение SELinux выходит за рамки данного документа, но понимание того, как писать правила политики, теперь крайне важно при запуске новых устройств Android. Уже доступно много информации о SELinux. См. вспомогательную документацию для получения рекомендуемых ресурсов.
Ключевые файлы
Чтобы включить SELinux, интегрируйте последнюю версию ядра Android , а затем добавьте файлы из каталога system/sepolicy . После компиляции эти файлы образуют политику безопасности ядра SELinux и охватывают основную операционную систему Android.
Как правило, не следует изменять файлы system/sepolicy напрямую. Вместо этого добавьте или отредактируйте собственные файлы политики для конкретного устройства в каталоге /device/ manufacturer / device-name /sepolicy . В Android 8.0 и более поздних версиях изменения, вносимые в эти файлы, должны влиять только на политику в каталоге поставщика. Подробнее о разделении публичной политики sepolicy в Android 8.0 и более поздних версиях см. в разделе «Настройка SEPolicy в Android 8.0+» . Независимо от версии Android, вам всё равно придётся изменять эти файлы:
Файлы политики
Файлы с расширением *.te — это исходные файлы политики SELinux, которые определяют домены и их метки. Возможно, вам потребуется создать новые файлы политики в каталоге /device/ manufacturer / device-name /sepolicy , но по возможности постарайтесь обновить существующие файлы.
Контекстные файлы
Контекстные файлы — это место, где вы указываете метки для своих объектов.
-
file_contextsназначает метки файлам и используется различными компонентами пользовательского пространства. При создании новых политик создайте или обновите этот файл, чтобы назначить новые метки файлам. Чтобы применить новыйfile_contexts, пересоберите образ файловой системы или запуститеrestoreconдля файла, который необходимо перемаркировать. При обновлении измененияfile_contextsавтоматически применяются к системным разделам и разделам пользовательских данных. Изменения также можно автоматически применять к другим разделам при обновлении, добавив вызовыrestorecon_recursiveв файл board после монтирования раздела в режиме чтения и записи. -
genfs_contextsназначает метки файловым системам, таким какprocилиvfat, которые не поддерживают расширенные атрибуты. Эта конфигурация загружается как часть политики ядра, но изменения могут не вступить в силу для in-core inodes, что потребует перезагрузки или размонтирования и повторного монтирования файловой системы для полного применения изменений. Конкретные метки также можно назначать конкретным точкам монтирования, напримерvfatс помощью параметраcontext=mount. -
property_contextsприсваивает метки системным свойствам Android, чтобы контролировать, какие процессы могут их устанавливать. Эта конфигурация считывается процессомinitво время запуска. -
service_contextsназначает метки службам-биндерам Android, чтобы контролировать, какие процессы могут добавлять (регистрировать) и находить (искать) ссылки на связыватели для данной службы. Эта конфигурация считывается процессомservicemanagerво время запуска. -
seapp_contextsназначает метки процессам приложения и каталогам/data/data. Эта конфигурация считывается процессомzygoteпри каждом запуске приложения иinstalldво время его запуска. - Файл
mac_permissions.xmlназначает приложениям тегseinfoна основе их подписи и, при необходимости, имени пакета. Тегseinfoзатем можно использовать в качестве ключа в файлеseapp_contextsдля назначения определённой метки всем приложениям с этим тегомseinfo. Эта конфигурация считываетсяsystem_serverво время запуска. -
keystore2_key_contextsназначает метки пространствам имён Keystore 2. Эти пространства имён поддерживаются демономkeystore2. Keystore всегда предоставлял пространства имён на основе UID/AID. Keystore 2 также поддерживает пространства имён, определённые в sepolicy. Подробное описание формата и соглашений этого файла можно найти здесь .
BoardConfig.mk makefile
После редактирования или добавления файлов политики и контекста обновите make-файл /device/ manufacturer / device-name /BoardConfig.mk указав подкаталог sepolicy и каждый новый файл политики. Подробнее о переменных BOARD_SEPOLICY см. в файле system/sepolicy/README .
BOARD_SEPOLICY_DIRS += \
<root>/device/manufacturer/device-name/sepolicy
BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te
После пересборки на вашем устройстве будет активирован SELinux. Теперь вы можете либо настроить политики SELinux для поддержки собственных дополнений к операционной системе Android, как описано в разделе «Настройка» , либо проверить существующую настройку, как описано в разделе «Проверка» .
После установки новых файлов политики и обновлений BoardConfig.mk новые параметры политики автоматически встраиваются в финальный файл политики ядра. Подробнее о построении sepolicy на устройстве см. в разделе «Создание sepolicy» .
Выполнение
Чтобы начать работу с SELinux:
- Включить SELinux в ядре:
CONFIG_SECURITY_SELINUX=y - Измените параметр kernel_cmdline или bootconfig таким образом:
илиBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
Это необходимо только для первоначальной разработки политики для устройства. После создания начальной политики самозагрузки удалите этот параметр, чтобы устройство выполняло принудительное применение политики, иначе оно не сможет пройти CTS.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- Загрузите систему в разрешительном режиме и посмотрите, какие запреты возникнут при загрузке:
В Ubuntu 14.04 или новее: В Ubuntu 12.04:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Проверьте вывод на наличие предупреждений, похожих
init: Warning! Service name needs a SELinux domain defined; please fix!Инструкции и инструменты см. в разделе «Проверка» . - Определите устройства и другие новые файлы, требующие маркировки.
- Используйте существующие или новые метки для своих объектов. Просмотрите файлы
*_contexts, чтобы узнать, как объекты были помечены ранее, и используйте информацию о значениях меток для назначения новой. В идеале это должна быть существующая метка, соответствующая политике, но иногда требуется новая метка и правила доступа к ней. Добавьте свои метки в соответствующие файлы контекста. - Определите домены/процессы, которым следует задать собственные домены безопасности. Вероятно, вам потребуется написать совершенно новую политику для каждого из них. Например, все службы, запущенные из
init, должны иметь свою собственную. Следующие команды помогают определить, какие из них остаются запущенными (но такая обработка требуется для ВСЕХ служб):adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Проверьте
init. device .rcчтобы определить все домены, у которых нет типа домена. Задайте им домен на ранних этапах разработки, чтобы избежать добавления правил вinitи не путать доступыinitс доступами, указанными в их собственной политике. - Настройте
BOARD_CONFIG.mkдля использования переменныхBOARD_SEPOLICY_*. Подробную информацию о настройке см. в файле README вsystem/sepolicy - Проверьте файлы device и device и убедитесь, что каждое использование
mountсоответствует правильно помеченной файловой системе или что указана опцияcontext= mount. - Проанализируйте каждое отклонение и создайте политику SELinux для его корректной обработки. См. примеры в разделе «Настройка» .
Начните с политик в AOSP, а затем дополняйте их собственными настройками. Подробнее о стратегии политики и более подробном рассмотрении некоторых из этих шагов см. в разделе «Написание политики SELinux» .
Варианты использования
Вот конкретные примеры эксплойтов, которые следует учитывать при создании собственного программного обеспечения и связанных с ним политик SELinux:
Символические ссылки: Поскольку символические ссылки выглядят как файлы, они часто читаются как файлы, что может привести к эксплойтам. Например, некоторые привилегированные компоненты, такие как init , изменяют права доступа к определённым файлам, иногда делая их чрезмерно открытыми.
Затем злоумышленники могут заменить эти файлы символическими ссылками на контролируемый ими код, что позволит им перезаписывать произвольные файлы. Но если вы знаете, что ваше приложение никогда не использует символические ссылки, вы можете запретить ему это делать с помощью SELinux.
Системные файлы: Рассмотрим класс системных файлов, которые должен изменять только системный сервер. Однако, поскольку netd , init и vold работают от имени root, они могут получить доступ к этим системным файлам. Таким образом, если netd будет скомпрометирован, это может привести к компрометации этих файлов и, возможно, самого системного сервера.
С помощью SELinux эти файлы можно идентифицировать как файлы данных системного сервера. Следовательно, единственный домен, имеющий доступ к ним на чтение и запись, — это системный сервер. Даже если бы netd был скомпрометирован, он не смог бы переключиться на домен системного сервера и получить доступ к этим системным файлам, хотя и работает под учетной записью root.
Данные приложения: Другой пример — класс функций, которые должны запускаться от имени пользователя root, но не должны иметь доступа к данным приложения. Это невероятно полезно, поскольку позволяет делать широкие утверждения, например, запрещать доступ к интернету определённым доменам, не связанным с данными приложения.
setattr: Для таких команд, как chmod и chown , можно определить набор файлов, к которым соответствующий домен может применить setattr . Изменения, вносимые за пределами этого списка, могут быть запрещены, даже для root-пользователя. Таким образом, приложение может выполнять chmod и chown для файлов с меткой app_data_files , но не shell_data_files или system_data_files .