Скачиваний:
81
Добавлен:
16.04.2013
Размер:
396.29 Кб
Скачать

Типы системных дескрипторов

TYPE

Тип системного дескриптора

0000

Резервировано

0001

TSS, 16-разрядный (доступен)

0010

LDT

0011

TSS, 16-разрядный (занят)

0100

Шлюз вызова подпрограммы, 16-разрядный

0101

Шлюз вызова задачи

0110

Шлюз вызова прерываний, 16-разрядный

0111

Шлюз вызова ловушки, 16-разрядный

1000

Резервировано

1001

TSS, 32-разрядный (доступен)

1010

Резервировано

1011

TSS, 32-разрядный (занят)

1100

Шлюз вызова подпрограммы, 32-разрядный

1101

Резервировано

1110

Шлюз вызова прерываний, 32-разрядный

1111

Шлюз вызова ловушки, 32-разрядный

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

Дескрипторы сегментов TSSиспользуются при переключении задач в многозадачном режиме. При этом бит 3 поляTYPEбайта доступа указывает, решается ли вызываемая задача с использованием 16- или 32-разрядных адресов и данных. БитBв байте доступа сегмента TSS называется битом занятости и указывает, является ли вызываемый сегмент занятым (соответствующая задача находится в процессе выполнения) или доступным (задача еще не поступила на выполнение). Переключение на занятую задачу вызывает исключение типа #GP(“нарушение защиты”). Отметим, что дескрипторы LDT и TSS всегда должны иметь значение бита разрядностиD/B=0.

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

Дескрипторы сегментов, использующих 16-разрядные адреса и операнды при размере сегментов до 1М-байт (значения битов G = D/B = 0), имеют нулевые значения байтов 5 и 6 дескриптора (рис.$4). Такие дескрипторы использовались в 16-разрядных микропроцессорах 80286. Остальные биты и поля дескрипторов для процессоров 80286 полностью соответствуют форматам, приведенным на рис.$4, $5. Поэтому процессоры семейства IA-32, обеспечивают полную программную совместимость с 16-разрядным микропроцессором 80286, выполняя сегменты инструкций (программы), написанные для 80286, без какой-либо модификации. Отличие состоит только в разрядности базового адреса, которая для 80286 равна 24 битам (ВА[23:0] в байтах 2, 3, 4 дескриптора), и границе сегмента, которая не должна превышать 64KB (L[15:0] в байтах 0,1 дескриптора).

Привилегии и защита памяти

В архитектуре IA-32, для защиты информации, хранящейся в сегментах памяти, используется система привилегий,которая регулирует доступ к тому или иному сегменту в зависимости от уровня его защищенности и от степени важности (привилегированности) запроса. Здесь установлены четыре уровня привилегийPL(privilegelevel), которые задаются номерами от 0 до 3 (иногда их называют кольцами защиты). Наиболее привилегированным является уровень с меньшим номером. Степень защищенности сегмента также имеет четыре уровня. Наименее защищенными (привилегированными) являются прикладные программы пользователя, для которых выделяется уровень с номеромPL=3. Уровни с номерамиPL=0, 1, 2 отводятся для системных программ (супервизора), которые можно разделить на три уровня в зависимости от требований к их защищенности. Наиболее защищенная часть – ядро операционной системы (ОС) имеет уровеньPL=0. В ядро входит часть ОС, обеспечивающая инициализацию работы, управление доступом к памяти, защиту и ряд других жизненно важных функций, нарушение которых полностью выводит систему из строя. Основная часть программ ОС (утилиты) должна иметь уровеньPL=1. К уровнюPL=2 обычно относят ряд служебных программ ОС, например, драйверы внешних устройств, системы управления базами данных, специализированные подсистемы программирования и другие.

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

В соответствии с уровнями привилегий и защищенности установлены следующие правила доступа для сегментов программ и данных.

  1. Данные из сегмента, имеющего уровень защиты PL, могут быть выбраны программой, имеющей такой же или более высокий уровень привилегий.

  2. Сегмент программ (процедура), имеющий уровень защиты PL, может быть вызван программой, имеющей такой же или более низкий уровень привилегий. Различные варианты вызова сегментов программ описаны ниже.

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

