Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Обучение от Mail.Ru Group.
Онлайн-университет
для программистов с
гарантией трудоустройства.
Набор открыт!
2010 г.

Прозрачный механизм удаленного обслуживания системных вызовов

Яковенко П.Н.
Институт системного программирования РАН (ИСП РАН), Москва

Содержание

1. Введение
2. Архитектура системы
2.1. Компоненты системы и их взаимодействие
3. Прозрачное обслуживание системных вызовов
3.1. Точка обслуживания системного вызова
4. Производительность системы
5. Заключение
Литература

Аннотация

В статье рассматривается подход к удаленному обслуживанию системных вызовов, не требующий модификации кода пользовательского приложения и операционной системы. Использование технологии аппаратной виртуализации для перехвата системных вызовов, чтения их параметров и записи результатов позволяет делегировать обслуживание перехваченных системных вызовов другой системе: виртуальной, выполняющейся на этом же физическом компьютере, или даже другой машине в сети. Возможность предоставлять отдельным процессам контролируемый доступ к ресурсам, к которым сама операционная система доступа не имеет, позволяет эффективно решать некоторые задачи компьютерной безопасности.

1. Введение

Решение некоторых задач компьютерной безопасности основано на ограничении доступа программного кода к различного рода ресурсам, в частности, сетевым ресурсам и файловой системе. Предоставив доступ к этим ресурсам только отдельным доверенным программам, можно гарантировать (при дополнительном контроле целостности этих программ) выполнение важных требований по безопасности, среди которых следует отметить предотвращение утечки критически важной информации через различные каналы передачи данных: сетевое соединение, переносные (USB) накопители и др.

Современные операционные системы (ОС) предоставляют широкие возможности по управлению доступом процессов к ресурсам компьютера. Однако недостаточная надежность массовых ОС (таких как Windows, Linux и др.) [1] делает актуальной задачу разработки независимых от ОС (ортогональных к ней) программных средств защиты информации. Такие средства защиты могут быть реализованы с использованием технологии аппаратной виртуализации, когда защищаемая система выполняется в аппаратной виртуальной машине (ВМ), а система защиты размещается в теле монитора виртуальных машин (также называемого гипервизором) [2,4]. Функционирование гипервизора на более высоком аппаратном уровне привилегий позволяет полностью контролировать выполнение как кода ОС, так и пользовательских программ, оставаясь при этом аппаратно защищенным от вредоносного воздействия со стороны кода в ВМ, в том числе, кода, выполняющегося в привилегированном режиме.

Пользовательский процесс в современных ОС не имеет прямого доступа к аппаратным ресурсам; операционная система представляет процессу некоторую абстрактную модель аппаратного обеспечения, взаимодействие с которой осуществляется посредством набора операций – системных вызовов (СВ). В частности, для установления сетевого соединения с удаленным компьютером и передачи ему данных процессу необходимо выполнить в заданном порядке несколько вполне определенных системных вызовов (socket, connect, send и т.п.).

В наших работах [2,3] было показано, как при помощи разделения полномочий по обслуживанию ресурсов между виртуальными машинами и делегирования обслуживания системных вызовов от одной виртуальной машины другой могут быть решены некоторые задачи компьютерной безопасности. Предложенные решения в целом базируются на схеме, изображенной на рисунке 1. Гипервизор обеспечивает одновременное выполнение двух изолированных друг от друга виртуальных машин. Обе ВМ работают под управлением одной и той же операционной системы. Первая ВМ — вычислительная — является основной. Пользователь может работать с ней в диалоговом режиме.

Оборудование, через которое осуществляется доступ к контролируемым ресурсам (ресурсы сети Интернет на рис. 1), физически отключается гипервизором от вычислительной ВМ. Это оборудование управляется другой — сервисной — виртуальной машиной, которая, вообще говоря, может выполняться скрытым для пользователя образом в фоновом режиме. Системные вызовы отдельных (доверенных) процессов перехватываются гипервизором, и те из них, которые относятся к контролируемым ресурсам, передаются на обслуживание (обслуживаются удаленно) в сервисную ВМ. Заметим, что обслуживание этих вызовов внутри вычислительной ВМ неминуемо приведет к ошибке в силу отсутствия у нее возможностей (оборудования) осуществить доступ к соответствующим ресурсам. Остальные системные вызовы доверенных процессов, а также все системные вызовы других процессов, обслуживаются средствами ОС в вычислительной ВМ.


Рисунок 1. Делегирование системных вызовов другой виртуальной машине

