Ia-32 перемикання стеків, dev64

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

Кожне завдання має визначати до 4-х стеків: один для прикладного коду (що працює на рівні привілеїв 3), і один для кожного іншого рівня 2, 1 і 0. Якщо тільки два рівня привілеїв використовуються, тоді два стека 3 і 0 повинні бути визначені . Кожен з стеків знаходиться в окремому сегменті і ідентифікується селектором сегменту і покажчиком стека.

Селектор сегмента і покажчик стека для стека рівня привілеїв 3 знаходяться в регістрах SS і ESP відповідно при виконанні коду на рівні привілеїв 3 і автоматично зберігаються в стеці викликає процедури при перемиканні стека.

Покажчики на стеки рівнів привілеїв 0, 1 і 2 зберігаються в TSS для поточної виконуваної завдання (див. Рис. 7-2).

Ia-32 перемикання стеків, dev64

(Малюнок з керівництва Intel)

Кожен зі згаданих покажчиків складається з селектора сегмента і покажчика стека (завантаженого в регістр ESP). Початкові покажчиками є значеннями тільки для читання. Процесор не змінює їх при виконанні завдання. Вони використовуються тільки для створення нових стеків при викликах до більш привілейованим сегментам. Ці стеки disposed (знищуються) при поверненні з викликається процедури. При наступному виклику, новий стек створюється з використанням початкового покажчика стека. TSS не визначає стека для рівня привілеїв 3, поспольку процесор не дозволяє передачу управління з процедур, які працюють на рівнях привілеїв 0, 1, 2 на рівень привілеїв 3 будь-яким способом, крім повернення (return).

Операційна Система відповідає за створення стеків і дескрипторів стекових сегментів для всіх використовуваних рівнів привілеїв і за завантаження початкових покажчиків на ці стеки в TSS. Кожен стек повинен бути доступний для читання / запису (це повинно бути дозволено в поле типу в його сегментном дескрипторі) і повинен надавати достатньо місця (визначається полем limit) для зберігання наступних сутностей:

  • Вмісту SS, ESP, CS і EIP регістрів викликає процедури
  • Параметрів і часових змінних необхідних для викликається процедури
  • Регістр прапорів EFLAGS і код помилки, при явному програмному виклику (implicit calls) обробника переривання або виключення.

Стек вимагає місця достатнього для зберігання великої кількості фреймів подібного типу, оскільки процедури часто викликають інші процедури, операційна система може підтримувати вкладеність безлічі переривань. Кожен стек повинен надавати достатньо місця для зберігання даних в найгіршому сценарії для даного рівня привілеїв. (Навіть якщо операційна система не використовує механізм апаратної багатозадачності, вона все одно повинна створити хоча б один TS для управління перемикання стеками). Коли виклик процедури через шлюз виклику призводить до зміни рівня привілеїв, процесор виконує наступні кроки для перемикання стеків і починає виконання викликаної процедури з новим рівнем привілеїв.

  1. Використовує DPL кодового сегмента призначення (новий CPL) для вибору покажчика на новий стек (селектор сегмента і покажчик стека) з TSS.
  2. Читає селектор сегмента і покажчик стека для стека на який потрібно переключитися з поточного TSS. Будь-які порушення лімітів виявлені при читанні селектора стекового сегмента, покажчика стека або дескриптора стекового сегмента призводять до генерації виключення invalid TSS (#TS).
  3. Перевіряє дескриптор стекового сегмента на відповідність типу і рівень привілеїв і генерує виняток invalid TSS (#TS) при виявленні порушень.
  4. Тимчасово зберігає поточні значення SS і ESP регістрів.
  5. Завантажує нові значення сегментний селектора і покажчик стека в SS і EIP.
  6. Поміщає тимчасово збережені значення для SS і EIP регістрів (для викликає процедури) в новий стек (див. Рис 5-13).
  7. Копіює кількість параметрів вказане полем parameter count шлюзу виклику з стека викликає процедури в новий стек. Якщо кількість (count) дорівнює нулю, параметри чи не копіюються.
  8. Поміщає instruction pointer (поточні значення регістрів CS і EIP) в новий стек.
  9. Завантажує селектор сегмента для нового кодового сегмента і новий покажчик інструкції EIP з шлюзу виклику в регістри CS, EIP і починає виконання викликаної процедури.

Cм. опис інструкції CALL в розділі 3, Довідника інструкцій (Instruction Set Reference) в IA-32 Intel Architecture Software Developer's Manual, Volume 2 для детального опису перевірок рівнів привілеїв та інших перевірок захисту, які виконуються процесором при далеких виклики через шлюз виклику.

Ia-32 перемикання стеків, dev64

(Ілюстрація з керівництва Intel)

Поле parameter count з шлюзу виклику визначає чіскло одиниць даних (до 31) які процесор повинен скопіювати з стека викликає процедури в стек викликається процедури. Якщо потрібно більше 31 елемента, один з параметрів може бути покажчиком на структуру даних або записані часові SS, ESP регістрів можуть бути використані для доступу до параметрів у «старому стеку». Розмір одиниць даних переданих викликається процедурою залежить від розміру шлюзу виклику (як описано в розділі 5.8.3 «Шлюзи викликів»).

Share this:

Схожі статті