Просмотрите эту страницу, чтобы ознакомиться с концепциями SELinux.
Обязательный контроль доступа
Security Enhanced Linux (SELinux) — это система обязательного контроля доступа (MAC) для операционной системы Linux. Как система MAC, она отличается от привычной системы дискреционного контроля доступа (DAC) Linux. В системе DAC существует концепция владения, при которой владелец определенного ресурса контролирует связанные с ним разрешения на доступ. Обычно это грубо детализировано и подвержено непреднамеренному повышению привилегий. Однако система MAC консультируется с центральным органом для принятия решения по всем попыткам доступа.
SELinux был реализован как часть фреймворка Linux Security Module (LSM), который распознает различные объекты ядра и чувствительные действия, выполняемые над ними. В точке, в которой каждое из этих действий будет выполнено, вызывается функция LSM hook, чтобы определить, следует ли разрешить действие, на основе информации для него, хранящейся в непрозрачном объекте безопасности. SELinux предоставляет реализацию для этих hooks и управление этими объектами безопасности, которые объединяются с его собственной политикой, для определения решений о доступе.
Наряду с другими мерами безопасности Android, политика контроля доступа Android значительно ограничивает потенциальный ущерб от скомпрометированных машин и учетных записей. Использование таких инструментов, как дискреционный и обязательный контроль доступа Android, дает вам структуру, гарантирующую, что ваше программное обеспечение будет работать только на минимальном уровне привилегий. Это смягчает последствия атак и снижает вероятность перезаписи или даже передачи данных ошибочными процессами.
В Android 4.3 и выше SELinux предоставляет зонтик обязательного контроля доступа (MAC) над традиционными средами дискреционного контроля доступа (DAC). Например, программное обеспечение обычно должно запускаться как учетная запись пользователя root для записи на необработанные блочные устройства. В традиционной среде Linux на основе DAC, если пользователь root оказывается скомпрометирован, он может записывать на каждое необработанное блочное устройство. Однако SELinux можно использовать для маркировки этих устройств, чтобы процесс, которому назначены привилегии root, мог записывать только на те, которые указаны в соответствующей политике. Таким образом, процесс не может перезаписывать данные и системные настройки за пределами определенного необработанного блочного устройства.
Дополнительные примеры угроз и способы их устранения с помощью SELinux см. в разделе «Варианты использования» .
Уровни принуждения
SELinux может быть реализован в различных режимах:
- Разрешительный — политика безопасности SELinux не применяется, а только регистрируется.
- Принудительное применение — политика безопасности применяется и регистрируется. Сбои отображаются как ошибки EPERM.
Этот выбор является бинарным и определяет, будет ли ваша политика действовать или просто позволит вам собирать потенциальные сбои. Permissive особенно полезен во время внедрения.
Типы, атрибуты и правила
Android использует компонент Type Enforcement (TE) SELinux для своей политики. Это означает, что все объекты (такие как файл, процесс или сокет) имеют тип, связанный с ними. Например, по умолчанию приложение имеет тип untrusted_app
. Для процесса его тип также известен как его домен . Можно аннотировать тип одним или несколькими атрибутами . Атрибуты полезны для ссылки на несколько типов одновременно.
Объекты сопоставляются с классами (например, файл, каталог, символическая ссылка, сокет), а различные виды доступа для каждого класса представлены разрешениями . Например, разрешение open
существует для класса file
. В то время как типы и атрибуты регулярно обновляются как часть политики Android SELinux, разрешения и классы определены статически и редко обновляются как часть нового выпуска Linux.
Правило политики имеет вид: allow source target : class permissions ;
где:
- Источник - Тип (или атрибут) субъекта правила. Кто запрашивает доступ?
- Цель - Тип (или атрибут) объекта. К чему запрашивается доступ?
- Класс — тип объекта (например, файл, сокет), к которому осуществляется доступ.
- Разрешения — выполняемая операция (или набор операций) (например, чтение, запись).
Пример правила:
allow untrusted_app app_data_file:file { read write };
Это говорит о том, что приложениям разрешено читать и записывать файлы с меткой app_data_file
. Существуют и другие типы для приложений. Например, для служб приложений с isolatedProcess=true
в их манифесте используется isolated_app
. Вместо того чтобы повторять правило для обоих типов, Android использует атрибут с именем appdomain
для всех типов, охватывающих приложения:
# Associate the attribute appdomain with the type untrusted_app. typeattribute untrusted_app appdomain; # Associate the attribute appdomain with the type isolated_app. typeattribute isolated_app appdomain; allow appdomain app_data_file:file { read write };
Когда написано правило, которое указывает имя атрибута, это имя автоматически расширяется до списка доменов или типов, связанных с атрибутом. Некоторые примечательные атрибуты:
-
domain
- атрибут, связанный со всеми типами процессов, -
file_type
— атрибут, связанный со всеми типами файлов.
Макросы
В частности, для доступа к файлам необходимо рассмотреть множество видов разрешений. Например, разрешения read
недостаточно для открытия файла или вызова stat
для него. Чтобы упростить определение правила, Android предоставляет набор макросов для обработки наиболее распространенных случаев. Например, чтобы включить отсутствующие разрешения, такие как open
, правило выше можно переписать следующим образом:
allow appdomain app_data_file:file rw_file_perms;
Дополнительные примеры полезных макросов см. в файлах global_macros
и te_macros
. Макросы следует использовать везде, где это возможно, чтобы снизить вероятность сбоев из-за отказов в соответствующих разрешениях.
После определения типа его необходимо связать с файлом или процессом, который он представляет. Подробнее о том, как выполняется эта ассоциация, см. в разделе Реализация SELinux . Дополнительную информацию о правилах см. в разделе Записная книжка SELinux .
Контекст и категории безопасности
При отладке политик SELinux или маркировке файлов (с помощью file_contexts
или при использовании ls -Z
) вы можете столкнуться с контекстом безопасности (также известным как label ). Например: u:r:untrusted_app:s0:c15,c256,c513,c768
. Контекст безопасности имеет формат: user:role:type:sensitivity[:categories]
. Обычно вы можете игнорировать поля user
, role
и sensitivity
контекста (см. Specificity ). Поле type
объяснено в предыдущем разделе. categories
являются частью поддержки многоуровневой безопасности (MLS) в SELinux. В Android 12 и выше категории используются для:
- Изолируйте данные приложения от доступа другого приложения,
- Изолируйте данные приложения от одного физического пользователя и передавайте их другому.
Специфичность
Android не использует все функции, предоставляемые SELinux. При чтении внешней документации имейте в виду следующие моменты:
- Большинство политик в AOSP определены с использованием языка политики ядра. Существуют некоторые исключения для использования общего промежуточного языка (CIL).
- Пользователи SELinux не используются. Единственный определенный пользователь —
u
. При необходимости физические пользователи представляются с использованием поля категорий контекста безопасности. - Роли SELinux и управление доступом на основе ролей (RBAC) не используются. Определены и используются две роли по умолчанию:
r
для субъектов иobject_r
для объектов. - Чувствительности SELinux не используются. Всегда установлена чувствительность
s0
по умолчанию. - Булевы значения SELinux не используются. Когда политика создается для устройства, она не зависит от состояния устройства. Это упрощает аудит и отладку политик.