суббота, 26 декабря 2009 г.

ISSP \ Домен 03. Архитектура и модель безопасности. Часть 2

В этой части рассмотрены следующие вопросы:
  • Архитектура операционной системы
  • Управление процессами
  • Управление потоками
  • Диспетчеризация процессов
  • Работа процессов

Обновлено: 05.04.2010


Операционная система предоставляет среду для работы приложений и пользователей. Операционная система состоит из различных слоев и модулей, которые отвечают за управление оборудованием, памятью, операциями ввода/вывода, процессами, файловой системой, а также предоставляют системные сервисы. Далее мы вкратце рассмотрим каждую из этих функций, относящихся к любой операционной системе.


Операционные системы, утилиты и приложения в действительности являются просто множеством строк команд. Эти статические строки кода оживают после инициализации программы и размещения в памяти. Приложения работают как отдельные модули, называемые процессами, операционная система также имеет множество различных процессов, выполняющих различные функции. Процесс – это набор команд, запущенный на выполнение. Программа не является процессом, пока она не загружена в память и не активирована операционной системой. При создании процесса операционная система выделяет ему ресурсы, такие как сегменты памяти, кванты процессорного времени, доступ к интерфейсам API (application programming interface), файлам и т.п.

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

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

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

В ранних версиях операционных систем (Windows 3.1, Macintosh) была реализована кооперативная многозадачность (cooperative multitasking), когда процессы сами освобождали ресурсы компьютера, по своему усмотрению. В более современных версиях (Windows 2000, XP, Unix-системах и т.д.) реализована вытесняющая многозадачность (preemptive multitasking), при использовании которой операционная система сама управляет использованием ресурсов процессами. Кооперативная многозадачность не может обеспечить стабильную среду, т.к. если программист не написал (или неправильно написал) код, надлежащим образом освобождающий ресурс после выполнения своего приложения, этот ресурс может оказаться заблокированным на неопределенное время и недоступным для других процессов. При использовании вытесняющей многозадачности операционная система управляет тем, сколько времени процесс может использовать ресурс. Система может приостановить процесс, использующий процессор и позволить другим процессам получить доступ к нему с помощью разделения времени (time sharing). В операционных системах с кооперативной многозадачностью, процессы имели слишком большой контроль над ресурсами, и если приложение зависало, это, как правило, затрагивало все остальные приложения, а иногда и саму операционную систему. В операционных системах с вытесняющей многозадачностью одно приложение не может также легко оказать негативное влияние на другое приложение.

Различные операционные системы используют различные модели процессов. Например, системы Unix и Linux позволяют своим процессам создавать новые дочерние процессы, что называется ветвлением (forking). Допустим, вы работаете в оболочке системы Linux. Эта оболочка является командным интерпретатором, а также интерфейсом, который позволяет пользователю взаимодействовать с операционной системой. Оболочка выполняется как процесс. Если вы введете в этой оболочке команду cat file1 file2 | grep stuff, вы скажете операционной системе, что нужно объединить (cat) два файла, а затем найти (grep) строки, которые имеют значение stuff. Когда вы нажмете клавишу ENTER, оболочка породит два дочерних процесса – один для команды cat и один для команды grep. Каждый из этих дочерних процессов получит характеристики родительского процесса, но будет иметь свое собственное пространство памяти, стек и значение счетчика команд.

Процесс может находиться в состоянии выполнения (running state – процессор выполняет команды процесса), в состоянии готовности (ready state – ожидание передачи команд процессору) или в заблокированном состоянии (blocked state – ожидание входящих данных). Эти различные состояния показаны на рисунке 3-4. Когда процесс заблокирован, он ждет, когда ему отправят некоторые данные. В предыдущем примере, после ввода команды cat file1 file2 | grep stuff, процесс grep не может выполнять свои функции поиска, пока процесс cat не выполнит объединение этих двух файлов. Процесс grep переведет себя в спящий режим и будет находиться в заблокированном состоянии, пока не выполнится процесс cat и не пошлет процессу grep входные данные, которые он должен будет обработать.

Рисунок 3-4. Процесс проходит через различные состояния

