Защита памяти от несанкционированного доступа в многозадачном режиме

Обновлено: 01.07.2024

В защищенном режиме процессор имеет четырехуровневую систему привиле­гий, которая управляет использованием привилегированных инструкций и до­ступом к сегментам памяти. Уровень привилегии сегмента указывается в его дескрипторе. Нумерация уровней происходит от 0 до 3, высшие привилегии соответствуют нулевому уровню. Для наглядности их принято изображать в виде колец.

Уровни привилегий обеспечивают защиту целостности операционной системы от «недружелюбных» программ. А также защиту адресных пространств одновременно выполняемых задач. Сервисы операционной системы, обра­ботчики прерываний и другое системное обеспечение могут включаться в вир­туальное адресное пространство каждой задачи и защищаться системой приви­легий. Как правило, назначение уровней следующее. Нулевой уровень – уровень операционной системы (ядро операционной системы). Уровни 1 и 2 – программы системного назначения. Уровень 3 – прочие прикладные программы (уровень прикладных программ). Дескрипторы (сегменты) и селекторы имеют свои атрибуты привилегий.

Привилегии задач оказывают влияние на выполнение инст­рукций и использование дескрипторов. Текущий уровень привилегии задачи CPL ( Current Privilege Level ) определяется двумя младшими битами регист­ра CS .

CPL задачи может изменяться только при передаче управления к новому сегменту через дескриптор шлюза (см. главу 5). Задача начинает выполняться с уровня CPL, указанного селектором кодового сегмента внутри TSS , когда задача иницииру­ется посредством операции переключения задач. Задача, выполняемая на нуле­вом уровне привилегий, имеет доступ ко всем сегментам, описанным в GDT , и является самой привилегированной. Задача, выполняемая на уровне 3, имеет самые ограниченные права доступа. Текущий уровень привилегии задачи может изме­няться только при передаче управления через шлюзы.

Привилегии сегмента задаются полем DPL байта управления доступом.

DPL определяет наибольший номер уровня привилегий (фактически, наименьшие привилегии), с которым возможен доступ к данному дескриптору. Самый защищенный (привилегированный) дескриптор имеет DPL =0, к нему имеют до­ступ только задачи с CPL =0 . Самый общедоступный дескриптор имеет DPL =3 , его могут использовать задачи с CPL =0, 1, 2, 3. Это правило применимо ко всем дескрипторам, за исключением дескриптора LDT .

Привилегии селектора задаются полем RPL ( Requested Privilege Level ) — двумя младшими битами селектора.

При обращении в сегмент данных с помощью RPL можно ограничить привилегии (относительно CPL ), вводится понятие эффективный уровень привилегий EPL ( Effective Privilege Level ), ко­торый определяется как максимальное из значений CPL и RPL, Селектор с RPL =0 не вводит дополнительных ограничений.

EPL = MAX ( CPL , RPL )

Контроль доступа к сегментам данных производится при исполнении команд, загружающих селекторы в SS , DS , ES , FS и GS . Команды загрузки DS , ES , FS и GS должны ссылаться на дескрипторы сегментов данных или сегментов кодов, допус­кающих чтение. Для получения доступа эффективный уровень привилегий EPL должен быть равным или меньшим (арифметически) уровня привилегий DPL де­скриптора.

EPL £ DPL

· Команды JMP или CALL могут ссылаться либо на подчиненный сегмент кода с DPL, большим или равным CPL, либо на неподчиненный сегмент с DPL равным CPL;

· Прерывания внутри задачи или вызовы, которые могут изменить уровень привилегий, могут передавать управление кодовому сегменту с уровнем привилегий, равным или большим уровня привилегий CPL, только через шлюзы с тем же или меньшим уровнем привилегий, чем CPL;

· Инструкции возврата, которые не переключают задачи, могут передать управление только кодовому сегменту с таким же или меньшим уровнем привилегий;

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

Смена уровня привилегий, происходящая при передаче управления, автома­тически вызывает переопределение стека. Начальное значение указателя стека SS : SP для уровня привилегий 0, 1, 2 содержится в TSS. При передаче управле­ния по командам JMP или CALL в CS : SP загружается новое значение указателя стека, а старые значения помещаются в новый стек. При возврате на прежний уро­вень привилегий его стек восстанавливается (как часть инструкции RЕТ или IRЕТ). Для вызовов подпрограмм с передачей параметров через стек и сменой уровня при­вилегий из предыдущего стека в новый копируется фиксированное число слов, заданное в шлюзе. Команда межсегментного возврата RET с выравниванием ука­зателя стека при возврате корректно восстановит значение предыдущего указателя.

Привилегии и битовая карта разрешения ввода/вывода контролируют воз­можность выполнения операций ввода/вывода и управления флагом пре­рываний IF . Уровень привилегий ввода/вывода определяется полем IOPL ( Input / Output Privilege Level ) регистра флагов. Значение IOPL можно изме­нить только при CPL =0 (только для операционной системы).

3.2 Защита по функциональному назначению.

Для надежной работы многозадачных систем необходима защита задач друг от друга. Защита предназначена для предотвращения несанкционированного до­ступа к памяти и выполнения критических инструкций — команды HLT , которая останавливает процессор, команд ввода/вывода, управления флагом разреше­ния прерываний и команд, влияющих на сегменты кода и данных. Механизмы защиты вводят следующие ограничения:

· Ограничение использования сегментов (например, запрет записи в только читаемые сегменты данных или попытки исполнения данных как кода). Для использования доступны только сегменты, дескрипторы которых описаны в GDT и LDT ;

· Ограничение доступа к сегментам через правила привилегий;

· Ограничение набора инструкций — выделение привилегированных инст­рукций или операций, которые можно выполнять только при определен­ных уровнях CPL и IOPL ;

· Ограничение возможности межсегментных вызовов и передачи управле­ния.

В защищенном режиме при исполнении инструкций процессор выполняет проверки условий, порождающих исключения:

Проверка при загрузке сегментных регистров

§ загрузка в SS сегмента кода или сегмента данных только для чтения;

§ загрузка управляющих дескрипторов в DS , ES или SS;

§ загрузка только исполняемых сегментов в DS , ES или SS;

§ загрузка сегмента данных в CS .

Проверка ссылок операндов

Проверка привилегий инструкций

При выполнении команд IRET и POPF с недостаточным уровнем привилегий биты IF и IOPL в регистре флагов не изменяются, исключения не порождаются:

· IF не меняется, при CPL > IOPL;

· IOPL не меняется, если CPL > 0.

Проверки при передаче управления по инструкциям JMP , CALL , RET , INT и IRET включают как проверку ссылок по размеру (в «ближних» формах JMP, CALL и RET выполняются только эти проверки), так и проверку правил приви­легий при межсегментных передачах через шлюзы.

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

· ARPL выравнивание RPL. При ее исполнении RPL селектора приравни­вается максимальному значению из текущего RPL селектора и поля RPL в указанном регистре. Если при этом RPL изменился, устанавливается ZF =1;

· VERR проверка возможности чтения: если сегмент, на который указы­вает селектор, допускает чтение, устанавливается ZF =1;

· VERW проверка возможности записи: если сегмент, на который указы­вает селектор, допускает запись, устанавливается ZF =1;

· LSL — чтение лимита сегмента в регистр, если позволяют привилегии. При успехе устанавливается ZF =1;

· LAR — чтение байта доступа дескриптора в регистр, если позволяют при­вилегии. При успехе устанавливается ZF =1.

Некоторые функции защиты выполняются и механизмом страничной пере­адресации, однако, в отличие от «непробиваемой» сегментной защиты, сущест­вуют способы обхода страничной защиты на уровне пользователя ( CPL =3).

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

Таким образом, средства защиты памяти должны предотвращать 2

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

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

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

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

Если нарушается защита памяти , исполнение программы приостанавливается и вырабатывается запрос прерывания по нарушению защиты памяти .

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

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

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

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

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


Рис. 17.1. Защита памяти методом граничных регистров

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

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

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

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

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

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

Функционирование этого механизма защиты памяти поясняется схемой на рис. 17.2.

При обращении к памяти группа старших разрядов адреса ОЗУ , соответствующая номеру блока, к которому производится обращение, используется как адрес для выборки из памяти ключей защиты кода ключа защиты, присвоенного операционной системой данному блоку. Схема анализа сравнивает ключ защиты блока памяти и ключ программы, находящийся в регистре слова состояния программы ( ССП ), и вырабатывает сигнал "Обращение разрешено" или сигнал " Прерывание по защите памяти". При этом учитываются значения режима обращения к ОЗУ ( запись или считывание), указываемого триггером режима обращения ТгРО, и режима защиты, установленного в разряде режима обращения (РРО) ключа защиты памяти .

Во всех процессорах, начиная с Intel286, при установке CR0.PE = 1 включается защищенный режим работы. В этом режиме помимо средств расширенной адресации и поддержки мультизадачности процессор обеспечивает многоуровневую систему защиты. Защита предотвращает несанкционированное использование данных, исполняемых кодов и портов ввода/вывода. Таким образом обеспечивается устойчивая и безопасная работа всех программ в многозадачной среде.

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

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

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

  • флаг Sдескриптора сегмента,
  • поле TYPEдескриптора сегмента,
  • поле LIMITдескриптора сегмента,
  • флаг Gдескриптора сегмента,
  • флаг Eдескриптора сегмента,
  • поле DPLдескриптора сегмента,
  • поле RPL (CPL) селектора сегмента,
  • флаги U/S и W/R в каталогах и таблицах страничных преобразований,
  • флаг CR0.WP,
  • поле уровня привилегий ввода/вывода в регистре флагов EFLAGS.IOPL.

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

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

Защита на уровне сегментов

Защита на уровне сегментов является основной и обеспечивает наибольшее количество функций. Основа ее функционирования — это разделение уровней привилегий и отслеживание текущих прав доступа.

Система защиты на уровне сегментов поддерживает четыре уровня привилегий (0, 1, 2, 3). Самым привилегированным уровнем считается нулевой уровень привилегий. На этом уровне предполагается исполнение программ ядра мультизадачных операционных систем (в простых ОС все программы, в т.ч. и пользовательские, могут исполняться на нулевом уровне привилегий, что равнозначно отсутствию защиты по уровням привилегий). Следующие уровни привилегий (1, 2, 3) предназначены для вспомогательных и пользовательских программ. Специальные дескрипторы — т.н. шлюзы, обеспечивают взаимодействие между задачами, выполняемыми на различных уровнях привилегий. Обычно все пользовательские программы работают на уровне привилегий 3, т.е. обладают наименьшим количеством прав доступа к различным компонентам ОС и областям памяти.

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

Защита на уровне страниц

Механизм страничной защиты введен в процессорах начиная с Intel386 и работает поверх всех средств сегментной защиты. Он включается в работу при инициализации страничного механизма и обеспечивает:

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

Его работа основана на специальных полях U/S и W/R в элементах таблиц страничных преобразований.

Поле U/S определяет права доступа для соответствующей страницы (страниц):

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

Поле W/R предназначено для установки защиты пользовательских страниц от записи. Причем в зависимости от текущего значения флага CR0.WP пользовательские страницы могут быть защищены и от записи программами супервизора, а не только от пользовательских программ.

Поля U/S и W/R имеются и в элементах каталога страниц и в элементах таблицы страниц. Поэтому возможно задание комбинированных условий защиты для различных страниц.

Таблица 2.6. Комбинация защиты в каталоге и в таблице страниц

Защита памяти. Разберёмся с основными средствам защиты памяти в Windows. Ведь одни процессы не должны получить доступ к памяти других процессов.

Средства защиты памяти

Windows предоставляет средства защиты памяти, чтобы пользовательские процессы не могли повредить адресное пространство другого процесса или операционной системы. В системе существует несколько основных механизма защиты. Ниже разберём их все.

Разделение на пользовательский режим работы и режим ядра

Как вы уже знаете, работа системы Windows разделена на два режима. Во-первых это пользовательский режим, в котором работают пользовательские процессы. Во-вторых это режим ядра, в котором работает ядро системы и драйвера устройств. Память выделенная для режима ядра используется только из режима ядра. То есть эта память доступна только для компонентов ядра и для драйверов. Потоки пользовательского режима не могут обращаться к этой памяти.

Защита памяти в Windows

Закрытое адресное пространство

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

Защита памяти в Windows

Аппаратная защита

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

Права доступа ACL

Предотвращение выполнения данных DEP

Посмотреть какие процессы поддерживают DEP можно в Process Explorer, добавив соответствующую колонку:

Дополнительно про защиту памяти в операционной системе Windows можете почитать тут.

Читайте также: