Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БІКС 2015_1 / Лек 6 Захист інформації на рівні операційної системи.doc
Скачиваний:
76
Добавлен:
12.02.2016
Размер:
3.66 Mб
Скачать

5.2. Сегментно-сторінковий розподіл пам'яті

Якщо сторінковий механізм вимкнено (в регістрі сгО біт pg = 0), з дескриптора за розглянутими вище алгоритмами визначається фізична базова адреса сегмента, а після додавання до неї зміщення — фізична адреса даних у пам'яті. Якщо ж сто­рінковий механізм увімкнено (в регістрі сгО біт pg = 1), то з дескриптора за тими самими алгоритмами визначається лінійна базова адреса сегмента, а після дода­вання до неї зміщення — лінійна адреса даних. Для обчислення фізичної адреси здійснюється сторінкове перетворення. Те саме стосується не лише адрес даних, а й базових адрес таблиць дескрипторів і адрес самих дескрипторів. Сторінкове пе­ретворення показано на рис. 10.4. Механізм сторінкового перетворення може ви­користовувати атрибути захисту сторінок з дескриптора (див. табл. 10.5).

Важливою відмінністю сегментно-сторінкового розподілу пам'яті порівняно з сегментним розподілом пам'яті у процесорах х86 є те, що в режимі сегмент­но-сторінкового розподілу пам'яті максимальним віртуальним адресним просто­ром є 4 Гбайт, і різні сегменти можуть перекриватися (вони можуть мати однако­вий розмір у 4 Гбайт і перекриватися повністю). Тоді до однієї лінійної адреси можна звернутися через різні сегменти та обійти таким чином згадані вище функ­ції захисту сегментів. Ці проблеми процесор не вирішує, а передає їх у сферу відповідальності операційної системи. Саме розробники операційної системи ви­значають, як будуть виділятися сегменти пам'яті процесам і потокам і як буде організовано взаємодію між ними, зокрема обмін даними.

Нумерація віртуальних сторінок — наскрізна та не залежить від поділу вірту­ального адресного простору на сегменти. Кожний процес має свій 4-гігабайтовий віртуальний адресний простір, а також власний набір розділів таблиць сторінок і власну таблицю розділів. Адресація таблиці розділів здійснюється через регістр сгЗ, отже, значення цього регістра специфічне для кожного процесу.

6. Керування задачами

Процесори х86 надають засоби для підтримки виклику процедур і задач [63, 92]. Виклик процедури означає виклик коду в межах одного процесу (потоку), коли відбувається переключення на інший сегмент коду (виклик процедури в межах

одного сегмента є тривіальним і не потребує спеціальних заходів захисту; відтак ми його не розглядатимемо), але зберігаються структури, що керують адресним простором процесу (таблиця LDT, таблиця сторінок). Після виклику задачі опе­раційною системою створюється новий процес з усіма відповідними структурами і відбувається переключення на нього. Виклик задачі здійснюється також у бага-тозадачній операційній системі, коли відбувається переключення між процесами. У такій системі необхідні структури вже є, і потрібно лише переключитися на них, забезпечивши збереження відповідних структур поточного процесу. За будь-якого виклику використовується захист, заснований на рівнях привілеїв.

6.1. Виклик процедур

Виконуючи будь-який програмний код, сучасні операційні системи постійно вик­ликають процедури, код яких розміщено в інших сегментах. Такі сегменти мо­жуть належати іншому програмному модулю тієї самої програми, бібліотеці або операційній системі. Процесори х86 пропонують кілька способів виклику проце­дур з інших сегментів:

  • прямий виклик процедури з непідпорядкованого сегмента;

  • прямий виклик процедури з підпорядкованого сегмента;

  • непрямий виклик процедури через шлюз.

Правила розмежування доступу на підставі привілеїв ураховують окрім, влас­не, рівнів привілеїв CPL, RPL і DPL ще й так звану підпорядкованість сегмента, що містить код процедури. Підпорядкованість сегмента задається прапорцем С у байті захисту дескриптора сегмента коду (див. табл. 10.3): С = 1 — підпоряд­кований сегмент, С Щ 0 - непідпорядкований сегмент.

Прямий виклик процедури з непідпорядкованого сегмента

Цей спосіб полягає у розміщенні в полі команди JMP або CALL селектора, який вказує на дескриптор нового кодового сегмента, того, що містить код процедури, яку викликають. Початкова адреса (точка входження) процедури визначається з базової адреси сегмента, яка знаходиться у дескрипторі, та зміщення, заданого в команді JMP або CALL.

Для такого виклику встановлено суворі правила захисту. Якщо сегмент, який викликають, є непідпорядкованим, то виклик дозволено лише тоді, коли рівень привілеїв сегмента, з якого робиться виклик, дорівнює рівню привілеїв сегмента, який викликають, тобто CPL ~ DPL Виклик процедури за умови, що CPL > DPL (тобто поточний код має нижчий рівень привілеїв, ніж код, який намагаються викликати), заборонено з очевидних міркувань захисту критичного коду з біль­шими привілеями від виклику з процедур, що мають нижчі привілеї, наприклад, для захисту процедур ОС від безконтрольного виклику з процедур користувача (безконтрольного — оскільки за такого виклику можна задати будь-яку точку входження і передати через стек будь-які параметри).