ПРИМЕЧАНИЕ. Не все операционные системы работают с процессами также, как системы Unix и Linux. Например, системы Windows не порождают новых дочерних процессов, вместо этого они создают новые потоки, которые работают в том же контексте, что и родительский процесс.
Операционная система отвечает за создание новых процессов, выделение каждому из них ресурсов, синхронизацию их взаимодействия и контроль, что не происходит ничего опасного. Операционная система хранит специальную таблицу процессов (process table), в которой содержится информация о каждом процессе. В этой таблице хранятся связанные с процессами параметры, например, состояние процесса, указатель стека, программный счетчик, распределение памяти, состояние открытых файлов и т.д. Вся эта информация нужна операционной системе для того, чтобы процессор загружал ее в свои регистры, когда ему необходимо взаимодействовать, например, с процессом 1. Когда закончится квант процессорного времени, выделенный процессу 1, вся текущая информация о состоянии процесса 1 сохранится в таблице процессов, чтобы, когда этот процесс снова получит квант времени, все эти сведения можно было загрузить обратно в регистры процессора. При этом из таблицы процессов в регистры процессора будет загружена информация процесса 2, а когда закончится и его квант процессорного времени, информация из регистров снова будет записана в таблицу процессов. Эти шаги показаны на Рисунке 3-5.

Рисунок 3-5. Таблица процессов содержит данные о состоянии процессов, которые необходимы процессору

Но как процесс узнает, когда он может взаимодействовать с процессором? Для этого используются прерывания (interrupt). Операционная система обманывает нас и приложения, заставляя думать, что процессор одновременно выполняет все задачи (операционную систему, приложения, операции с памятью, ввод/вывод и действия пользователей). Но в действительности это невозможно. Большинство процессоров могут выполнять только одну операцию за раз, поэтому система имеет аппаратные и программные прерывания. Когда устройству необходимо взаимодействовать с процессором, оно должно дождаться своего прерывания, которое его вызовет. То же самое происходит и в программном обеспечении. Каждый процесс имеет прерывание, связанное с ним. Это как присваивание номеров в отделе обслуживания клиентов в магазине – вы не можете пойти к прилавку, пока ваш номер не был назван.

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

ПРИМЕЧАНИЕ. Некоторые критические процессы не могут допустить прерывание своего выполнения другим процессом. Операционная система обеспечивает установку приоритетов для различных процессов. Когда одному процессу нужно прервать другой процесс, операционная система сравнивает уровни приоритета обоих процессов, чтобы определить, следует ли разрешать такое прерывание.
Есть две категории прерываний: маскируемые (maskable) и немаскируемые (non-maskable). Маскируемые прерывания связаны с событиями, которые не могут быть очень важны, и программист может указать, что даже если происходит маскируемое прерывание, программа не прерывает своей работы. Таким образом, маскируемые прерывания могут игнорироваться. Немаскируемые прерывания не могут быть проигнорированы приложением ни при каких обстоятельствах, поскольку события, которые вызывают немаскируемые прерывания, имеют критическое значение. Например, кнопке RESET может быть назначено немаскируемое прерывание, чтобы при нажатии этой кнопки процессор сразу выполнял соответствующие команды.

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

Сторожевой таймер (watchdog timer) является примером критического процесса, который всегда должен выполнять свою работу. Этот процесс выполнит "горячую" перезагрузку системы, если она зависнет и не сможет восстановиться. Например, если возникают проблемы с управлением памятью и операционная система зависает, сторожевой таймер перезагрузит систему. Этот механизм обеспечивает более стабильную среду.


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


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

Определения. Концепции работы компьютерных операционных систем могут быть очень сложными. Убедитесь, что вы понимаете следующие основные определения:

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

Диспетчеризация (scheduling) и синхронизация (synchronizing) различных процессов и их действий – это часть управления процессами, выполняемого операционной системой. При разработке операционной системы, необходимо определить порядок (политику) диспетчеризации процессов. Политика диспетчеризации предназначена для управления взаимодействием процессов друг с другом. Различные операционные системы могут использовать различные варианты диспетчеризации (по сути, алгоритмы управления разделением процессорного времени). Как было сказано ранее, различные процессы имеют различные уровни приоритета (прерывания), которые учитываются при распределении процессорного времени. Операционная система создает и удаляет процессы по мере необходимости, меняет их состояние (готов, заблокирован, выполняется). Она также контролирует взаимные блокировки (deadlock) процессов, пытающихся использовать одни и те же ресурсы.

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