При перехвате системного вызова гипервизор может проконтролировать допустимость контекста, из которого выполняется запрос на системный вызов, т.е. разрешен ли данному процессу доступ к такой категории ресурсов, и выполнять удаленное обслуживание вызова только в случае успешного прохождения проверки. Анализируя параметры вызова, гипервизор может также осуществлять более тонкий контроль доступа к ресурсу, например, разрешать сетевой доступ только к ограниченному числу компьютеров в сети, имеющих заданные адреса.

В данной работе описывается архитектура и детали реализации механизма удаленного выполнения системных вызовов, используемого в системе безопасности, которая представлена в работе [3]. В ней контролируемыми ресурсами являются исключительно ресурсы сети Интернет. Как следствие, реализация, рассматриваемая в данной работе, допускает удаленное обслуживание только тех системных вызовов, которые могут быть использованы при сетевом взаимодействии через сокеты. Однако, учитывая общность представления сокетов и файлов для пользовательского процесса в виде дескрипторов файлов и, как следствие, общность многих системных вызовов, рассматриваемый механизм в целом пригоден также для тех сценариев, когда контролируемым ресурсом является файловая система.

Отдельные компоненты системы, рассматриваемой в данной работе, могут также использоваться для эффективного решения тех задач, в которых требуется выполнять трассировку системных вызовов. Дело в том, что штатные механизмы трассировки в ОС Linux (ptrace) базируются на сигналах, посылаемых ядром ОС процессу-монитору (отладчику) при выполнении отлаживаемым процессом системного вызова, что приводит к частому переключению контекста процессов (монитора и трассируемого процесса). Кроме того, чтение данных из адресного пространства трассируемого процесса возможно только порциями по 4 байта. Размещение монитора процессов на уровне гипервизора позволяет устранить указанные ограничения.

Задача удаленного выполнения системных вызовов рассматривается также в рамках проекта VirtualSquare [6]. Отличие предлагаемого нами подхода состоит в использовании технологии аппаратной виртуализации для перехвата системных вызовов. Кроме того, в работе [6] подмножество системных вызовов, исполняемых удаленно, задается жестко, в то время как в нашем подходе решение об удаленном выполнении системного вызова принимается, исходя из дескриптора ресурса, к которому обращается процесс. В ряде случаев системный вызов надо одновременно выполнять в обеих системах (локальной и удаленной) с последующим объединением результатов, и этот вопрос также рассмотрен в данной работе.

Механизм удаленного выполнения системных вызовов близка механизму удаленного выполнения процедур [7], широко применяемому в распределенных программных системах, в частности, в сетевой файловой системе NFS [8]. Принципиальное отличие предлагаемого нами решения состоит в отсутствии необходимости модификации (в том числе, перекомпиляции) кода приложения и операционной системы для обслуживания системных вызовов в другой системе.

Статья организована следующим образом. В разделе 2 представлен краткий обзор технологии аппаратной виртуализации и изложена общая архитектура системы и ее компонент. В разделе 3 детально рассмотрены принципы работы системы и обработка различных сценариев доступа к ресурсам. В разделе 4 представлены результаты анализа производительности системы как на синтетических тестах, так и на реальных приложениях. В разделе 5 подводятся итоги работы.

2. Архитектура системы

Технология виртуализации позволяет выполнять ОС в аппаратной виртуальной машине (ВМ) под управлением сравнительно небольшой по размеру системной программы – монитора виртуальных машин (гипервизора) [5]. Аппаратная виртуальная машина представляет собой эффективный изолированный дубликат реальной машины, и выполнение в ней операционной системы не требует внесения каких-либо изменений в код ОС. Гипервизор полностью контролирует взаимодействие ОС в ВМ с оборудованием и может обеспечить надежную изоляцию ВМ, опираясь на аппаратные механизмы защиты.

Функционирование гипервизора и организация выполнения виртуальной машины во многом схожи с тем, как операционная система управляет выполнением пользовательских процессов. Гипервизор инициализирует системные структуры данных, необходимые оборудованию, и выполняет специальную инструкцию VMRUN, реализующую запуск ВМ и передачу управления соответствующей инструкции кода ОС. При возникновении аппаратного события (прерывания) или при выполнении операционной системой привилегированной инструкции (в том числе, системного вызова) выполнение ВМ прерывается, и управление передается гипервизору на следующую инструкцию после VMRUN. После обработки перехваченного события гипервизор возобновляет выполнение ВМ.

