Содержание
Обзор KasperskyOS
KasperskyOS – специализированная операционная система на основе микроядра разделения и монитора безопасности.
См. также:
Общие сведения
Микроядерность
KasperskyOS является микроядерной операционной системой. Ядро предоставляет минимальную функциональность, включая планирование исполнения программ, управление памятью и вводом-выводом. Код драйверов устройств, файловых систем, сетевых протоколов и другого системного ПО исполняется в пользовательском режиме (вне контекста ядра).
Процессы и службы
ПО, управляемое KasperskyOS, исполняется в виде процессов. Процесс – это запущенная на исполнение программа, которая имеет следующие особенности:
- может предоставлять службы другим процессам и/или использовать службы других процессов через механизм IPC;
- использует службы ядра через механизм IPC;
- ассоциируется с правилами безопасности, которые регулируют взаимодействия процесса с другими процессами и ядром.
Служба (англ. endpoint) – набор связанных по смыслу методов, доступных через механизм IPC (например, служба для приема и передачи данных по сети, служба для работы с прерываниями).
Реализация архитектурных подходов MILS и FLASK
Разрабатывая систему на базе KasperskyOS, ПО проектируют как набор компонентов (программ), взаимодействие между которыми регулируется механизмами безопасности. С точки зрения безопасности уровень доверия к каждому компоненту может быть высоким или низким, то есть ПО системы включает доверенные и недоверенные компоненты. Взаимодействиями компонентов между собой (и с ядром) управляет ядро (см. рис. ниже), уровень доверия к которому является высоким. Такой дизайн системы базируется на архитектурном подходе MILS (Multiple Independent Levels of Security), который применяется при разработке информационных систем ответственного применения.
Решение о разрешении или запрете конкретного взаимодействия принимает модуль безопасности Kaspersky Security Module. (Это решение называется решением модуля безопасности.) Модуль безопасности является модулем ядра, уровень доверия к которому является высоким, как и к самому ядру. Ядро выполняет решение модуля безопасности. Такое разделение функций по управлению взаимодействиями основано на архитектурном подходе FLASK (Flux Advanced Security Kernel), используемом в операционных системах для гибкого применения политик безопасности.
Взаимодействие процессов между собой и с ядром в KasperskyOS
Решение на базе KasperskyOS
Системное ПО (включая ядро KasperskyOS и модуль безопасности Kaspersky Security Module) и прикладное ПО, интегрированные для работы в составе программно-аппаратного комплекса, представляют собой решение на базе KasperskyOS (далее также решение). Программы, входящие в решение на базе KasperskyOS, являются компонентами решения на базе KasperskyOS (далее компонентами решения). Каждый экземпляр компонента решения исполняется в контексте отдельного процесса.
Политика безопасности решения на базе KasperskyOS
Разрешения и запреты взаимодействий процессов между собой и с ядром KasperskyOS задает политика безопасности решения на базе KasperskyOS (далее политика безопасности решения, политика). Политика безопасности решения сохраняется в модуле безопасности Kaspersky Security Module и используется этим модулем, когда он принимает решения о разрешении или запрете взаимодействий.
Также политика безопасности решения может задавать логику обработки обращений процесса к модулю безопасности через интерфейс безопасности. Процесс может использовать интерфейс безопасности, чтобы передать в модуль безопасности какие-либо данные (например, чтобы повлиять на последующие решения модуля безопасности) или получить решение модуля безопасности, которое требуется процессу для определениях своих дальнейших действий.
Технология Kaspersky Security System
Технология Kaspersky Security System позволяет реализовать разнообразные политики безопасности решений. При этом можно комбинировать несколько механизмов безопасности и гибко регулировать взаимодействия процессов между собой и с ядром KasperskyOS. Чтобы описать политику безопасности решения, используется специально разработанный язык PSL (Policy Specification Language). На основе описания политики безопасности решения создается модуль безопасности Kaspersky Security Module для использования в конкретном решении.
Генераторы исходного кода
Часть исходного кода решения на базе KasperskyOS создается генераторами исходного кода. Специальные программы генерируют исходный код на языке C из декларативных описаний. Генерируется исходный код модуля безопасности Kaspersky Security Module, инициализирующей программы (запускает остальные программы в решении и статически задает топологию взаимодействия между ними), а также методов и типов для осуществления IPC (транспортный код).
Транспортный код генерируется компилятором nk-gen-c
из декларативных описаний на языках IDL (Interface Definition Language), CDL (Component Definition Language) и EDL (Entity Definition Language) соответственно (подробнее см. "Формальные спецификации компонентов решения на базе KasperskyOS").
Исходный код модуля безопасности Kaspersky Security Module генерируется компилятором nk-psl-gen-c
из описания политики безопасности решения и IDL-, CDL-, EDL-описаний.
Исходный код инициализирующей программы генерируется утилитой einit
из описания инициализации решения (в формате YAML) и IDL-, CDL-, EDL-описаний.
Архитектура KasperskyOS
Архитектура KasperskyOS представлена на рисунке ниже:
Архитектура KasperskyOS
В KasperskyOS приложения и драйверы взаимодействуют между собой и с ядром, используя библиотеку libkos
, которая предоставляет интерфейсы для обращения к службам ядра. (Драйвер в KasperskyOS в общем случае работает на том же уровне привилегий, что и приложение.) Библиотека libkos
обращается к ядру, выполняя только три системных вызова: Call()
, Recv()
и Reply()
, которые реализуют механизм IPC. Службы ядра поддерживаются подсистемами ядра, назначение которых приведено в таблице ниже. Подсистемы ядра взаимодействуют с аппаратурой через уровень аппаратных абстракций (англ. Hardware Abstraction Layer, HAL), что упрощает портирование KasperskyOS на различные платформы.
Подсистемы ядра и их назначение
Обозначение |
Наименование |
Назначение |
---|---|---|
HAL |
Подсистема аппаратных абстракций |
Базовая поддержка аппаратуры: таймеры, контроллеры прерываний, блок управления памятью (англ. Memory Management Unit, MMU). Подсистема включает в себя драйверы UART и низкоуровневые средства управления электропитанием. |
IO |
Менеджер ввода-вывода |
Регистрация и освобождение ресурсов аппаратной платформы, необходимых для работы драйверов: прерываний (англ. Interrupt ReQuest, IRQ), MMIO-памяти (англ. Memory-Mapped Input-Output), портов ввода-вывода, DMA-буферов. При наличии у аппаратуры блока управления памятью для операций ввода-вывода (англ. Input-Output Memory Management Unit, IOMMU) подсистема задействуется для более высоких гарантий разделения памяти. |
MM |
Менеджер физической памяти |
Выделение и освобождение физических страниц памяти, распределение областей физически непрерывных страниц. |
VMM |
Менеджер виртуальной памяти |
Управление физической и виртуальной памятью: резервирование, фиксирование, освобождение. Работа с таблицами страниц памяти для изоляции адресных пространств процессов. |
THREAD |
Менеджер потоков |
Управление потоками исполнения: создание, уничтожение, приостановка и возобновление. |
TIME |
Подсистема часов реального времени |
Получение и установка системного времени. Использование таймеров, предоставляемых аппаратурой. |
SCHED |
Планировщик |
Поддержка трех классов планирования: потоки реального времени, потоки общего назначения и IDLE – состояние, когда нет потока, готового для исполнения. |
SYNC |
Подсистема, обеспечивающая примитивы синхронизации |
Реализация базовых примитивов синхронизации: спинлок (англ. spinlock), мьютекс (англ. mutex), событие (англ. event). Ядро поддерживает лишь один примитив – фьютекс (англ. futex), остальные примитивы реализованы на его основе в пространстве пользователя. |
IPC |
Подсистема межпроцессного взаимодействия |
Реализация синхронного механизма IPC по принципу рандеву. |
KSMS |
Подсистема взаимодействия с модулем безопасности |
Подсистема, работающая с модулем безопасности. Она предоставляет модулю безопасности для проверки все сообщения, передающиеся через IPC. |
OBJ |
Менеджер объектов |
Управление общим поведением всех ресурсов KasperskyOS: отслеживание жизненного цикла, назначение уникальных идентификаторов безопасности (подробнее см. "Управление доступом к ресурсам"). Подсистема тесно связана с механизмом управления доступом на основе мандатных ссылок (англ. Object Capability, OCap). |
ROMFS |
Подсистема запуска образа неизменяемой файловой системы |
Операции с файлами из ROMFS: открытие и закрытие, получение списка файлов и их описаний, получение характеристик файла (имени, размера). |
TASK |
Подсистема управления процессами |
Управление процессами: запуск, завершение, приостановка и возобновление. Получение характеристик запущенных процессов (например, имени, пути и приоритета) и кодов их завершения. |
ELF |
Подсистема загрузки исполняемых файлов |
Загрузка исполняемых ELF-файлов из ROMFS в оперативную память, разбор заголовков ELF-файлов. |
DBG |
Подсистема поддержки отладки |
Механизм отладки на основе GDB (GNU Debugger). Наличие подсистемы в ядре опционально. |
PM |
Менеджер электропитания |
Управление электропитанием: выполнение перезагрузки и выключения. |
Механизм IPC
Обмен IPC-сообщениями
В KasperskyOS процессы взаимодействуют между собой, обмениваясь IPC-сообщениями: IPC-запросом и IPC-ответом. Во взаимодействии процессов выделяется две роли: клиент (процесс, инициирующий взаимодействие) и сервер (процесс, обрабатывающий обращение). При этом процесс, являющийся клиентом в одном взаимодействии, может выступать как сервер в другом.
Чтобы обмениваться IPC-сообщениями, клиент и сервер используют три системных вызова: Call()
, Recv()
и Reply()
(см. рис. ниже):
- Клиент направляет серверу IPC-запрос. Для этого один из потоков исполнения клиента выполняет системный вызов
Call()
и блокируется до получения IPC-ответа от сервера. - Серверный поток, выполнивший системный вызов
Recv()
, находится в ожидании IPC-запросов. При получении IPC-запроса этот поток разблокируется, обрабатывает запрос и отправляет IPC-ответ с помощью системного вызоваReply()
. - При получении IPC-ответа клиентский поток разблокируется и продолжает исполнение.
Обмен IPC-сообщениями между клиентом и сервером
Вызов методов служб сервера
Отправка IPC-запросов серверу осуществляется, когда клиент вызывает методы служб (далее также интерфейсные методы) сервера (см. рис. ниже). IPC-запрос содержит входные параметры вызываемого метода, а также идентификатор службы RIID и идентификатор вызываемого метода MID. Получив запрос, сервер использует эти идентификаторы, чтобы найти реализацию метода. Сервер вызывает реализацию метода, передав в нее входные параметры из IPC-запроса. Обработав запрос, сервер отправляет клиенту IPC-ответ, содержащий выходные параметры метода.
Вызов метода службы сервера
IPC‑каналы
Чтобы два процесса могли обмениваться IPC-сообщениями, между ними должен быть установлен IPC-канал. IPC-канал имеет клиентскую и серверную стороны. Один процесс может использовать одновременно несколько IPC-каналов. При этом для одних IPC-каналов процесс может быть сервером, а для других IPC-каналов этот же процесс может быть клиентом.
В KasperskyOS предусмотрено два способа создания IPC-каналов:
- Статический способ предполагает создание IPC-каналов при запуске решения. Статическое создание IPC-каналов выполняется инициализирующей программой.
- Динамический способ позволяет уже запущенным процессам установить IPC-каналы между собой.
Управление IPC
Модуль безопасности Kaspersky Security Module интегрирован в механизм, реализующий IPC. Содержимое IPC-сообщений для всех возможных взаимодействий известно модулю безопасности, так как для генерации исходного кода этого модуля используются IDL-, CDL-, EDL-описания. Это позволяет модулю безопасности проверять взаимодействие процессов на соответствие политике безопасности решения.
Ядро KasperskyOS обращается к модулю безопасности каждый раз, когда один процесс отправляет IPC-сообщение другому процессу. При этом сценарий работы модуля безопасности включает следующие шаги:
- Модуль безопасности проверяет, что IPC-сообщение соответствует вызываемому методу службы (проверяются размер IPC-сообщения, а также размер и размещение некоторых структурных элементов).
- Если IPC-сообщение некорректно, модуль безопасности выносит решение "запрещено", и следующий шаг сценария не выполняется. Если IPC-сообщение корректно, выполняется следующий шаг сценария.
- Модуль безопасности проверяет, что правила безопасности разрешают запрашиваемое действие. Если это так, модуль безопасности выносит решение "разрешено", в противном случае он выносит решение "запрещено".
Ядро выполняет решение модуля безопасности, то есть доставляет IPC-сообщение процессу-получателю либо отклоняет его доставку. В случае отклонения доставки IPC-сообщения процесс-отправитель получает код ошибки через код возврата системного вызова Call()
или Reply()
.
Проверке подлежат как IPC-запросы, так и IPC-ответы. На рисунке ниже показана схема управляемого обмена IPC-сообщениями между клиентом и сервером.
Управляемый обмен IPC-сообщениями между клиентом и сервером
В началоТранспортный код для IPC
Чтобы реализовать взаимодействие процессов, необходим транспортный код, отвечающий за корректное создание IPC-сообщений, их упаковку, отправку и распаковку. Разработчику решения на базе KasperskyOS нет необходимости самостоятельно писать транспортный код. Вместо этого можно использовать специальные инструменты и библиотеки, поставляемые в составе KasperskyOS SDK.
Транспортный код для разрабатываемых компонентов решения
Разработчик компонента решения на базе KasperskyOS может сгенерировать транспортный код на основе IDL-, CDL-, EDL-описаний, относящихся к этому компоненту. Для этого в составе KasperskyOS SDK поставляется компилятор nk-gen-c
. Компилятор nk-gen-c
позволяет генерировать транспортные методы и типы для использования как клиентом, так и сервером.
Транспортный код для поставляемых компонентов решения
Большинство компонентов, поставляемых в составе KasperskyOS SDK, может быть использовано в решении как локально, то есть путем статической компоновки с другими компонентами, так и через IPC.
Чтобы использовать поставляемый компонент через IPC, в составе KasperskyOS SDK есть следующие транспортные библиотеки:
- клиентская библиотека компонента решения, которая преобразует локальные вызовы в IPC-запросы;
- серверная библиотека компонента решения, которая преобразует IPC-запросы в локальные вызовы.
Клиентская библиотека компонуется с кодом клиента (с кодом компонента, который будет использовать поставляемый компонент). Серверная библиотека компонуется с реализацией поставляемого компонента (см. рис. ниже).
Использование поставляемого компонента решения через IPC
В началоIPC между процессом и ядром
Механизм IPC используется при взаимодействии процессов с ядром KasperskyOS, то есть процессы обмениваются с ядром IPC-сообщениями. Ядро предоставляет службы, а процессы используют их. Процессы обращаются к службам ядра, вызывая функции библиотеки libkos
(непосредственно или через другие библиотеки). Клиентский транспортный код для взаимодействия процесса с ядром сосредоточен в этой библиотеке.
Разработчику решения не требуется создавать IPC-каналы между процессами и ядром, так как эти каналы создаются автоматически при создании процессов. (Для организации взаимодействия между процессами разработчику решения нужно позаботиться о создании IPC-каналов между ними.)
Модуль безопасности Kaspersky Security Module принимает решения о взаимодействии процессов с ядром так же, как и о взаимодействии процессов между собой. (В составе KasperskyOS SDK есть IDL-, CDL-, EDL-описания для ядра, которые используются для генерации исходного кода модуля безопасности.)
В началоУправление доступом к ресурсам
Виды ресурсов
В KasperskyOS есть два вида ресурсов:
- Системные ресурсы, которыми управляет ядро. К ним относятся, например, процессы, регионы памяти, прерывания.
- Пользовательские ресурсы, которыми управляют процессы. Примеры пользовательских ресурсов: файлы, устройства ввода-вывода, накопители данных.
Дескрипторы
Как системные, так и пользовательские ресурсы идентифицируются дескрипторами (англ. handles). Процессы (и ядро KasperskyOS) могут передавать дескрипторы другим процессам. Получая дескриптор, процесс получает доступ к ресурсу, который этот дескриптор идентифицирует. То есть процесс, получивший дескриптор, может запрашивать операции над ресурсом, указывая в запросе полученный дескриптор. Один и тот же ресурс может идентифицироваться несколькими дескрипторами, которые используют разные процессы.
Идентификаторы безопасности (SID)
Для системных и пользовательских ресурсов ядро KasperskyOS назначает идентификаторы безопасности. Идентификатор безопасности (англ. Security Identifier, SID) – это глобальный уникальный идентификатор ресурса (то есть у ресурса есть только один SID, а дескрипторов может быть несколько). Модуль безопасности Kaspersky Security Module идентифицирует ресурсы по их SID.
При передаче IPC-сообщения, содержащего дескрипторы, ядро так изменяет это сообщение, что на этапе проверки модулем безопасности оно содержит значения SID вместо дескрипторов. Когда IPC-сообщение будет доставлено получателю, оно будет содержать дескрипторы.
У ядра так же, как и у ресурсов, есть SID.
Контекст безопасности
Технология Kaspersky Security System позволяет применять механизмы безопасности, которые принимают на вход значения SID. При применении таких механизмов модуль безопасности Kaspersky Security Module различает ресурсы (и ядро KasperskyOS) и связывает с ними контексты безопасности. Контекст безопасности представляет собой данные, ассоциированные с SID, которые используются модулем безопасности для принятия решений.
Содержимое контекста безопасности зависит от используемых механизмов безопасности. Контекст безопасности может содержать, например, состояние ресурса, уровни целостности субъектов и/или объектов доступа. Если контекст безопасности хранит состояние ресурса, это позволяет, например, разрешить выполнять операции над ресурсом, если только этот ресурс находится в каком-либо конкретном состоянии.
Модуль безопасности может изменить контекст безопасности, когда принимает решение. Например, могут измениться сведения о состоянии ресурса (модуль безопасности проверил по контексту безопасности, что файл находится в состоянии "не используется", разрешил открыть файл на запись и записал в контекст безопасности этого файла новое состояние "открыт на запись").
Управление доступом к ресурсам ядром KasperskyOS
Ядро KasperskyOS управляет доступом к ресурсам одновременно двумя взаимодополняющими способами: выполняя решения модуля безопасности Kaspersky Security Module и реализуя механизм безопасности на основе мандатных ссылок (англ. Object Capability, OCap).
Каждый дескриптор ассоциируется с правами доступа к идентифицируемому им ресурсу, то есть является мандатной ссылкой (англ. capability) в терминах OCap. Получая дескриптор, процесс получает права доступа к ресурсу, который этот дескриптор идентифицирует. Например, правами доступа могут быть: право на чтение, право на запись, право на передачу другому процессу возможности выполнять операции над ресурсом (право на передачу дескриптора).
Процессы, которые используют ресурсы, предоставляемые ядром или другими процессами, являются потребителями ресурсов. Когда потребитель ресурсов открывает системный ресурс, ядро передает ему дескриптор, ассоциированный с правами доступа к этому ресурсу. Эти права доступа назначаются ядром. Перед выполнением операции над системным ресурсом, которую запрашивает потребитель, ядро проверяет, что у потребителя достаточно прав. Если это не так, ядро отклоняет запрос потребителя.
В IPC-сообщении дескриптор передается вместе с маской прав. Маска прав дескриптора представляет собой значение, биты которого интерпретируются как права доступа к ресурсу, который этот дескриптор идентифицирует. Потребитель может узнать свои права доступа к системному ресурсу из маски прав дескриптора этого ресурса. Ядро использует маску прав дескриптора для проверки, что запрашиваемые потребителем операции над системным ресурсом разрешены.
Модуль безопасности может проверять маски прав дескрипторов и по результатам проверки разрешать или запрещать взаимодействия процессов между собой и с ядром, связанные с доступом к ресурсам.
Ядро запрещает расширение прав доступа при передачи дескрипторов между процессами (при передаче дескриптора права доступа могут быть только ограничены).
Управление доступом к ресурсам поставщиками ресурсов
Процессы, которые управляют пользовательскими ресурсами и доступом к этим ресурсам для других процессов, являются поставщиками ресурсов. (Поставщиками ресурсов являются, например, драйверы.) Поставщики управляют доступом к ресурсам двумя взаимодополняющими способами: выполняя решения модуля безопасности Kaspersky Security Module и используя механизм OCap, который предоставляется ядром KasperskyOS.
Если обращение к ресурсу осуществляется по его имени (например, для открытия), то модуль безопасности не может быть использован для управления доступом к ресурсу без участия поставщика. Это связано с тем, что модуль безопасности идентифицирует ресурс по SID, а не по имени. В таких случаях поставщик находит у себя дескриптор ресурса по имени ресурса и передает этот дескриптор (вместе с другими данными, например, с требуемым состоянием ресурса) модулю безопасности через интерфейс безопасности (модуль безопасности получает SID, соответствующий переданному дескриптору). Модуль безопасности принимает решение и возвращает его поставщику. Поставщик выполняет решение модуля безопасности.
Когда потребитель ресурсов открывает пользовательский ресурс, поставщик передает ему дескриптор, ассоциированный с правами доступа к этому ресурсу. При этом поставщик решает, какими именно правами доступа к ресурсу будет обладать потребитель. Перед выполнением операции над пользовательским ресурсом, которую запрашивает потребитель, поставщик проверяет, что у потребителя достаточно прав. Если это не так, поставщик отклоняет запрос потребителя.
Потребитель может узнать свои права доступа к пользовательскому ресурсу из маски прав дескриптора этого ресурса. Поставщик использует маску прав дескриптора для проверки, что запрашиваемые потребителем операции над пользовательским ресурсом разрешены.
Структура маски прав дескриптора
Маска прав дескриптора имеет размер 32 бита и состоит из общей и специальной части. Общая часть описывает права, неспецифичные для любых ресурсов (флаги этих прав определены в заголовочном файле services/ocap.h
). Например, в общей части находится флаг OCAP_HANDLE_TRANSFER
, который определяет право на передачу дескриптора. Специальная часть описывает права, специфичные для пользовательского или системного ресурса. Флаги прав специальной части для системных ресурсов определены в заголовочном файле services/ocap.h
. Структура специальной части для пользовательских ресурсов определяется поставщиком ресурсов с использованием макроса OCAP_HANDLE_SPEC()
, который определен в заголовочном файле services/ocap.h
. Поставщику ресурсов необходимо экспортировать публичные заголовочные файлы с описанием структуры специальной части.
При создании дескриптора системного ресурса маска прав задается ядром KasperskyOS, которое применяет маски прав из заголовочного файла services/ocap.h
. Применяются маски прав с именами вида OCAP_*_FULL
(например, OCAP_IOPORT_FULL
, OCAP_TASK_FULL
, OCAP_FILE_FULL
) и вида OCAP_IPC_*
(например, OCAP_IPC_SERVER
, OCAP_IPC_LISTENER
, OCAP_IPC_CLIENT
).
При создании дескриптора пользовательского ресурса маска прав задается пользователем.
При передаче дескриптора маска прав задается пользователем, но передаваемые права доступа не могут быть повышены относительно прав доступа, которые имеет процесс.
В началоСтруктура и запуск решения на базе KasperskyOS
Структура решения
Загружаемый в аппаратуру образ решения на базе KasperskyOS содержит следующие файлы:
- образ ядра KasperskyOS;
- файл с исполняемым кодом модуля безопасности Kaspersky Security Module;
- исполняемый файл инициализирующей программы;
- исполняемые файлы всех остальных компонентов решения (например, прикладных программ, драйверов);
- файлы, используемые программами (например, файлы с параметрами, шрифтами, графическими и звуковыми данными).
Для хранения файлов в образе решения используется файловая система ROMFS.
Запуск решения
Запуск решения на базе KasperskyOS происходит следующим образом:
- Загрузчик запускает ядро KasperskyOS.
- Ядро находит и загружает модуль безопасности (как модуль ядра).
- Ядро запускает инициализирующую программу.
- Инициализирующая программа запускает все остальные программы, входящие в решение.