Але й протилежна ситуація, а саме виклик за умови, що CPL < DPL (тобто по­точний код має виший рівень привілеїв за код, який намагаються викликати), та­кож заборонена. Це обмеження введено зтше міркувань, що у загальному випадку привілейований код не може використовувати процедури з низькими привіле­ями, позаяк останні вважаються ненадійними.

Прямий виклик процедури з підпорядкованого сегмента

Виклик підпорядкованих сегментів — це один зі способів, у який програми з низь­ким рівнем привілеїв можуть використовувати код, що має високий рівень приві­леїв. Наприклад, це буває корисним, коли програми користувача застосовують системні бібліотеки. Виклик коду процедури, яка розміщується в підпорядковано­му сегменті, здійснюється аналогічно виклику процедур із непідпорядкованих сег­ментів (точки входження так само можна задавати в довільний спосіб). Але у разі підпорядкованого сегмента виклик здійснюється за умови, що CPL > DPL, тобто код, що викликає, має привілеї, не вищі за привілеї коду, який викликають. Під­порядкований сегмент має особливу властивість. Код із підпорядкованого сегмен­та успадковує рівень привілеїв коду, що його викликав, тому, яким би не був DPL підпорядкованого сегмента, під час виклику коду CPL не змінюється. Наприклад, код системної бібліотеки, який міститься в сегменті з DPL ш 0 виконуватиметься з CPL т 0, якщо його було викликано з ядра ОС, і з CPL = 3, якщо його було вик­ликано з програми користувача. Тож системний код, викликаний із програми ко­ристувача, буде мати обмежені можливості доступу до системних даних і достатні можливості для роботи з даними користувача.

Непрямий виклик процедури через шлюз

Можливостей, які надає виклик процедур із підпорядкованого сегмента, недос­татньо, щоб реалізувати системні виклики, позаяк потрібно не лише виконувати визначений код, а й звертатися до системних даних. Механізм контрольованого виклику процедур, які виконуються зі своїм рівнем привілеїв, вищим за той, що має поточний код, реалізується за допомогою шлюзів.

Шлюз — це спеціальний системний дескриптор (рис. 10.12, табл. 10.8). Шлюз, який може бути розташовано і в таблиціGDT, і в таблиці LDT, призначений для виклику не сегмента коду, а окремої процедури з нього. Для виклику цієї проце­дури шлюз містить адресу її точки входження — селектор сегмента і зміщення. Виклик здійснюється шляхом розміщення в полі команди JMP або CALL селек­тора, який вказує на шлюз (задане в команді зміщення не береться до уваги).

Шлюз має власний DPL, який визначає можливість доступу до нього коду: виконується умова CPL <DPL, тоді код має привілеї, не нижчі за привілеї шлюзу. Рівень DPL сегмента того коду, що викликається через шлюз, із рівнем CPL не порівнюється, натомість порівнюється із RPL селектора, що міститься у шлюзі. Якщо виклик успішний, код виконується зі своїм CPL, заданим DPL сегмента.

Таблиця 10.8. Поля шлюзу виклику процедури

Номер байта

Ширина

Символьне

Призначення 1 вміст полів

ш шлюзі

поля

позначення

(розради)

0...1

16

offset_l

Молодші 16 розрядів зміщення точки входження

2...3

16

selector

Селектор сегмента, який містить код

А

процедури

ч

біти 0...4

5

WC

Лічильник параметрів

біти 5.,.7

3

Заповнення нулями

5

Байт захисту

біти 0...3

4

Type

Тип: С (386) або 4 (286)

біт 4

у.

S

=0 — «системний»

біти 5...6

2

DPL

Рівень привілеїв шлюзу

біт 7

І

P

Щ — шлюз відкритий

=0 — шлюз закритий

ш

16

offset 1

Старші 16 розрядів зміщення точки входження

Шлюзом можна керувати: біт Р у байті захисту шлюзу використовується для його «відкривання» або «закривання».

Виклик через шлюз надає також можливість контрольовано передавати пара­метри через стек. У будь-якому процесі передбачено кілька (до трьох) стеків, кож­ний з яких відповідає певному рівню привілеїв. Під час виклику через шлюз про­цедури, яка має рівень привілеїв, відмінний від CPL, процесор створює нови^стек шляхом завантаження в регістр ss селектора, що відповідає потрібному рівню при­вілеїв (цей селектор міститься в контексті процесу TSS). У новий стек із поточного копіюється стільки 32-розрядних слів (параметрів виклику процедури), скільки вказано в полі WC шлюзу. Також у новий стек копіюється селектор старого стека, який дає змогу повернутися до процедури, з якої було здійснено виклик.