Архитектура системы выглядит следующим образом. Гипервизор реализует одновременное выполнение двух виртуальных машин (рис. 1), работающих под управлением одинаковой операционной системы Linux. Отметим, что операционные системы в виртуальных машинах могут быть разными, если гипервизор при этом обеспечивает необходимое преобразование системных вызовов между исходной и целевой операционными системами. В вычислительной ВМ выполняются процессы пользователя, среди которых выделен набор доверенных процессов. Гипервизор предоставляет доверенным процессам привилегию доступа к ресурсам, обслуживаемым ОС в сервисной ВМ (контролируемым ресурсам); другие процессы доступа к этим ресурсам не имеют. Доступ доверенных процессов к контролируемым ресурсам производится посредством перехвата их системных вызовов и, при необходимости, их перенаправления для обслуживания в сервисную ВМ.

Обе виртуальные машины выполняются асинхронно, и вычислительная ВМ не блокируется на время удаленного обслуживания системного вызова. В это время процесс, инициировавший системный вызов, находится в состоянии ожидания, а все остальные процессы в вычислительной ВМ продолжают выполняться нормальным образом. Более того, система допускает одновременное обслуживание нескольких удаленных системных вызовов, поступающих от разных доверенных процессов.

При перехвате запроса процесса на выполнение системного вызова гипервизор копирует все входные параметры вызова в собственную область памяти и передает запрос на обслуживание вызова в сервисную ВМ. Системный вызов может быть блокирующим (например, read), и время его выполнения в общем случае не ограничено. Для избегания блокировки всей вычислительной ВМ на время обслуживания вызова процесс, инициировавший системный вызов, переводится в состояние ожидания, позволяя другим процессам продолжить свое выполнение. При поступлении из сервисной ВМ результатов обслуживания вызова гипервизор прерывает выполнение вычислительной ВМ, выводит процесс из состояния ожидания и копирует результаты в его адресное пространство. Пребывание процесса в состоянии ожидания реализуется штатными средствами ОС в ВМ без вмешивательства в работу механизма управления процессами в операционной системе.

Внутри сервисной ВМ выполняется набор процессов – делегатов, являющихся экземплярами специализированной программы. Каждый из делегатов обслуживает запросы на системные вызовы отдельного доверенного процесса из вычислительной ВМ, причем иерархия делегатов в сервисной ВМ соответствует иерархии доверенных процессов в вычислительной ВМ. Новый делегат порождается каждый раз при создании нового доверенного процесса и уничтожается при завершении работы этого процесса.

Выполнение делегата состоит в циклическом исполнении системных вызовов, поступивших от соответствующего доверенного процесса, и извещении гипервизора о результатах (делегат, в отличие от доверенного процесса, знает о существовании гипервизора). Делегаты получают запрос на выполнение системного вызова от специализированного процесса – диспетчера – через механизм межпроцессного взаимодействия (очередь сообщений). Все запросы, поступающие от гипервизора, проходят через процесс-диспетчер. Диспетчер отслеживает соответствия между идентификаторами доверенных процессов и идентификаторами делегатов и, получив запрос от гипервизора на обслуживание системного вызова некоторого доверенного процесса, перенаправляет его соответствующему делегату. Дальнейшее обслуживание запроса целиком производится делегатом без участия диспетчера. В частности, делегат самостоятельно выполняет доступ к хранилищу, извещает гипервизор о результатах системного вызова и т.д.

Иерархия каждого доверенного процесса восходит к служебному процессу, являющемуся экземпляром специальной пользовательской программы – монитора. Первый доверенный процесс всегда порождается монитором. Монитор, в свою очередь, не является доверенной программой. Задача монитора состоит в запуске нового (в том числе, первого) доверенного процесса и отслеживании его состояния, а также состояния всех его дочерних процессов, часть из которых могут быть доверенными, а часть – нет.

Монитор реализован на базе стандартного интерфейса отладки ptrace. Монитор перехватывает события порождения и завершения процессов, в том числе, аварийного, например, при получении процессом сигнала, для которого у него не зарегистрирован обработчик. При выполнении одним из дочерних процессов системного вызова fork или exec монитор определяет, требуется ли данному процессу выполнение в доверенном режиме (т.е. будет ли новый процесс доверенным), и, в случае необходимости, запрашивает гипервизор о его включении для процесса. При завершении доверенного процесса монитор также извещает об этом гипервизор.


Рисунок 2. Паспорт доверенной задачи.

