Современная электроника №2/2019
СОВРЕМЕННЫЕ ТЕХНОЛОГИИ 24 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА ◆ № 2 2019 виде множества частей, каждая в своём сервере. Открытые файлы и связанные с ними атрибуты хранятся в сервере, реализующем VFS (Virtual File System), сокеты – в сетевом сервере и так далее (см. рис. 3). Например, системный вызов fork, который является единственным спо- собом создания нового процесса в классическом UNIX, должен создать полную копию выполняемого процесса за исключением некоторых специаль- но оговорённых вещей. То есть новый процесс должен выполнять тот же код, иметь доступ к тем же данным и иметь те же самые открытые файлы. Помимо очевидных проблем с пред- сказуемостью: данные потомка долж- ны копироваться из предка при первом обращении к ним, данный системный вызов требует создания полной копии всего состояния. Очевидно, что в слу- чае классического микроядра это тре- бует дублирования состояния процес- са в каждом из серверов. Учитывая, что сами серверы работают асинхронно, а к тому же являются ещё и потенци- ально ненадёжными, реализация тако- го функционала выливается в серьёз- ную проблему, тогда как в классических монолитных ОС это делается доволь- но просто. С ИСТЕМНЫЕ ПРОЦЕССЫ Способ, который применяется для решения этой проблемы, заключает- ся в том, что состояние пользователь- ских процессов хранится в специаль- ном системном процессе, который выполняет роль UNIX-сервера. В этом случае состояние процессов хранится в одном месте и его относи- тельно просто скопировать. В этом же процессе может храниться дерево фай- ловой системы (которое является гло- бальным для всех процессов в UNIX) и тому подобное. В QNX роль такого процесса выполняет Process manager (procnto), в задачи которого входит управление процессами, памятью, загрузкой образов исполняемых фай- лов и поддержка глобального простран- ства имён [3]. В MINIX также есть ана- логичный процесс (Process manager), являющийся, наряду с файловой систе- мой, обязательным системным компо- нентом [4]. Подобные системы являются более надёжными, нежели традиционные монолитные ядра, хотя бы по той при- чине, что драйверы устройств являются основным источником ошибок, и они в данных архитектурах полностью изо- лированы. Тем не менее, побочным эффектом такой архитектуры с систем- ным процессом является также и то, что этот процесс входит в доверенную базу системы наравне с микроядром. Ошибки и уязвимости в этом процес- се могут вести к компрометации всей системы. А учитывая, что он содержит практически весь функционал тради- ционного UNIX, можно предположить, что основной источник ошибок будет содержаться именно в этом критиче- ском процессе. Статистика показывает верность этого предположения [5, 6]. По данным MWRLabs, уязвимости самого микроядра QNX составляют менее 10% всех найденных уязвимостей. Львиная доля ошибок заключена в реализации UNIX-функций вроде setuid, загрузчи- ке образов и т.д. Таким образом, даже при наличии полностью корректно- го микроядра, нельзя делать выводы относительно надёжности систем на его основе. Что касается различных вариантов верифицированных микроядер L4, то, помимо наличия критических про- цессов, для упрощения формальной верификации используется подход, при котором ядро является вытесняе- мым лишь частично, поэтому не может использоваться там, где важна предска- зуемость и низкая латентность преры- ваний. FX-RTOS С 2010 года компания Eremex разра- батывает собственную микроядерную ОСРВ FX-RTOS, которая призвана в какой-то степени решить эти пробле- мы. Подход, предлагаемый FX-RTOS, основан на известном правиле «80/20», которое переформулируется в виде «реализация 80% функционала тра- диционного UNIX используя 20% кода» плюс отказ от функций, нега- тивно влияющих на безопасность. Отказ от хранимого в единственном месте глобального состояния прило- жений позволил реализовать систему без критических процессов. Реализо- вав приложение или сервер, работа- ющие поверх микроядра и выполня- ющие некоторую важную функцию, пользователь может быть уверен, что даже в случае аварийного завершения всех прочих процессов, это приложе- ние не только продолжит работать, но и будут соблюдены его требования к работе в реальном времени. Нет необ- ходимости принимать на веру надёж- ность инфраструктурных компонен- тов, если они не используются. Более того, в рамках одной системы можно допустить сосуществование «надёж- ной» и «ненадёжной» инфраструкту- ры. Например, ответственное прило- жение может использовать свой соб- ственный выделенный стек UDP/IP (который гораздо проще полноценно- го TCP/IP), работающий на отдельном аппаратном интерфейсе, тогда как прочие приложения могут использо- вать стандартный сетевой стек. Таким образом, достигаемый уровень изо- ляции и независимости приложе- ний сравним с таковым при исполь- зовании виртуализации, но при этом реализуемый силами микроядра, без использования гипервизоров и аппа- ратной поддержки соответствующих технологий. Особое внимание уделяется также защите от атак, приводящих к отказу в обслуживании. В частности, все ресур- сы процесса, которые могут быть выде- лены статически, выделяются статиче- ски на этапе его запуска и впоследствии не изменяются. Тем самым гарантиру- ется наличие этих ресурсов в случае аварийного перезапуска, в отличие от традиционных систем, где выделение ресурсов происходит по запросу и в принципе может закончиться неудач- но. Например, для каждого процесса должен быть определён максимальный размер памяти, который ему разреша- ется использовать. При запуске процес- са эта память выделяется сразу, после чего стеки потоков и куча выделяют- ся уже внутри процесса. На это можно возразить, что в разные моменты вре- мени разным процессам может потре- боваться вообще вся доступная в систе- ме оперативная память и такой подход слишком ограничивает пользователь- ские программы. Но, если в системе возможно существование нескольких Представление приложений в ядре ОС Рис. 3. Информация о состоянии приложений в микроядре Приложения Сервер файлов Сервер сети Микроядро
RkJQdWJsaXNoZXIy MTQ4NjUy