Захист пам'яті
Захист пам'яті — це спосіб контролю прав доступу до пам'яті на комп'ютері, що є частиною більшості сучасних операційних систем. Основною метою захисту пам'яті є запобігання доступу до пам'яті, яка не була виділена під поточний процес. Це не дає можливості програмним помилкам чи шкідливому програмному забезпеченню в поточному процесі впливати на інші процеси, або саму операційну систему. Спроба доступу до пам'яті, яка не належить даному процесу, спричиняє апаратне переривання (пастку), яке називають помилкою сегментації, або порушенням пам'яті. Ця помилка, зазвичай, спричиняє аварійне завершення роботи процесу, що призвів до переривання. Захист пам'яті включає додаткові техніки для забезпечення безпеки комп'ютера такі, як випадковість розташування адресного простору та захист виконуваного простору.
Методи
Сегментація
Сегментація — це поділ пам'яті комп'ютера на сегменти. Посилання на місце в пам'яті включає значення, що визначає сегмент, і зміщення в межах сегменту.
Архітектура x86 має багато особливих функцій, пов'язаних з сегментацією, які допомагають при використанні захисту пам'яті в цій архітектурі. [1] У процесорах з архітектурою x86 може бути використана Глобальна таблиця дескрипторів або Локальна таблиця дескрипторів для посилання на сегмент комп'ютерної пам'яті. Вказівники на сегменти пам'яті можуть також зберігатися в сегментних регістрах процесора. На початку процесори x86 містили 4 сегментних регістри: CS (сегмент коду), SS (сегмент стеку), DS (сегмент даних) та ES (додатковий сегмент). Пізніше було додано ще два сегментні регістри — FS та GS.[1]
Поділ на сторінки
При поділі на сторінки, адресний простір пам'яті ділиться на блоки рівного розміру, які називаються сторінками. Використовуючи апаратні засоби віртуальної пам'яті, кожна сторінка може знаходитись в будь-якому місці фізичної пам'яті комп'ютера, або бути позначеною, як захищена. Віртуальна пам'ять дозволяє отримати лінійний віртуальний адресний простір і використовувати його для доступу до блоків, які складаються з різних фрагментів адресного простору фізичної пам'яті.
Більшість архітектур комп'ютерних систем, які підтримують поділ на сторінки, також використовують сторінки, як основу захисту пам'яті.
Таблиця сторінок відображає віртуальну пам'ять на фізичну. Таблиця сторінок, зазвичай, невидима для процесу. Таблиця сторінок робить виділення додаткової пам'яті простішим, оскільки кожна нова сторінка може бути виділена в будь-якому місці фізичної пам'яті. Програма не може доступитися до сторінки, яка не була явно виділена для неї, бо кожна адреса в пам'яті вказує на сторінку, яка була виділена для цієї програми, або генерує переривання, яке називається помилкою сторінки. Сторінки, які не виділені під жодну програму, або виділені під будь-яку іншу програму, не мають ніякої адреси з точки зору поточної програми.
Переривання помилки сторінки не обов'язково означає помилку програми. Вони використовуються не тільки для захисту пам'яті. Операційна система може використовувати певний підхід при керуванні таблицею сторінок, в якому при звертанні до сторінки, що була раніше записана на диск, виникає переривання помилки сторінки. Операційна система перехоплює це переривання, підвантажує потрібні сторінки в пам'ять, після чого програма продовжує своє виконання, так ніби не сталося жодної помилки. Ця схема, відома як механізм віртуальної пам'яті, дозволяє переміщати дані в пам'яті, які в даний момент не використовуються, на диск і назад зрозумілим для програм способом. Цей механізм використовується для збільшення загальної ємності пам'яті.
У деяких системах, таких як W^X, механізм підвантаження сторінок використовується і для захисту виконуваного простору.
Ключі захисту
Механізм ключів захисту ділить фізичну пам'ять на блоки деякого розміру (напр. 4 kiB), кожен з яких має пов'язане з ним числове значення, яке називається ключем захисту. Кожен процес також має пов'язане значення ключа захисту. При доступі до пам'яті апаратними засобами перевіряється чи ключ захисту поточного процесу збігається зі значенням пов'язаним з блоком даних, до якого відбувається доступ; якщо ж ні, то генерується виняток. Цей механізм був представлений в архітектурі System/360. Сьогодні він доступний у архітектурі System z та активно використовується операційною системою System z і її підсистемами.
Механізм ключів захисту System z описаний вище використовує асоціацію з фізичними адресами. Він відрізняється від механізму ключів захисту, який використовувався процесорами Intel Itanium і Hewlett-Packard Precision Architecture (HP/PA, також відомий як PA-RISC), який використовує асоціацію з віртуальними адресами і дозволяє пов'язувати кілька ключів до одного процесу.
У архітектурах процесорів Itanium і PA записам буфера асоціативної трансляції (TLB) відповідають ключі(key) (Itanium) або ідентифікатори доступу(access id) (PA). Процес, який виконується, має кілька регістрів для ключів захисту (16 для Itanium[2], 4 для HP/PA[3]). Ключ запису TLB, вибраний за допомогою віртуальної адреси, порівнюється з кожним регістром ключів захисту. Якщо хоча б якийсь з них має відповідне значення, то після виконання додаткових перевірок доступ дозволяється. Якщо жодний не підходить, то генерується помилка або виняток. Обробник програмних помилок, при бажанні, може порівняти цей ключ з більшим списком ключів, які підтримує програмне забезпечення. Таким чином, регістри ключів захисту в середині процесора можуть розглядатися, як програмно-керований кеш більшого списку ключів, асоційованих з процесом.
PA має 15-18 біт ключа; Itanium — як мінімум 18. Ключі зазвичай прив'язані до доменів захисту (protection domains), таких як бібліотеки, модулі та інші.
У архітектурі x86, ключі захисту[4] дозволяють позначати віртуальні адреси для сторінок користувача, використовуючи будь-який з 16 ключів захисту. Всі сторінки, позначені тим самим ключем, утворюють домен захисту. Новий регістр містить права доступу, асоційовані з кожним доменом захисту. Операції зчитування та запису перевіряють права доступу як у таблиці сторінок, так і ключі захисту, асоційовані з доменом захисту віртуальної адреси, і дозволяють доступ тільки тоді, коли в обох схемах доступ дозволений. Права доступу ключів захисту можуть бути визначені з користувацького простору, що дозволяє програмам на пряму обмежувати доступ до даних без втручання операційної системи.
Оскільки ключі захисту асоційовані з віртуальними адресами, то домени захисту можуть бути різними в різних адресних просторах, і процеси, які виконуються в різних адресних просторах можуть використовувати всі 16 доменів.
Симуляція сегментації
Симуляція — це використання програми контролю для інтерпретації інструкцій машинного коду деяких архітектур комп'ютерних систем. Такий симулятор інструкцій може забезпечити захист пам'яті використовуючи схему, схожу на сегментацію, при цьому перевіряючи цільову адресу та довжину кожної інструкції в реальному часі перед власне виконанням потрібних команд. Симулятор повинен обчислити цільову адресу та довжину інструкції та порівняти їх зі списком дійсних адресних областей, які він зберігає для поточного потоку, таких як будь-який блок динамічної пам'яті отриманий з часу запуску потоку, або будь-який слот дійсної спільної статичної пам'яті. Значення «дійсності» може змінюватися впродовж життєвого циклу потоку в залежності від контексту. Деколи може бути дозволено змінювати статичний блок пам'яті, а деколи ні, зважаючи на поточний режим виконання, який може залежати або не залежати від ключа запису, або стану інспектора запису. В загальному не рекомендується використовувати цей метод захисту пам'яті на процесорах, де існують більш адекватні засоби, оскільки він вимагає досить великих обчислювальних потужностей комп'ютера. Проте, цей метод зазвичай використовується для відлагодження та тестування, щоб забезпечити досить високий рівень деталізації для загальних, в іншому випадку, порушень пам'яті. Він може точно вказати, яка саме інструкція намагається перезаписати певну ділянку пам'яті, що може мати однаковий ключ з ділянкою пам'яті без захисту.
Адресування на основі Capability
Адресування на основі Capability (Capability-based addressing) — метод, який не використовується в сучасних комерційних комп'ютерах. У цьому методі вказівники замінені захищеними об'єктами (які називаються capabilities), що можуть бути створені лише використовуючи привілейовані інструкції, які можуть бути виконані лише ядром операційної системи, або деякими іншими процесами з правами на це. Такий підхід дає ядру можливість ефективно контролювати, який процес має доступ, до якого об'єкта в пам'яті, без потреби використовувати окремі адресні простори або перемикачі контексту. Лише кілька комерційних проектів використовували цей тип захисту: Plessey System 250, IBM System/38, архітектура Intel iAPX 432 та KeyKOS. Підходи з використанням capability широко використовуються в дослідницьких системах таких, як EROS і Combex DARPA Browser. Вони також використовуються в деяких віртуальних машинах, найбільш помітно в Smalltalk і Java. В даний час, в Кембриджському університеті працюють над заснованим DARPA проектом CHERI для створення сучасного capability-комп'ютера, що буде підтримувати і програми, розроблені для інших систем.
Оцінка рівня захисту
Рівень захисту певної системи може бути оцінений за допомогою вимірювання його близькості до принципу найменших привілеїв.[5]
Захист пам'яті в різних операційних системах
Різні операційні системи використовують різні форми захисту або відокремлення пам'яті. Хоча захист пам'яті був загальноприйнятий на більшості мейнфреймів і багатьох мікрокомп'ютерних системах з 1960х, справжнє відокремлення пам'яті не використовувалося в операційних системах для домашніх комп'ютерів до виходу OS/2 в 1987 році. У попередніх системах такий недостатній захист, навіть використовувався як форма взаємодії між процесами, використовуючи вказівники. В сімействі операційних систем Windows 9x процеси можуть доступатися до системної пам'яті.[6]
Деякі операційні системи, які реалізують захист пам'яті:
- Microsoft Windows, починаючи з Windows NT 3.1;
- OS/2;
- OS-9, як необов'язковий модуль;
- Unix-подібні системи, включаючи Solaris, Linux, BSD, Mac OS X, iOS і GNU Hurd;
- Plan9 і Inferno, створені в Bell Labs як послідовники Unix.
На Unix-подібних системах, виклик mprotect використовується для керування захистом пам'яті.[7]
Див. також
- Storage violation, для порушення захисту пам'яті
- Separation of protection and security
- Захищений режим
Примітки
- Intel (July 2008). Intel 64 and IA-32 Architectures Software Developer's Manuals: Volume 3A: System Programming Guide, Part 1 (PDF). Intel. Процитовано 21 серпня 2008.
- Keys in Itanium. Архів оригіналу за 28 листопада 2007. Процитовано 24 травня 2015.
- Memory protection in HP PA-RISC. Архів оригіналу за 7 червня 2011. Процитовано 24 травня 2015.
- Intel Software Developer Manual
- Cook, D.J. Measuring memory protection, accepted for 3rd International Conference on Software Engineering, Atlanta, Georgia, May 1978.
- Windows 9x does not have true memory protection. Everything2. 24 червня 2000. Процитовано 29 квітня 2009.
- mprotect. The Open Group Base Specifications Issue 6. The Open Group.
Посилання
- Intel Developer Manuals — in-depth information on memory protection for Intel based architectures.