Монитор определяет, для каких процессов следует запрашивать доверенный режим выполнения, основываясь на специальном конфигурационном файле – паспорте задачи (рис. 2). Паспорт содержит имя изначально запускаемой программы (не обязательно доверенной) и список передаваемых ей параметров командной строки. Основная часть паспорта состоит из набора шаблонов для идентификации новых процессов, для которых следует запрашивать включение доверенного режима. Для каждого шаблона указывается уникальный идентификатор доверенной программы, зарегистрированной в гипервизоре. В гипервизоре для каждой зарегистрированной программы перечислен набор хэш-кодов, позволяющих проверить, что запускаемая программа действительно является одной из доверенных [1].

При выполнении дочерним процессом системного вызова exec монитор производит поиск шаблона, который может быть сопоставлен имени запускаемой программы, и, в случае успеха, делает запрос гипервизору на включение доверенного режима, сообщая ему идентификатор процесса (PID) и идентификатор соответствующей доверенной программы (например, 444 на рис. 2). Гипервизор проверяет допустимость включения доверенного режима для процесса в данной точке выполнения и, в случае соблюдения контекстных условий безопасности [1], активирует доверенный режим. При перехвате системного вызова fork монитор активирует доверенный режим для дочернего процесса только в том случае, если родительский процесс выполняется в доверенном режиме. Следует отметить, что гипервизор контролирует корректность выполнения запроса, т.е. что родительский процесс выполняется в доверенном режиме и действительно выполнил системный вызов fork.

Паспорт задачи также содержит адрес произвольной инструкции RET в коде доверенной программы. Монитор при помощи модуля (расширения) ядра в вычислительной ВМ регистрирует для доверенного процесса по этому адресу обработчик сигнала, не используемого процессом. Посылка такого сигнала доверенному процессу приведет просто к выполнению инструкции RET. Этот сигнал используется для отмены выполнения системного вызова в вычислительной ВМ в тех случаях, когда для корректного обслуживания системного вызова его требуется выполнять в обеих виртуальных машинах (см. раздел 3.1).

2.1. Компоненты системы и их взаимодействие

Удаленное обслуживание системных вызовов реализуется гипервизором совместно с другими компонентами системы, функционирующими в обеих ВМ – вычислительной и сервисной. Компоненты функционирует как в пользовательском пространстве (монитор, диспетчер, делегаты), так и в пространстве ядра ОС (загружаемые модули ядра ОС).

В ходе инициализации системы в ядро ОС в вычислительной и сервисной ВМ динамически загружаются модули ядра. Каждый модуль выделяет непрерывное пространство физической памяти (по умолчанию 1 страницу размером 4Кб) для организации кольцевого буфера, регистрирует несколько обработчиков прерываний, при помощи которых гипервизор извещает виртуальную машину о событиях, требующих обработки и сообщает эту информацию (адрес буфера и номера прерываний) гипервизору посредством гипервызова. В сервисной ВМ также запускается пользовательский процесс – диспетчер.

В ходе удаленного обслуживания системного вызова компоненты системы взаимодействуют между собой, причем механизмы взаимодействия реализованы по-разному (рис. 3). Реализация механизма взаимодействия некоторой пары компонент определяется уровнями привилегий, на которых они выполняются. Любая компонента может обратиться к гипервизору посредством гипервызова. Выполнение ВМ при этом прерывается, и управление передается гипервизору. Синхронный характер этого обращения позволяет передавать параметры гипервызова аналогично тому, как пользовательский процесс передает параметры ядру ОС при выполнении системного вызова: числовые параметры и адреса областей памяти передаются через регистры, при необходимости гипервизор читает область памяти виртуальной машины по указанным адресам и извлекает из нее (или записывает в нее) дополнительную информацию.

Пользовательский процесс (диспетчер или монитор) обращается за сервисом к модулю ядра посредством системных вызовов. Модуль ядра регистрирует в ОС специальное логическое устройство, видимое на уровне файловой системы как файл. Операции доступа к этому файлу (системные вызовы read/write/ioctl) вызывают соответствующие функции в драйвере логического устройства. Драйвер обрабатывает запрос процесса и возвращает управление ему. Если операция блокирующая, то драйвер может приостановить выполнение процесса до тех пор, пока он не сможет обслужить запрос. Модуль ядра обращается к пользовательскому процессу посредством посылки сигналов.


Рисунок 3. Взаимодействие компонент системы.

Взаимодействие пользовательских процессов друг с другом (например, диспетчера с делегатами) осуществляется при помощи стандартных механизмов межпроцессного взаимодействия (IPC) ОС Linux – разделяемой памяти, очереди сообщений и пр. Все делегаты в сервисной ВМ являются членами одной иерархии процессов, восходящей к диспетчеру, что облегчает контроль создания разделяемых между процессами ресурсов: ресурс, создаваемый родителем, доступен потомку, а ресурс, создаваемый потомком, не доступен родителю.

Наиболее сложной является ситуация, в которой гипервизору требуется известить компоненты в виртуальной машине о некотором событии. Для этого гипервизор использует возможность, предоставляемую аппаратурой виртуализации, вбрасывать прерывания и исключительные ситуации в виртуальную машину посредством соответствующих полей в управляющей структуре VMCB ВМ. Тогда после возобновления ВМ аппаратура обеспечивает ей доставку прерывания непосредственно перед выполнением первой инструкции в ВМ. В результате вброса прерывания ОС передает управление на обработчик (вектор) данного прерывания, зарегистрированный модулем ядра в таблице обработчиков прерываний в процессе инициализации системы.

Параметры события передаются через кольцевой буфер. Буфер физически расположен в области памяти ВМ и разделяется между гипервизором и ВМ по схеме «поставщик – потребитель». Буфер представляет собой замкнутый в кольцо массив структур данных (фиксированного размера), голова которого сдвигается по мере выемки запросов из буфера, а хвост — по мере помещения запросов в буфер. Если буфер переполнен, то доставка запроса откладывается до тех пор, пока в буфере не освободится место, т.е. пока ОС не обработает хотя бы одно из ранее сгенерированных событий. Запросы, ожидающие доставки в ВМ, накапливаются в очереди в памяти гипервизора.

Структура данных, представляющая собой элемент кольцевого буфера, едина для всех событий и включает поля для всех возможных параметров фиксированной длины. Параметры переменной длины передаются через отдельный буфер переменного размера, расположенный в памяти гипервизора — хранилище. Координаты параметра переменной длины — смещение от начала хранилища и длина — специфицируются в структуре данных кольцевого буфера. Например, для системного вызова write структура включает 3 поля: идентификатор файлового дескриптора, начало (смещение) буфера в хранилище и длина буфера. Для каждого доверенного процесса гипервизор поддерживает отдельный экземпляр хранилища.

При получении запроса, содержащего параметры переменной длины, код в ВМ, которому предназначается этот запрос (например, делегат), выполняет гипервызов на доступ к хранилищу, передавая координаты запрашиваемого параметра и адрес буфера в собственной памяти, в который должны быть записаны данные из хранилища. Гипервизор обслуживает запрос и возобновляет выполнение ВМ. При этом он контролирует, что границы запрашиваемого блока данных не выходят за пределы хранилища. Доступ к хранилищу возможен как по чтению, так и по записи.

При необходимости передать запрос одной из компонент внутри ВМ гипервизор ожидает, когда выполнение ВМ будет прервано по тому или иному событию (например, по таймеру), и анализирует, может ли он послать запрос в данной точке. Для этого в кольцевом буфере должно быть свободное место, а прерывания не должны быть маскированы в ВМ. Если это так, то гипервизор (при необходимости) заполняет хранилище параметрами переменной длины, формирует структуру данных для кольцевого буфера, указывая в ней координаты параметров в хранилище, записывает сформированный запрос в буфер и вбрасывает прерывание. Вброс прерывания передает управление обработчику прерывания, который анализирует содержимое буфера и либо обслуживает его самостоятельно, либо передает запрос другой компоненте, отвечающей за его обслуживание (например, диспетчеру).

Если получателем запроса гипервизора является пользовательский процесс (например, диспетчер), то доставка такого запроса производится транзитом через драйвер логического устройства. Пользовательский процесс обращается к файлу устройства и, в случае отсутствия запроса на данный момент, переходит в состояние ожидания. При поступлении запроса от гипервизора обработчик прерывания извещает об этом драйвер устройства. Тот, в свою очередь, читает запрос из кольцевого буфера, копирует его в память процесса и выводит его из состояния ожидания. Если запрос содержит параметры переменной длины, то доступ к хранилищу осуществляется тем пользовательским процессом, который непосредственно обслуживает запрос.

Содержание Вперёд

Новости мира IT:

Архив новостей

Последние комментарии:

Релиз ядра Linux 4.14  (9)
Среда 22.11, 19:04
Loading

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...