Проект Android с открытым исходным кодом (AOSP) обеспечивает надежную базовую политику для приложений и служб, которые являются общими для всех устройств Android. Участники AOSP регулярно дорабатывают эту политику. Ожидается, что основная политика составит около 90–95 % окончательной политики для устройств, а настройки для конкретных устройств составят оставшиеся 5–10 %. В этой статье основное внимание уделяется настройкам для конкретных устройств, написанию политики для конкретных устройств и некоторым ловушкам, которых следует избегать на этом пути.
Вызов устройства
При написании политики для конкретного устройства выполните следующие действия.
Запуск в разрешительном режиме
Когда устройство находится в разрешительном режиме , отказы регистрируются, но не применяются. Разрешительный режим важен по двум причинам:
- Разрешительный режим гарантирует, что запуск политики не задерживает выполнение других задач раннего запуска устройства.
- Принудительное отрицание может маскировать другие отрицания. Например, доступ к файлу обычно включает в себя поиск в каталоге, открытие файла, а затем его чтение. В принудительном режиме произойдет только отказ в поиске по каталогу. Разрешительный режим гарантирует, что все отказы будут видны.
Самый простой способ перевести устройство в разрешительный режим — использовать командную строку ядра . Его можно добавить в файл BoardConfig.mk
устройства: platform/device/<vendor>/<target>/BoardConfig.mk
. После изменения командной строки выполните команду make clean
, затем make bootimage
и запустите новый загрузочный образ.
После этого подтвердите разрешительный режим с помощью:
adb shell getenforce
Две недели — разумный срок для пребывания в глобальном разрешительном режиме. После устранения большинства отказов вернитесь в режим принудительного применения и устраняйте ошибки по мере их поступления. Домены, которые все еще выдают отказы, или службы, которые все еще находятся в стадии интенсивной разработки, могут быть временно переведены в разрешительный режим, но как можно скорее верните их в режим принудительного применения.
Применять на ранней стадии
В принудительном режиме отказы одновременно протоколируются и применяются. Рекомендуется как можно раньше перевести ваше устройство в обязательный режим. Ожидание создания и применения политики для конкретного устройства часто приводит к появлению ошибок в продукте и ухудшению пользовательского опыта. Начните достаточно рано, чтобы принять участие в тестировании и обеспечить полное тестирование функциональности в реальных условиях. Ранний старт гарантирует, что соображения безопасности будут учитываться при проектных решениях. И наоборот, предоставление разрешений исключительно на основании наблюдаемых отказов является небезопасным подходом. Используйте это время для проверки безопасности устройства и выявления ошибок в поведении, которое не должно быть разрешено.
Удалить или удалить существующую политику
Существует ряд веских причин создать политику для конкретного устройства с нуля на новом устройстве, в том числе:
- Аудит безопасности
- Слишком либеральная политика
- Уменьшение размера полиса
- Мертвая политика
Устранение отказов в основных услугах
Отказы, генерируемые основными службами, обычно устраняются путем маркировки файлов. Например:
avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0” dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1 avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
полностью решается путем правильной маркировки /dev/kgsl-3d0
. В этом примере tcontext
— это device
. Это представляет собой контекст по умолчанию, в котором все в /dev
получает метку « устройство », если не назначена более конкретная метка. Простое принятие вывода Audit2allow приведет к созданию неправильного и чрезмерно разрешающего правила.
Чтобы решить проблему такого рода, присвойте файлу более конкретную метку, в данном случае — gpu_device . Никаких дополнительных разрешений не требуется, поскольку медиасервер уже имеет необходимые разрешения в основной политике для доступа к gpu_device.
Другие файлы, специфичные для устройства, которые должны быть помечены типами, предопределенными в основной политике:
- блокировать устройства
- аудиоустройства
- видеоустройства
- датчики
- НФК
- gps_device
- файлы в /sys
- файлы в /proc
В целом предоставление разрешений меткам по умолчанию неверно. Многие из этих разрешений запрещены правилами Neverallow , но даже если они не запрещены явно, рекомендуется указать специальную метку.
Маркируйте новые услуги и устраняйте отказы
Службы, запускаемые с помощью Init, должны работать в собственных доменах SELinux. В следующем примере служба «foo» помещается в собственный домен SELinux и предоставляет ей разрешения.
Сервис запускается в init. device .rc
файл init. device .rc
как:
service foo /system/bin/foo class core
- Создайте новый домен «foo»
Создайте файл
device/ manufacturer / device-name /sepolicy/foo.te
со следующим содержимым:# foo service type foo, domain; type foo_exec, exec_type, file_type; init_daemon_domain(foo)
Это исходный шаблон для домена foo SELinux, к которому вы можете добавлять правила, основанные на конкретных операциях, выполняемых этим исполняемым файлом.
- Метка
/system/bin/foo
Добавьте следующее в
device/ manufacturer / device-name /sepolicy/file_contexts
:/system/bin/foo u:object_r:foo_exec:s0
Это гарантирует, что исполняемый файл правильно помечен и SELinux запускает службу в правильном домене.
- Создайте и прошейте загрузочный и системный образы.
- Уточните правила SELinux для домена.
Используйте отказы, чтобы определить необходимые разрешения. Инструмент Audit2allow предоставляет хорошие рекомендации, но используйте его только для разработки политики. Не просто копируйте вывод.
Вернитесь в режим принудительного применения
Устранять неполадки в разрешительном режиме можно, но как можно раньше вернитесь в принудительный режим и постарайтесь оставаться в нем.
Распространенные ошибки
Вот несколько решений распространенных ошибок, которые случаются при написании политик для конкретных устройств.
Чрезмерное использование отрицания
Следующий пример правила подобен запиранию входной двери, но оставлению окон открытыми:
allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms
Цель ясна: доступ к устройству отладки может иметь каждый, кроме сторонних приложений.
Это правило ошибочно в нескольких отношениях. Исключение untrusted_app
легко обойти, поскольку все приложения могут при желании запускать службы в домене isolated_app
. Аналогично, если в AOSP добавляются новые домены для сторонних приложений, они также получают доступ к scary_debug_device
. Это правило слишком либерально. Большинству доменов не будет полезно иметь доступ к этому инструменту отладки. Правило должно было быть написано так, чтобы разрешать только те домены, которым требуется доступ.
Отладка функций в производстве
Функции отладки не должны присутствовать в производственных сборках, как и их политика.
Самая простая альтернатива — разрешить функцию отладки только тогда, когда SELinux отключен в сборках eng/userdebug, таких как adb root
и adb shell setenforce 0
.
Другая безопасная альтернатива — включить разрешения на отладку в оператор userdebug_or_eng .
Взрыв размера политики
Характеристика SEAndroid Policies in the Wild описывает тревожную тенденцию роста количества настроек политик устройств. Политика, специфичная для устройства, должна составлять 5–10 % от общей политики, действующей на устройстве. Настройки в диапазоне 20%+ почти наверняка содержат слишком привилегированные домены и мертвую политику.
Неоправданно большая политика:
- Выполняет двойной удар по памяти, поскольку политика находится на виртуальном диске, а также загружается в память ядра.
- Тратит дисковое пространство из-за необходимости создания загрузочного образа большего размера.
- Влияет на время поиска политики времени выполнения.
В следующем примере показаны два устройства, где политика, специфичная для производителя, составляла 50 % и 40 % политики на устройстве. Переписывание политики привело к существенному улучшению безопасности без потери функциональности, как показано ниже. (Устройства AOSP Shamu и Flounder включены для сравнения.)
В обоих случаях политика была резко уменьшена как по размеру, так и по количеству разрешений. Уменьшение размера политики почти полностью связано с удалением ненужных разрешений, многие из которых, вероятно, были правилами, созданными audit2allow
и без разбора добавленными в политику. Мертвые домены также были проблемой для обоих устройств.
Предоставьте возможность dac_override
Отказ dac_override
означает, что процесс-нарушитель пытается получить доступ к файлу с неправильными разрешениями пользователя/группы/мира unix. Правильное решение — почти никогда не предоставлять разрешение dac_override
. Вместо этого измените разрешения Unix для файла или процесса . Некоторым доменам, таким как init
, vold
и installd
действительно нужна возможность переопределять разрешения файлов unix для доступа к файлам других процессов. См . блог Дэна Уолша для более подробного объяснения.