Одним из примеров взаимной блокировки может быть ситуация, когда процесс A использует ресурс 1 и нуждается в ресурсе 2 для выполнения своих задач, но процесс В использует ресурс 2 и нуждается в ресурсе 1, чтобы закончить свою работу. Таким образом, оба процесса находятся в состоянии взаимной блокировки, поскольку у них нет ресурсов, которые им необходимы, чтобы завершить уже начатую работу. Такие ситуации происходят все реже по мере совершенствования технологий программирования. Кроме того, операционные системы теперь имеют специальные функции, обнаруживающие такие ситуации и освобождающие используемый ресурс, либо контролирующие надлежащее распределение ресурсов между процессами.

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


Компьютеры могут запускать различные приложения и процессы одновременно. Процессы совместно используют ресурсы и взаимодействуют друг с другом. Некоторые области памяти, файлы и переменные разделяются между различными процессами. Учитывая все это, крайне важно позаботиться об обеспечении стабильной, безопасной вычислительной среды и поддержании ее целостности. Необходимо гарантировать, что несколько процессов не могут одновременно осуществлять операции чтения и записи одного и того же ресурса. Именно операционная система является основной программой, которая обеспечивает соответствующие защитные механизмы и не позволяет программам повредить область памяти друг у друга. Операционная система работает с процессором, чтобы обеспечить деление времени на кванты с помощью прерываний, для предоставления процессам адекватного доступа к центральному процессору. Это также гарантирует, что вредоносные приложения не окажут негативного влияния на важные функции системы.

Для защиты процессов друг от друга операционная система может использовать изоляцию процессов (process isolation). Изоляция процессов необходима, чтобы процессы «не наступали друг другу на ноги», взаимодействуя небезопасным образом, и не оказывали негативного влияния на производительность друг друга. Более старые операционные системы не обеспечивали достаточной изоляции процессов. Если в такой операционной системе «зависала» одна программа, «зависали» и все другие программы, а иногда и сама операционная система. В операционной системе с надлежащей изоляцией процессов «зависание» одного процесса не влияет на другие запущенные программы. (Изоляция процессов требует использования вытесняющей многозадачности). Для реализации изоляции процессов могут использоваться различные методы:
  • Инкапсуляция объектов
  • Временное мультиплексирование общих ресурсов
  • Разделение имен
  • Виртуальное отображение
Когда процесс инкапсулирован, никакие другие процессы не могут взаимодействовать с его внутренним кодом. Если процессу А нужно взаимодействовать с процессом В, процессу А достаточно знать как взаимодействовать с интерфейсом процесса В. Интерфейс определяет порядок взаимодействия между двумя процессами. Программные компоненты должны знать, как правильно взаимодействовать с интерфейсами друг друга. Интерфейсы диктуют типы запросов (которые будут принимать процессы), и типы результатов (которые они будут предоставлять). Таким образом, два процесса могут общаться друг с другом, даже если они написаны на разных языках программирования, поскольку они знают, как общаться с интерфейсом друг с друга. Инкапсуляция обеспечивает скрытие данных, т.е. за пределами программных компонентов не будет известно, как работает процесс и не будет возможности манипулировать внутренним кодом процесса. Этот механизм обеспечивает целостность и модульность программного кода.

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

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

Отображение виртуального адресного пространства отличается от физического отображения памяти. Для приложений создается иллюзия того, что каждое из них является единственным запущенным приложением в операционной системе. Когда приложению требуется память для работы, оно говорит менеджеру памяти операционной системы, сколько памяти ему нужно. Операционная система выделяет необходимый объем памяти и связывает его с запрашивающим приложением. Приложение использует свою собственную схему адресации, которая обычно начинается с 0, но в действительности приложение не работает с физическим адресным пространством (хотя ему кажется, что работает). Вместо этого, оно работает в адресном пространстве, которое ему предоставил менеджер памяти. Физическая память – это микросхемы памяти в системе. Операционная система берет часть этой памяти и связывает ее с запрашивающим процессом. Как только процессу предоставлено собственное пространство памяти, он может адресовать эту часть как он хочет, это называется виртуальным отображением адресов. Виртуальное отображение адресов позволяет различным процессам иметь собственное пространство памяти; менеджер памяти гарантирует невозможность ненадлежащего взаимодействия одного процесса с памятью другого процесса. Это обеспечивает целостность и конфиденциальность.

Комментариев нет: