Защита.

Глава 1. Проверки, обеспечивающие защиту.

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

            В данном разделе рассматривается механизм защиты, применяемый в защищённом режиме. Защита в режиме реальных адресов и виртуального 8086 рассматривается в разделе "Режим виртуального процессора 8086".

    1.1. Разрешение и запрещение защиты сегментов и страниц.

            Установка флага PE в регистре CR0 заставляет процессор переключиться в защищённый режим, который в свою очередь автоматически обеспечивает механизм защиты, причём та его часть, которая отвечает за защиту по привилегиям, может вообще не использоваться, если программа, работающая в защищённом режиме использует все дескрипторы и селекторы на нулевом уровне привилегий.
            Защита на уровне страниц автоматически обеспечивается при включении страничного преобразования установкой бита PG в CR0. Эту защиту можно отключить, выполнив следующие операции:
  • Сбросить флаг WP в регистре CR0.
  • Установить флаги R/W и (U/S) в каждом элементе каталога и таблиц страниц.

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

    1.2. Поля и флаги, используемые для защиты на уровне сегментов и страниц.
  • Флаг типа дескриптора (S) - (4-й бит байта прав доступа дескриптора). Определяет вид дескриптора - если 0, то он описывает системный объект, если 1, то сегмент кода или данных.
  • Поле типа дескриптора - (Биты 0..3 байта прав доступа). Определяет тип системного объекта, сегмента кода или данных.
  • Поле предела дескриптора - (Биты 0..15 и 48..51 в дескрипторе). Определяют размер сегмента в единицах размера (байтах или 4Кб страницах).
  • Флаг гранулярности G - (Бит 55 дескриптора). Определяет единицы измерения размера сегмента: 0 - сегмент измеряется в байтах, 1 - в 4Кб страницах.
  • Флаг E - (Бит 2 байта прав доступа дескриптора сегмента данных). Определяет расширение сегмента: 0 - адреса растут вверх (как в обычном сегменте), 1 - вниз (т.е. наоборот).
  • Поле уровня привилегий дескриптора (DPL) - (Биты 5 и 6 байта прав доступа). Определяют уровень привилегий сегмента.
  • Поле запрошенного уровня привилегий (RPL) - (Биты 0 и 1 любого селектора сегмента). Содержат запрашиваемый уровень привилегий при обращении к дескриптору.
  • Поле текущего уровня привилегий (CPL) - (Биты 0 и 1 регистра CS). Содержат уровень привилегий текущей процедуры.
  • Флаг пользователя/системы (User/Supervisor) (U/S) - (Бит 2 элемента каталога или таблицы страниц). Определяют тип страницы: 0 - системный, 1 - пользовательский.
  • Поле чтения/записи (Read/write) (R/W) - (Бит 1 элемента каталога или таблицы страниц). Определяет тип доступа к странице: 0 - только чтение, 1 - чтение и запись.

    1.3. Проверка предела.

            Проверка предела дескриптора сегмента не позволяет программе обращаться за пределы сегмента. Значение предела зависит от флага гранулярности (G) дескриптора. Предел определяет максимальное значение смещения в сегменте.
            Для сегментов данных, расширяющихся вниз, предел определяет последний адрес, доступ к которому запрещён внутри сегмента. Допустимыми будут адреса в диапазоне от (предел + 1) до FFFFh, если флаг D=0 и от (предел + 1) до FFFFFFFFh, если D=1. Максимальный размер такие сегменты имеют с пределом, равным нулю.
            Процессор также проверяет пределы дескрипторных таблиц GDT, IDT, LDT и текущего сегмента TSS, не позволяя обращаться за их пределы.

    1.4. Проверка типа

            Дескриптор сегмента содержит информацию о типе в двух элементах:
  • Флаг S (тип дескриптора).
  • Поле типа.

            Процессор использует эту информацию для определения ошибочных действий программ, когда они пытаются использовать сегмент или шлюз неправильным или несоответствующим образом.
            Флаг S определяет, описывает дескриптор системный объект или сегмент кода или данных. Поле типа содержит 4 дополнительных бита, определяя различные типы дескрипторов.
            В таблице 1-1 приведены значения поля типа дескрипторов, в таблице 1-2 приведены значения полей для системных дескрипторов.

            Процессор проверяет значение типа несколько раз, когда оперирует селекторами и дескрипторами. Далее приведены примеры типичных операций, где происходит проверка типов:
    - В регистр CS можно загрузить только селектор сегмента кода.
    - Селектор сегмента нечитаемого кода нельзя загружать в сегментные регистры данных (DS, ES, FS и GS).
    - В регистр SS можно загружать только селектор сегмента данных, разрешённого для записи.
    - В LDTR можно загрузить можно загрузить только селектор для LDT.
    - В TR можно загрузить можно загрузить только селектор для TSS.
    - Нельзя записывать в сегмент кода.
    - Нельзя записывать в сегмент данных, предназначенный только для чтения.
    - Нельзя читать из сегмента кода, предназначенного только для выполнения.
    - Команда LAR должна обращаться к дескриптору сегмента или шлюза для сегментов LDT, TSS, шлюзу вызова, шлюзу задачи, сегменту кода или данных.
    - Команда LSL должна обращаться к дескриптору сегмента LDT, TSS, кода или данных.
    - Элементом IDT может быть только шлюзы прерывания, ловушки или вызова.
    - При выполнении команд FAR CALL и FAR JMP процессор проверяет тип дескриптора, селектор которого содержится в адресе назначения этих команд. Если это дескриптор сегмента кода или шлюза вызова, то происходит передача управления по этому адресу; если дескриптор описывает TSS или шлюз задачи, то происходит переключение задач.

    Таблица 1-1. Тип сегмента
    Бит # 11 10 9 Тип  
    Название   E W
      0 0 0 Данные Только чтение
    0 0 1 Данные Чтение и запись
    0 1 0 Данные Только чтение, расширяется вниз
    0 1 1 Данные Чтение и запись, расширяется вниз
      1 0 0 Код Только выполнение
    1 0 1 Код Только выполнение
    1 1 0 Код Только выполнение, согласованный
    1 1 1 Код Выполнение и считывание, согласованный


    Таблица 1-2. Типы системных объектов
    Значе-
    ние
    Поле типа1
    биты: 3 2 1 0
    Системный объект
    0 0 0 0 0 Зарезервировано
    1 0 0 0 1 16-разрядный TSS (Свободный)2
    2 0 0 1 0 LDT
    3 0 0 1 1 16-разрядный TSS (Занятый)2
    4 0 1 0 0 16-разрядный шлюз вызова (call gate)
    5 0 1 0 1 Шлюз задачи (task gate)
    6 0 1 1 0 16-разрядный шлюз прерывания (interrupt gate)
    7 0 1 1 1 16-разрядный шлюз ловушки (trap gate)
    8 1 0 0 0 Зарезервировано
    9 1 0 0 1 32-разрядный TSS (Свободный)2
    10 1 0 1 0 Зарезервировано
    11 1 0 1 1 32-разрядный TSS (Занятый)2
    12 1 1 0 0 32-разрядный шлюз вызова (call gate)
    13 1 1 0 1 Зарезервировано
    14 1 1 1 0 32-разрядный шлюз прерывания (interrupt gate)
    15 1 1 1 1 32-разрядный шлюз ловушки (trap gate)

    Примечания:
    1. Полем типа в дескрипторе системного объекта являются 4 бита в 5-м байте дескриптора или его битами 40..43.
    2. Для дескрипторов TSS второй по счёту бит в поле типа называется B от слова "Busy" и этот бит отражает занятость задачи: 1/0 - задача занята / свободна.

    1.5. Проверка нулевого селектора сегмента.

            Попытка загрузки нулевого селектора в регистр CS или SS приводит к генерации исключение общей защиты (#GP). Этот селектор можно загружать в регистры DS, ES, FS или GS, но тогда обращение через них к памяти приводит к генерации такого же исключения.

    Следующая глава Оглавление Вопросы? Замечания? Пишите: sasm@narod.ru

      Copyright © Александр Семенко.
    TopList

    Hosted by uCoz