Уровень привилегий дескриптора DPL(DescriptorPL) задается битами 5,6 в байте доступа дескриптора (см. рис.$5). Указывает уровень защищенности сегмента, т.е. номер кольца защиты, к которому он относится.

Уровень привилегий запроса RPL(RequestedPL) задается битами 0,1 селектора, загруженного в сегментный регистр при обращении к соответствующему сегменту. Этот уровень устанавливается выполняемой программой, которая с помощью данного селектора обращается к памяти системы.

Текущий уровень привилегий CPL(CurrentPL) задается битами 0,1 селектора, размещенного в регистре сегмента программCS. Определяет уровень привилегий выполняемого в настоящий момент сегмента программы.

Напомним, что меньшее значение DPL,RPL,CPLсоответствует более высокому уровню привилегий (защиты). Наиболее защищенный сегмент имеет значениеDPL=0, наименее защищенный –DPL=3. Для наименее привилегированных программ пользователяCPL=3, наиболее привилегированные программы ядра ОС имеютCPL=0.

Процессор имеет специальную инструкцию ARPL,используемую для коррекции значения RPL селектора. Данная инструкция выполняет сравнение RPL селектора и поля RPL в указанном регистре или ячейке памяти. Результатом инструкции является селектор, в котором эти биты, имеют максимальное из значений, заданных в исходных полях RPL.

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

Обращение к сегментам данныхпроизводится с помощью селекторов, загружаемых в регистрыDS,ES,FS,GS. При обращении анализируются значения RPL селектора и CPL текущей программы. Эффективный уровень привилегий для запроса данных в этом случае определяется как максимум из значений RPL и CPL. Обращение к запрашиваемому сегменту данных разрешается, если его уровень защитыDPLmax(RPL,CPL). Нарушение этого правила при обращении вызывает исключение типа #GP«нарушение общей защиты».

Таким образом, задавая определенное значение RPL в селекторе, можно управлять доступом текущей программы к сегментам данных, имеющим различный уровень защиты. Например, при RPL=0 доступ к данным будет определяться значением CPL текущей программы. Если задатьRPL=3, то при любом CPL программа может обратиться только к наименее защищенным сегментам данных, относящимся к кольцу 3.

Обращение к сегменту стекавыполняется путем загрузки селектора в регистрSS. Этот селектор должен выбирать дескриптор сегмента с разрешенной записью, т.е. в байте доступа битR/Wдолжен быть установлен в 1. Значения RPL и DPL должны быть равны CPL. Нарушение этих правил (обращение к сегменту, для которогоR/W=0; использование селекторов и дескрипторов, имеющих значения RPL и DPL, не равные CPL) приводит к исключению типа #GP. При обращении к дескриптору, имеющему значение бита присутствияP=0 (отсутствующий сегмент) возникает исключение типа #SS“ошибка обращения к стеку”.

Обращение к сегментам программ(передача управления) реализуется при выполнении инструкций межсегментного переходаJMP,вызова подпрограммыCALLи возврата из подпрограммыRET,прерыванияINTи возврата из прерыванияIRET. Правила обращения к сегментам программ зависят от значения бита подчиненностиCв байте доступа дескриптора.

Обращение к подчиненным сегментам, для которых установлено значение C=1, допускается только из программ, имеющих такой же или более низкий уровень привилегий. Таким образом, в программах с текущим уровнем привилегий CPL могут выполняться межсегментные инструкцииJMP, CALLс передачей управления подчиненному сегменту, имеющемуDPLCPL. При такой передаче значение CPL сохраняется, т.е. сохраняется уровень привилегий вызывающей программы.

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

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

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

Обращение к неподчиненным сегментам, имеющим значение C=0, с помощью инструкцийJMP иCALLдопускается только в случае, если уровень привилегий текущей программы равен уровню защиты сегмента: CPL=DPL

3

Сегмент

кода A

Селектор сегмен­таD3 (RPL=3)

(CPL=3)

Селектор сегмен­таD2 (RPL=2)

Сегмент

2

Сегмент

кода D

кода B

(DPL=2)

(CPL=2)

Селектор сегмен­таE2 (RPL=2)

Подчиненный

сегмент

Селектор сегмен­та D1 (RPL=1)

Неподчиненный

1

Сегмент

сегмент

кода C

Сегмент

(CPL=1)

Селектор сегмен­та E1 (RPL=1)

кода E

(DPL=1)

Сегмент

Селектор сегмен­та E0 (RPL=0)

0

кода F

(CPL=0)

Уровень привилегий

Рис. $6 Примеры обращений к подчиненному и неподчиненному сегментам из различных уровней привилегий. Стрелки из точек – запрещенные обращения: (1) RPL>CPLприC=0; (2)CPLDPLприC=0; (3)RPL>DPLприC=0; (4)CPL>DPLприC=1.

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

Для вызова более привилегированной программы инструкция CALL илиJMPдолжна обратиться к хранящемуся вLDTдескриптору шлюза вызова, формат которого показан на рис.$7.

Байты 7,6

Байт 5

Байт 4

31

16

15

14

13

12

11

8

7

6

5

4

0

Смещ.в целевом сегменте [31:16]

P

gDPL

0

TYPE

0

0

0

WC

Селектор целевого TSS

Смещение в целевом сегменте[15:0]

31

16

15

0

Байты 3,2

Байты 1,0

Рис. $7. Формат дескриптора шлюза вызова программы

В байтах 2,3 дескриптора шлюза содержится селектор вызываемого сегмента программы, а байты 0, 1, 6, 7 задают относительный адрес инструкции, являющейся точкой входа в эту программу. Байт доступа 5 содержит бит присутствияPи поле уровня привилегий дескриптора шлюзаgDPL(gateDPL), которые имеют такое же назначение, как и в дескрипторах сегментов. ПолеTYPEв байте доступа шлюза (табл. $.1) содержит код 0100 (если вызываемая программа написана для процессора 80286), либо код 1100 (если программа написана для процессоров 386+). ПолеWC(WordCount) в байте 4 указывает количество параметров, которые переносятся из стека, обслуживающего программы с текущим уровнем привилегийCPL, в стек, используемый программами с уровнем привилегий вызываемой программы. Параметры представляют собой 32-разрядные слова (16-разрядные для процессоров 80286), число которых может составлять от 0 до 31.

При вызове программ через шлюз должны выполняться следующие правила.

  1. Значения RPL селектора, вызывающего шлюз, должно быть меньше или равно значению gDPL в байте доступа шлюза.

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

  3. Значение gDPL шлюза вызова должно быть больше или равно уровню DPLвызываемого сегмента программ:gDPLDPL.

  4. Вызываемый сегмент программ должен иметь такой же или более высокий уровень привилегий DPL, чем текущая программа:DPLCPL.

Последнее правило реализуется при выполнении инструкции CALLс обращением к любым видам сегментов программ (подчиненным и неподчиненным) и инструкцииJUMP,вызывающей подчиненный сегмент. Если инструкцияJUMPосуществляет переход к неподчиненному сегменту программ, то необходимо выполнение правилаDPL=CPL.

Примеры реализации этих правил при различных комбинациях значений RPL, CPL, gDPL, DPL иллюстрируются на рис.$8. Здесь разрешенные связи обозначены обычными стрелками, а запрещенные – обозначены стрелками из точек, причем возле каждой такой стрелки в кружочке указан номер правила, которое она нарушает.

Заметим, что селекторы и дескрипторы разных уровней привилегий физически могут располагаться в сегментах данных любого уровня позволяющего их загрузку в сегментные регистры. Например, все селекторы могут располагаться в сегменте данных третьего уровня, а дескрипторы в таблице GDT, имеющейPL=0.

Если эти правила выполняются, то после вызова дескриптора шлюза в сегментный регистр CSзагружается селектор – байты 3,2 этого дескриптора. Этот селектор выбирает из LDT дескриптор вызываемого сегмента программы. При этом поле RPL селектора игнорируются, а вместо него в регистр CS в качестве CPL заносится значение DPL из дескриптора вызываемого сегмента. В регистрEIPиз дескриптора шлюза загружается относительный адрес входа в программу – байты 0, 1, 6, 7 (для программ процессора 80286 вIPзагружаются байты 0, 1).

Если вызванная программа имеет другой (более высокий) уровень привилегий, чем текущая, то при выполнении инструкций JMP,CALLс использованием шлюза вызова производится переключение стека. Выполняется обращение к стеку, организованному для программ с уровнем привилегий, соответствующим уровню вызванной программы. В этот стек последовательно вводятся старые значенияSSиESP; параметры, переносимые из старого стека; старые значения CS и EIP. Число переносимых параметров определяется полем WC шлюза вызова, причем выбираются последние параметры, загруженные в старый стек.

Сел.шл. K

Шлюз K

3

Сегмент

(RPL=3)

(gDPL=3)

Сегмент

кода A

кода F

(CPL=3)

Сел.шл.М3

(DPL=3)

(RPL=3)

Сел.шл.М2

Шлюз М

2

Сегмент

(RPL=2)

(gDPL=2)

кода B

(CPL=2)

Сел.шл. N

Шлюз N

(RPL=2)

(gDPL=2)

1

Сегмент

Селектор

кодаC

шлюза М1

(CPL=1)

(RPL=1)

0

Сегмент

Сегмент

кода D

кода E

(DPL=0)

(DPL=0)

Уровень привилегий

Подчиненный сегмент. Стек не переключается

Не подчиненный сегмент. Стек переключается

Рис. $8. Варианты передачи управления между уровнями защиты, с использованием шлюзов вызова.

На рис. $9 показано переключение стека при программном вызове через шлюз со сменой уровня привилегий.

Переключение стека производится автоматически путем загрузки в регистры SS и ESP из сегмента состояния задачи TSSнового содержимого, которое определяет начальный адрес стека для программ данного уровня привилегий.

Необходимо отметить, что переключение стека реализуется только при обращении к неподчиненным сегментам программ (имеющих в дескрипторе значение бита C=0). Если через шлюз осуществляется вызов подчиненного сегмента программ (значение битаC=1), то переключение стека не производится.

Параметр 3

SSпроц-ры А

Параметр 2

ESPпроц-ры А

Параметр 1

ESP

Параметр 3

Параметр 2

Стек вызывающей процедуры А

Параметр 1

CSпроц-ры А

EIPпроц-ры А

ESP

Стек вызванной процедуры B, после ее вызова

Рис. $9 Переключение стека при вызове через шлюз со сменой уровня привилегий

По инструкции RETпроизводится восстановление из стека старого содержимого регистровCS,EIP(IP) иSS,ESP(SP). Таким образом, одновременно с возвратом к исходной программе происходит возвращение к старому стеку. ИнструкцияRETпроверяет значение CPL и полеRPLизвлекаемого из стека старого содержимого CS, определяющие уровень привилегий программы, к которой осуществляется возврат. Инструкция выполняется только в том случае, когда значение этих битов больше или равно CPL, т.е. возврат осуществляется к программе с такимжеили меньшим уровнем привилегий.

Нарушение инструкциями JMP, CALL, RETуказанных правил обращения к сегментам программ вызывает исключение типа #GP(нарушение защиты).

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

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

Инструкции VERR, VERWпроверяют возможности записи в сегмент данных и чтения из сегмента программ, устанавливаемые соответствующими битами дескрипторов. Если запись или чтение разрешены, то устанавливается значение признакаZF=1 в регистреEFLAGS. Предварительный анализ значения этого признака позволяет избежать запрещенных видов обращения к данному сегменту, вызывающих прерывание текущей программы. Адресация необходимого сегмента при выполнении инструкцийVERR, VERWпроизводится таким же образом, как и инструкциейLAR.

Реализация ввода – вывода с помощью инструкций IN, OUT, INS, OUTSв защищенном режиме производится с учетомCPLвыполняемой программы. Величина CPL сравнивается со значением поляIOPLв регистреEFLAG. Ввод-вывод производится только при выполнении условияCPLIOPL. Нарушение этого условия вызывает исключение типа #GP, если доступ к адресованному инструкцией порту не разрешен специальной битовой картой ввода/вывода, задаваемой при решении отдельных задач.

Соседние файлы в папке M4