- PVSM.RU - https://www.pvsm.ru -
Самой распространенной операционной системой для смартфонов на сегодняшний день является Android. Но не только этот факт подогревает интерес к ней. Открытость, возможность что-то настроить, подкрутить, и, естественно, сломать тоже в немалой степени способствуют увеличению популярности этой платформы. Я попробую поделиться опытом, как устроена эта операционная система, а так же рассмотреть систему безопасности. Всем, кому интересно, добро пожаловать! В этой статье я рассмотрю безопасность на уровне ядра.
Термины я буду стараться писать на английком языке, так как боюсь ошибиться в их переводе. Если кто-то знает, как их красиво перевести на русский язык, напишите мне, и я дам перевод этих терминов. Желательно, чтобы у вас под рукой находились исходный код Android (хотя я и буду стараться давать ссылки на файлы в Интернете), потому что я иногда буду давать ссылки на файлы, где находится та или иная функциональность. Как загрузить исходный код, можно почитать здесь [1] или вот в этой [2] статье на Хабре.
Ну никуда не деться от этой картинки. Я нашел её на просторах Интернета и нужна она для того, чтобы понять из чего состоит Android. Итак, в стеке Android выделяют четыре уровня (снизу-вверх):
Linux kernel. Как неудивительно это звучит, но изначально, Android Inc. — это стартап. Как и во всех стартапах, в этой компании стояла задача максимально использовать уже существующие решения. Поэтому в качестве ядра этой платформы был выбран Linux из-за его открытости и наличия необходимой функциональности. В Android ядро Linux управляет памятью, процессами, а так же используется в качестве hardware abstraction layer (HAL). Насколько мне известно, в Linux драйвера либо встроены в ядро, либо разработаны в виде загружаемых модулей ядра. Так как в Android загрузка модулей ядра по умолчанию отключена, а если встраивать все драйвера, то ядро очень сильно разрастется, то было принято решение создать промежуточный слой (proxy) между ядром и драйверами, который и назвали HAL. Таким образом, HAL — это просто набор интерфейсов, имплементация которых реализована в драйверах. С другой стороны в ядро были добавлены некоторые системы, которые характерны только для Android систем. На данный момент, они пока не включены в основную ветку ядра Linux, поэтому просто скачать ядро Linux и заменить им ядро Android не получится. Среди них следует выделить, Binder (обеспечивает межпроцессное взаимодействие IPC/RPC), Asynchronous SHared MEMory — Ashmem (драйвер разделяемой памяти), Wakelocks (механизм, который позволяет предотвращать затемнение экрана и/или отключение процессора), Low Memory Killer, Alarm, Logger и т.д.
Native Libraries. К этому слою относятся различные нативные библиотеки, которые необходимы для работы Android. Они так же позаимствованы у open-source сообщества. Среди них мы можем найти SQLite, WebKit и т.д.
Android Framework. К этому слою относится то, с чем мы обычно взаимодействуем, когда пишем наши приложения для Android (PowerManager, ActivityManager, NotificationManager и т.д.).
Applications. Приложения бывают двух типов: те, что поставляются вместе с образом системы (системные) и приложения, которые мы загружаем из маркета или других источников. В первом случае, в устройстве приложения находятся в "/system/app" директории, во втором случае в "/data/app".
Давайте рассмотрим процесс установки приложения на Android устройство.
Существует несколько способов установить приложение на устройство (в общем случае):
На рисунке, например, приложение ex1.apk устанавливается с помощью PackageInstaller (используется в случае, если вам, например, по почте прислали приложение и вы хотите его установить с устройства), ex2.apk устанавливается с помощью Android Market (Google Play), и приложение ex3.apk устанавливается с помощью комманды adb install ex3.apk (обычно эта комманда используется разработчиками приложений для установки приложения с компьютера).
Во время установки, Android каждому приложению по умолчанию присваивает уникальные user ID (UID) и group ID (GID), таким образом каждому приложению в этой операционной системе соответсвует свой пользователь. Имя пользователя обычно имеет формат app_x, а идентификаторы пользователя вычисляется по формуле (Process.FIRST_APPLICATION_UID + x), Process.FIRST_APPLICATION_UID равен 10000. Эти идентификаторы приложения не изменяются. Список установленных приложений хранится в файле "/data/system/packages.list" и если у вас рутованый телефон, или вы работаете с эмулятором, то вы можете просмотреть этот файл, используя следующую комманду:
adb shell cat /data/system/packages.list
У каждого приложения есть своя домашняя директория, например /data/data/<package_name>, где <package_name> — имя Android пакета, например com.ex.ex1 Имя Android пакета задается в свойстве package в файле AndroidManifest.xml Эта папка — Internal storage (внутреннее хранилище), директория, где приложение хранит все свои приватные данные, и к которому разработчики приложений получают доступ используя функции Context.getFilesDir() [3] или Context.getDir() [4] У этой папки права доступа определены как drwxrwx--x, т.е. только владелец и пользователи входящие в группу владельцев имеют полный доступ к этой папке. А так как каждое приложение определено как уникальный пользователь, то это означает, что приложения, по умолчанию, не имеют доступа к информации друг друга. Хотя при создании файла во внутреннем хранилище можно явно задать, что этот файл будет MODE_WORLD_READABLE [5] и/или MODE_WORLD_WRITABLE [6]
Кроме того, на уровне ядра уникальные UID и GID каждого приложения используются для разделения доступа к ресурсам системы (память и процессорное время). Таким образом, на уровне ядра для каждого приложения создается своя собственная песочница (Application Sandbox).
С другой стороны, разработчик приложения может указать некоторые ЕГО приложения должны иметь один и тот же UID. В AndroidManifest.xml файле для этого есть специальное свойство sharedUserId [7] В этом случае, эти приложения будут иметь доступ к ресурсам друг-друга, но только если они подписаны одним и тем же ключом разработчика. Если приложения имеют
Некоторые permission (разрешения) так же работают на уровне ядра. Давайте, например, рассмотрим наиболее используемое разрешение android.permission.INTERNET [8] Если приложение запрашивает это разрешение, то Android во время установки дополнительно включает это приложение в специальную группу «inet». Так же работают и некоторые другие разрешения. Список соответствия между этими разрешениями и соответствующими группами можно найти в файле frameworks/base/data/etc/platform.xml [9]:
<permissions>
...
<permission name="android.permission.INTERNET" >
<group gid="inet" />
</permission>
<permission name="android.permission.CAMERA" >
<group gid="camera" />
</permission>
<permission name="android.permission.READ_LOGS" >
<group gid="log" />
</permission>
...
</permissions>
Список соответствия между именами этих групп и значениями (GID) задан в явном виде в файле system/core/include/private/android_filesystem_config.h [10] в массиве структур android_ids[]:
...
#define AID_ROOT 0 /* traditional unix root user */
#define AID_SYSTEM 1000 /* system server */
...
#define AID_CAMERA 1006 /* camera devices */
...
#define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
...
static const struct android_id_info android_ids[] = {
{ "root", AID_ROOT, },
...
{ "camera", AID_CAMERA, },
{ "log", AID_LOG, },
...
{ "inet", AID_INET, },
...
}
...
Таким образом, если приложение пытается подключиться к Интернету, ядро проверяет, находится ли это приложение в группе с идентификатором AID_INET. Если нет, то приложению запрещается доступ. Код этой проверки очень тривиальный [11]:
...
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
#include <linux/android_aid.h>
static inline int current_has_network(void)
{
return in_egroup_p(AID_INET) || capable(CAP_NET_RAW);
}
#else
static inline int current_has_network(void)
{
return 1;
}
#endif
...
/*
* Create an inet socket.
*/
static int inet_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
...
if (!current_has_network())
return -EACCES;
...
}
Это моя первая статья на Хабре, так что не судите строго. Если сообществу интересно, то я продолжу в следующих статьях описывать внутренности Android. Я понимаю, что много не знаю, да и времени всегда не хватает, но я постараюсь поделиться тем, что уже пропустил через себя. Надеюсь, что узнаю что-то новое из комментариев! Если кому-то интересна какая-то определенная тема, то пишите в комментариях, постараюсь в будущих статьях учесть ваши пожелания.
Автор: zyrik
Источник [16]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/31442
Ссылки в тексте:
[1] здесь: http://source.android.com/source/index.html
[2] этой: http://habrahabr.ru/company/intel/blog/153521/
[3] Context.getFilesDir(): http://developer.android.com/reference/android/content/Context.html#getFilesDir()
[4] Context.getDir(): http://developer.android.com/reference/android/content/Context.html#getDir(java.lang.String, int)
[5] MODE_WORLD_READABLE: http://developer.android.com/reference/android/content/Context.html#MODE_WORLD_READABLE
[6] MODE_WORLD_WRITABLE: http://developer.android.com/reference/android/content/Context.html#MODE_WORLD_WRITEABLE
[7] sharedUserId: http://developer.android.com/guide/topics/manifest/manifest-element.html#uid
[8] android.permission.INTERNET: http://developer.android.com/reference/android/Manifest.permission.html#INTERNET
[9] frameworks/base/data/etc/platform.xml: https://android.googlesource.com/platform/frameworks/base//+/master/data/etc/platform.xml
[10] system/core/include/private/android_filesystem_config.h: https://android.googlesource.com/platform/system/core//+/master/include/private/android_filesystem_config.h
[11] тривиальный: https://android.googlesource.com/kernel/common.git//+/android-3.4/net/ipv4/af_inet.c
[12] «Embedded Android»: http://shop.oreilly.com/product/0636920021094.do
[13] «Android Security Underpinnings»: https://marakana.com/s/post/1393/slides.htm
[14] «Understanding Android Security»: http://css.csail.mit.edu/6.858/2012/readings/android.pdf
[15] Android Security Overview: http://source.android.com/tech/security/index.html
[16] Источник: http://habrahabr.ru/post/175517/
Нажмите здесь для печати.