- •1.1. Поняття операційної системи, її призначення та функції
- •1.1.1. Поняття операційної системи
- •1.1.2. Призначення операційної системи
- •1.1.3. Операційна система як розширена машина
- •1.1.4. Операційна система як розподілювач ресурсів
- •1.2. Історія розвитку операційних систем
- •1.3. Класифікація сучасних операційних систем
- •1.4. Функціональні компоненти операційних систем
- •1.4.1. Керування процесами й потоками
- •1.4.2. Керування пам'яттю
- •1.4.3. Керування введенням-виведенням
- •1.4.4. Керування файлами та файлові системи
- •1.4.5. Мережна підтримка
- •1.4.6. Безпека даних
- •1.4.7. Інтерфейс користувача
- •2.1. Базові поняття архітектури операційних систем
- •2.1.1. Механізми і політика
- •2.1.2. Ядро системи. Привілейований режим і
- •2.2. Реалізація архітектури операційних систем
- •2.2.1. Монолітні системи
- •2.2.2. Багаторівневі системи
- •2.2.3. Системи з мікроядром
- •2.2.4. Концепція віртуальних машин
- •2.3.1. Взаємодія ос і апаратного забезпечення
- •2.3.2. Взаємодія ос і виконуваного програмного коду
- •2.4.1. Базова архітектура unix
- •2.4.2. Архітектура Linux
- •2.5. Особливості архітектури: Windows хр
- •2.5.1. Компоненти режиму ядра
- •2.5.2. Компоненти режиму користувача
- •2.5.3. Об'єктна архітектура Windows хр
- •3.1. Базові поняття процесів і потоків
- •3.1.1. Процеси і потоки в сучасних ос
- •3.1.2. Моделі процесів і потоків
- •3.1.3. Складові елементи процесів і потоків
- •3.2. Багатопотоковість та її реалізація
- •3.2.1. Поняття паралелізму
- •3.2.2. Види паралелізму
- •3.2.3. Переваги і недоліки багатопотоковості
- •3.2.4. Способи реалізації моделі потоків
- •3.3. Стани процесів і потоків
- •3.4. Опис процесів і потоків
- •3.4.1. Керуючі блоки процесів і потоків
- •3.4.2. Образи процесу і потоку
- •3.5. Перемикання контексту й обробка переривань
- •3.5.1. Організація перемикання контексту
- •3.5.2. Обробка переривань
- •3.6. Створення і завершення процесів і потоків
- •3.6.1.Створення процесів
- •3.6.2.Ієрархія процесів
- •3.6.3.Керування адресним простором під час створення процесів
- •3.6.4. Особливості завершення процесів
- •3.6.5. Синхронне й асинхронне виконання процесів
- •3.6.6. Створення і завершення потоків
- •4.1. Загальні принципи планування
- •4.1.1. Особливості виконання потоків
- •4.1.2. Механізми і політика планування
- •4.1.3. Застосовність принципів планування
- •4.2. Види планування
- •4.2.1. Довготермінове планування
- •4.2.2. Середньотермінове планування
- •4.2.3. Короткотермінове планування
- •4.3. Стратегії планування. Витісняльна і невитісняльна багатозадачність
- •4.4. Алгоритми планування
- •4.4.1. Планування за принципом fifo
- •4.4.2. Кругове планування
- •4.4.3. Планування із пріоритетами
- •4.4.4. Планування на підставі характеристик подальшого виконання
- •4.4.5. Багаторівневі черги зі зворотним зв'язком
- •4.4.6. Лотерейне планування
- •4.5. Реалізація планування в Linux
- •4.5.1. Планування процесів реального часу в ядрі
- •6.1. Види міжпроцесової взаємодії
- •6.1.1.Методи розподілюваної пам'яті
- •6.1.2.Методи передавання повідомлень
- •6.1.3.Технологія відображуваної пам'яті
- •6.1.4.Особливості міжпроцесової взаємодії
- •6.2. Базові механізми міжпроцесової взаємодії
- •6.2.1. Міжпроцесова взаємодія на базі спільної пам'яті
- •6.2.2. Основи передавання повідомлень
- •6.2.3. Технології передавання повідомлень
- •8.1. Основи технології віртуальної пам'яті
- •8.1.1. Поняття віртуальної пам'яті
- •8.1.2. Проблеми реалізації віртуальної пам'яті. Фрагментація пам'яті
- •8.1.4. Підхід базового і межового регістрів
- •8.2. Сегментація пам'яті
- •8.2.1. Особливості сегментації пам'яті
- •8.2.2. Реалізація сегментації в архітектурі іа-32
- •8.3. Сторінкова організація пам'яті
- •8.3.1. Базові принципи сторінкової організації пам'яті
- •8.3.2. Порівняльний аналіз сторінкової організації пам'яті та сегментації
- •8.3.3. Багаторівневі таблиці сторінок
- •8.3.4. Реалізація таблиць сторінок в архітектурі іа-32
- •8.3.5. Асоціативна пам'ять
- •8.4. Сторінково-сегментна організація пам'яті
- •8.5. Реалізація керування основною пам'яттю: Linux
- •8.5.1. Використання сегментації в Linux. Формування логічних адрес
- •8.5.2. Сторінкова адресація в Linux
- •8.5.3. Розташування ядра у фізичній пам'яті
- •8.5.4.Особливості адресації процесів і ядра
- •8.5.5.Використання асоціативної пам'яті
- •8.6. Реалізація керування основною пам'яттю: Windows хр
- •8.6.1.Сегментація у Windows хр
- •8.6.2.Сторінкова адресація у Windows хр
- •8.6.3.Особливості адресації процесів і ядра
- •8.6.4. Структура адресного простору процесів і ядра
- •11.1. Поняття файла і файлової системи
- •11.1.1. Поняття файла
- •11.1.2.Поняття файлової системи
- •11.1.3.Типи файлів
- •11.1.4. Імена файлів
- •11.2. Організація інформації у файловій системі
- •11.2.1. Розділи
- •11.2.2. Каталоги
- •11.2.3. Зв'язок розділів і структури каталогів
- •11.3. Зв'язки
- •11.3.1. Жорсткі зв'язки
- •11.3.2. Символічні зв'язки
- •11.4. Атрибути файлів
- •11.5. Операції над файлами і каталогами
- •11.5.1. Підходи до використання файлів процесами
- •12.1. Базові відомості про дискові пристрої
- •12.1.1. Принцип дії жорсткого диска
- •12.1.2. Ефективність операцій доступу до диска
- •12.2. Розміщення інформації у файлових системах
- •12.2.1. Фізична організація розділів на диску
- •12.2.2. Основні вимоги до фізичної організації файлових систем
- •12.2.3. Неперервне розміщення файлів
- •12.2.4. Розміщення файлів зв'язними списками
- •12.2.5. Індексоване розміщення файлів
- •12.2.6. Організація каталогів
- •15.1. Завдання підсистеми введення-виведення
- •15.1.1. Забезпечення ефективності доступу до пристроїв
- •15.1.2. Забезпечення спільного використання зовнішніх пристроїв
- •15.1.3. Універсальність інтерфейсу прикладного програмування
- •15.1.4. Універсальність інтерфейсу драйверів пристроїв
- •15.2. Організація підсистеми введення-виведення
- •15.2.1. Символьні, блокові та мережні драйвери пристроїв
- •15.2.2. Відокремлення механізму від політики за допомогою
- •15.3. Способи виконання операцій введення-виведення
- •15.3.1. Опитування пристроїв
- •15.3.2. Введення-виведення, кероване перериваннями
- •15.3.3. Прямий доступ до пам'яті
- •15.4. Підсистема введення-виведення ядра
- •15.4.1. Планування операцій введення-виведення
- •15.4.2. Буферизація
- •15.7. Керування введенням-виведенням: unix і Linux
- •15.7.1. Інтерфейс файлової системи
- •15.7.2. Передавання параметрів драйверу
- •15.7.3. Структура драйвера
- •15.7.4. Виконання операції введення-виведення для пристрою
- •15.8. Керування введенням-виведенням: Windows хр
- •15.8.1. Основні компоненти підсистеми введення-виведення
- •15.8.2. Виконання операції введення-виведення для пристрою
- •15.8.3. Передавання параметрів драйверу пристрою
- •17.1. Термінальне введення-виведення
- •17.1.1. Організація термінального введення-виведення
- •17.1.3. Термінальне введення-виведення у Win32 api
- •17.2. Командний інтерфейс користувача 17.2.1.
- •17.2.2. Переспрямування потоків введення-виведення
- •17.2.3. Використання каналів
- •17.3. Графічний інтерфейс користувача
- •17.3.1. Інтерфейс віконної та графічної підсистеми Windows хр
- •17.3.2. Система X Window
- •17.4. Процеси без взаємодії із користувачем
- •17.4.1. Фонові процеси на основі posix
- •17.4.2. Служби Windows хр
- •16.1. Загальні принципи мережної підтримки
- •16.1.1. Рівні мережної архітектури і мережні сервіси
- •16.1.2. Мережні протоколи
- •16.2. Реалізація стека протоколів Інтернету
- •16.2.1. Рівні мережної архітектури tcp/ip
- •16.2.2. Канальний рівень
- •16.2.3. Мережний рівень
- •16.2.4. Транспортний рівень
- •16.2.5. Передавання даних стеком протоколів Інтернету
- •16.3. Система імен dns
- •16.3.1. Загальна характеристика dns
- •16.3.2. Простір імен dns
- •16.3.3. Розподіл відповідальності
- •16.3.4. Отримання ір-адрес
- •16.3.5. Кешування ір-адрес
- •16.3.6. Типи dns-ресурсів
- •16.4. Програмний інтерфейс сокетів Берклі
- •16.4.1. Особливості роботи з адресами
- •16.4.2. Створення сокетів
- •16.4.3. Робота з потоковими сонетами
- •16.4.4. Введення-виведення з повідомленням
- •19.1. Загальні принципи завантаження ос
- •19.1.1. Апаратна ініціалізація комп'ютера
- •19.1.2. Завантажувач ос
- •19.1.3. Двоетапне завантаження
- •19.1.4. Завантаження та ініціалізація ядра
- •19.1.5. Завантаження компонентів системи
- •19.2. Завантаження Linux
- •19.2.1. Особливості завантажувача Linux
- •19.2.2. Ініціалізація ядра
- •19.2.3. Виконання процесу init
- •19.3. Завантаження Windows хр
- •20.1. Багатопроцесорні системи
- •20.1.1. Типи багатопроцесорних систем
- •20.1.2. Підтримка багатопроцесорності в операційних системах
- •20.1.3. Продуктивність багатопроцесорних систем
- •20.1.4. Планування у багатопроцесорних системах
- •20.1.5. Спорідненість процесора
- •20.1.6. Підтримка багатопроцесорності в Linux
- •20.1.7. Підтримка багатопроцесорності у Windows хр
- •20.2. Принципи розробки розподілених систем
- •20.2.1. Віддалені виклики процедур
- •20.2.2. Використання Sun rpc
- •20.2.3. Використання Microsoft rpc
- •20.2.4. Обробка помилок і координація в розподілених системах
- •20.3. Розподілені файлові системи
- •20.3.1. Організація розподілених файлових систем
- •20.3.2. Файлова система nfs
- •20.3.3. Файлова система Microsoft dfs
- •20.4. Сучасні архітектури розподілених систем
- •20.4.1. Кластеры системи
- •20.4.2. Grid-системи
- •18.1. Основні завдання забезпечення безпеки
- •18.2. Базові поняття криптографії
- •18.2.1. Поняття криптографічного алгоритму і протоколу
- •18.2.2. Криптосистеми з секретним ключем
- •18.2.3. Криптосистеми із відкритим ключем
- •18.2.4. Гібридні криптосистеми
- •18.2.5. Цифрові підписи
- •18.2.6. Сертифікати
- •18.3. Принципи аутентифікаціїі керування доступом
- •18.3.1. Основи аутентифікації
- •18.3.2. Основи керування доступом
- •18.4. Аутентифікація та керування доступом в unix
- •18.4.1. Облікові записи користувачів
- •18.4.2. Аутентифікація
- •18.4.3. Керування доступом
- •18.5. Аутентифікація і керування доступом у Windows xp
- •18.5.1. Загальна архітектура безпеки
- •18.5.2. Аутентифікація
- •18.5.3. Керування доступом
- •18.6. Аудит
- •18.6.1. Загальні принципи організації аудиту
- •18.6.2. Робота із системним журналом unix
- •18.6.3. Журнал подій Windows xp
- •18.7. Локальна безпека даних
- •18.7.1. Принципи шифрування даних на файлових системах
- •18.7.2. Підтримка шифрувальних файлових систем у Linux
- •18.7.3. Шифрувальна файлова система Windows xp
- •18.8. Мережна безпека даних
- •18.8.1. Шифрування каналів зв'язку
- •18.8.2. Захист інформації на мережному рівні
- •18.8.3. Захист інформації на транспортному рівні
- •18.9. Атаки і боротьба з ними
- •18.9.1. Переповнення буфера
- •18.9.2. Відмова від обслуговування
- •18.9.3. Квоти дискового простору
- •18.9.4. Зміна кореневого каталогу застосування
18.4.3. Керування доступом
Реалізація керування доступом до файлів у UNIX збереглася, майже не змінившись від ранніх версій системи. Фактично вона є скороченою реалізацією списків контролю доступу.
Основні принципи реалізації
Наведемо принципи реалізації керування доступом в UNIX.
1. Усі файли і каталоги в UNIX мають власника (owner), що належить до певної групи (group), і права доступу (permissions).
2. Розрізняють три категорії прав доступу: для читання, записування і виконання. Для звичайних файлів назви прав відповідають їхньому змісту (зазначимо, що ядро UNIX намагатиметься завантажити у пам'ять і виконати будь-який файл, на який у поточного користувача є права на виконання).
3. Для каталогів задають той самий набір прав, але вони відрізняються за змістом від прав для файлів:
♦ право читання для каталогу означає можливість отримання списку імен файлів, що містяться в ньому (тобто читання вмісту каталогу як файла);
♦ право записування в каталог означає можливість створення в каталозі нових файлів і вилучення наявних (тобто записування в каталог як у файл); зазначимо, що для вилучення файла прав на нього самого можна й не мати — достатньо прав на каталог, де він зберігається;
♦ право виконання означає можливість пошуку в каталозі, тобто доступу до окремих файлів.
Із цього випливає, що якщо для каталогу задаються права «тільки для виконання», то доступ до окремих файлів у ньому можна отримати, коли знати їхні імена, список же всіх файлів отримати буде неможливо. Таке задання прав використовують, аби сторонні особи не могли випадково виявити файли, які, однак, потребують спільного доступу. 3 іншого боку, якщо задати права «тільки для читання», можна переглядати список файлів каталогу, але доступ до окремих файлів стане неможливий.
4. Права кожної категорії задають окремо для власника файла, для користувачів його групи і для всіх інших користувачів усього дев'ять базових комбінацій прав; можна сказати, що із кожним файлом пов'язаний список контролю доступу із трьох елементів.
Приклад задання прав
У UNIX-системах є стандартна утиліта виведення вмісту каталогу, яку називають 1 s. Ось фрагмент результату виклику цієї утиліти для каталогу
drwxr-xr-x 2 shekvl osbook 1024 Sep 8 02:26 dir/
-rwxr-x--- 1 shekvl osbook 11370 Sep 3 13:18 test*
-rw....... 1 shekvl osbook 149 Sep 3 13:41 test.c
Першим полем ліворуч є поле атрибутів файла, формат якого розглянемо докладніше. Перший стовпчик цього поля визначає тип файла (для каталогів у ньому стоятиме символ d, для звичайних файлів - прочерк, для символічних зв'язків — 1).
Далі йде символьне відображення прав доступу. Воно складається із трьох трійок символів rwx. Ці трійки визначають (зліва направо): права власника, групи і всіх інших користувачів. У кожній трійці символ г означає право на читання, w - на записування, x - на виконання. Якщо відповідного права немає, то замість символу стоятиме прочерк.
У наведеному списку файлів:
♦ для каталогу dir задані усі права для власника, а також права на читання і виконання для групи та інших користувачів; це означає, що додавання і вилучення файлів дозволене власникові каталогу, інші дії — усім;
♦ виконуваний файл test може бути прочитаний і запущений власником і членами його групи, записаний — тільки власником, усі інші користувачі доступу до нього не мають;
♦ файл test.c може бути прочитаний і записаний тільки його власником, інші користувачі жодних прав на нього не мають. '
Програмний інтерфейс роботи із правами доступу
Для зміни прав доступу до файла використовують системні виклики chmod() (файл задають іменем) і fchmod() (файл задають дескриптором), для зміни власника і групи - chown() і fchown(). Є також утиліти chmod, chown і chgrp.
Опишемо особливості використання виклику chmod():
int chmod(const char *pathname, int mode);
Параметр mode визначає права доступу. Вони можуть бути компактно записані у вісімковому числовому відображенні. Елемент списку контролю доступу відображають сумою трьох чисел: 1 - для права на виконання, 2 - на записування, 4 -на читання. Тому, наприклад, 0 означає відсутність прав, 5 - читання і виконання, 6 - читання і записування, 7 - усі права. Увесь список відображають сукупністю трьох чисел (у тому самому порядку, що і для символьного відображення); так, права для dir у цьому випадку були б задані як 755, для test - 750, для test.c - 600.
Ось приклад використання виклику chmod() для задання прав, що визначають можливість читання і записування для власника, читання для групи і відсутність доступу для інших користувачів:
chmod("./test.c". 0640);
Як було видно раніше, таке саме числове відображення може бути передане як режим створення файла у системні виклики open(), mkfifo() тощо:
int fd - open("./myfile.txt". 0_RDWR | 0_CREAT. 0640);
Для отримання прав доступу до заданого файла необхідно скористатися системними викликами stat() або fstat():
struct stat attrs;
stat("./myfile.txt". &attrs):
// S_IFMT задає маску, що- визначає всю інформацію, крім прав доступу
printf("права доступу: *o\n", attrs.st_mode & -S_IFMT);
Для перевірки того, чи є в поточного процесу права на доступ до заданого файла, використовують системний виклик access():
int access(const char *pathname, int mode);
де: pathname - повний шлях до файла;
mode - тип перевірки (ROK - наявність права на читання, WOK - на записування, XOK - на виконання, FOK - перевірка на наявність файла). Виклик access() повертає 0 за наявності прав, -1 - за їхньої відсутності.
if (access("myfile.txt". R_0K) == -1)
printf("HeMae права на читання файла\п");
Недоліки схеми керування доступом UNIX
Описана схема керування доступом проста для розуміння, але багато в чому обмежена. Основне обмеження пов'язане із довжиною списку контролю доступу (3 елементи). Звідси виникають такі проблеми, як неможливість надання конкретному користувачу прав доступу до файла без створення для нього окремої групи (що не можливо зробити без наявності прав адміністратора).
Останнім часом в UNIX-системах усе ширше використовують списки контролю доступу без обмеження кількості елементів (у Linux їхня реалізація стала доступна у ядрі 2.6).
Виконання із правами власника
Права доступу для файлів і каталогів у UNIX дають змогу задавати додаткові біти. Одним із таких бітів є setuid-біт. Для його задання у числовому зображенні ліворуч потрібно додати 4 і обов'язково задати право виконання для власника (наприклад, задати права як 4755). Символьне відображення в цьому разі має такий вигляд: rwsr-xr-x.
Setuid-біт задає для файла режим виконання із правами власника. Під час запуску такого файла на виконання створюють setuid-процес, для якого ui d відповідає користувачу, що запустив програму, a euid - власникові виконуваного файла. Ядро OC під час авторизації доступу до файлів завжди використовує euid. У результаті маємо, що setuid-процес отримує під час доступу до файлів такі самі права, що і власник відповідного виконуваного файлу.
Прикладом використання такого біта є програма passwd, що дає змогу користувачу задати пароль на вхід у систему. 3 одного боку, вона має бути доступна для запуску будь-якому користувачу системи, з іншого - під час зміни пароля їй потрібно перезаписувати файли /etc/passwd або /etc/shadow, що вимагає виконання із правами root. Щоб задовольнити ці вимоги, для виконуваного файла passwd власником вказують root і задають setuid-біт.
Для визначення ефективного ідентифікатора користувача для поточного процесу використовують системний виклик geteuid():
// для setuid-програми uid і euid можуть розрізнятися printf("uid=*d. euid=fcdVn", getuid(). Geteuid();
Застосування, які виконуються із правами root, можуть переходити до виконання із правами інших користувачів за допомогою системного виклику setuid(), що змінює значення ui d і eui d для поточного процесу:
struct passwd *pw = getpwnam("nobody");
setuid(pw->pw_uid);
// тепер процес виконується
// з правами користувача nobody
Таку технологію, наприклад, використовують у веб-сервері Apache, основний процес якого запускають із правами root, після чого він виконує підготовчі дії, а потім створює нащадків для обслуговування запитів, які негайно переходять до виконання із правами непривілейованого користувача.
Задання параметра umask
Залишається з'ясувати, які права задають для нових файлів. Цим керує встановлення прав за замовчуванням. Якщо його не змінювати, каталоги створюватимуть із правами 777 (усі дії дозволені всім), а файли - із правами 666 (усі дії, крім виконання, дозволені всім).
Змінити встановлення прав можна, задаючи спеціальний параметр umask за допомогою системного виклику umask() або однойменної утиліти. Під час створення нового файла значення цього параметра побітово відніматиметься від 666 (вісімкового) для звичайних файлів і з 777 — для каталогів; права для файла будуть результатом цього віднімання. Наведемо приклад виклику umask():
umask(022);
Після виконання цього виклику файли створюються із правами 644, а каталоги — із правами 755. Найчастіше задають значення umask, що дорівнюють 022 і 002, задання 077 спричинятиме створення файлів, закритих для всіх, крім власника.
Пщтримка можливостей у Linux
Ядро Linux дає змогу задавати списки можливостей для процесів, починаючи з версії 2.4. Структура таких списків аналогічна до описаної у розділі 18.3.2.
Наявність підтримки можливостей дозволяє обійти обмеження концепції «все або нічого», коли процесу потрібна тільки частина прав суперкористувача і він змушений брати їх усі, ризикуючи нашкодити системі. Тепер такий процес може задати набір можливостей, що точно описує права, які йому потрібні.