Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 [ 14 ] 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

вызов mknod, доступный только суперпользователю. Если же владельцем программы mkdir будет суперпользователь и для нее будут установлены права доступа 04755, обычные пользователи смогут запускать ее и тем самым вызывать mknod, но весьма ограниченным образом.

Когда процесс исполняет файл, в разрешениях которого выставлены биты SETUID или SETGID, эффективный идентификатор пользователя или группы отличаются от настоящих значений. Но иногда для процесса важно знать, чему равны эффективные и реальные значения uid и gid. Чтобы получить эту информацию, процесс может делать системные вызовы getuid и getgid. Оба этих вызова возвращают одновременно и эффективный, и реальный идентификаторы, а чтобы получать эти значения по отдельности, служат четыре библиотечные процедуры: getuid, getgid, geteuid, getegid. Первые две возвращают реальные значения, вторые две - эффективные.

Для обычных пользователей единственный способ изменить свой идентификатор - запустить программу, у которой установлен бит SETUID. Но для суперпользователей существует и другая возможность, предоставляемая системным вызовом setuid, устанавливающим одновременно реальное и эффективное значение uid. Вызов setgid, соответственно, устанавливает реальное и эффективное значение gid. Кроме того, суперпользователь может менять владельца файла при помощи системного вызова chown. Другими словами, у суперпольователя есть множество возможностей нарушать все возможные правила защиты. Это объясняет, почему многие студенты посвящают столь много времени попыткам стать суперпользователем.

Два последних системных вызова из данной категории могут делаться и обычными процессами. Первый из них, umask, устанавливает системную битовую маску, применяемую для маскирования битов прав доступа к файлу при его создании. Если сделать вызов

umask(022):

то при вызовах creat или mknod в правах доступа к создаваемому объекту будут маскироваться биты 022. Иначе говоря, вызов

creatCfile . 0777):

создаст файл с правами доступа 0755, а не 0777. Кроме того, битовая маска наследуется дочерними процессами, поэтому, если оболочка сразу после входа сделает вызов umask, ни одна из запущенных пользователем в этой сессии программ не сможет создать файл, который может изменить другой пользователь.

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

Следовательно, необходимо иметь возможность узнать, разрешен ли доступ для реального (а не эффективного) uid. Это можно сделать с помощью системного вызова access. Чтобы проверить возможность чтения, параметр mode должен быть равен 4, записи - 2 и исполнения - 1. Эти значения можно комбинировать. Например, если mode равен 6, то вызов вернет О, если разрешены и запись.



и чтение. В противном случае вызов вернет -1. Если параметр mode равен О, то делается проверка того, что файл существует и возможен обзор ведущих к нему директорий.

1.4.6. Системные вызовы для работы со временем

Для работы с часами у MINIX есть четыре системных вызова. Вызов time возвращает текущее время в секундах, причем нулем считается полночь 1 января 1970 года (имеется в виду начало дня, а не его конец). Кроме того, чтобы считывать значение системного таймера, нужно иметь возможность сначала это значение установить. Возможность установить часы дает вызов stime, доступный только суперпользователю. Третий вызов - utime, он позволяет владельцу файла изменить значение времени, записанное в i-узле файла. У этого вызова довольно офаниченная область применения, но некоторым профаммам он нужен, например, профамма touch устанавливает время в i-узле файла в соответствие с текущим значением времени.

Наконец, есть вызов times, позволяющий узнать, сколько времени процессор провел, исполняя процесс, и сколько времени потрачено на систему (то есть на обработку системных вызовов). Кроме того, суммируется и возвращается общее время системы и процесса для всех дочерних процессов.

1.5. Структура операционной системы

Теперь, когда мы уже видели, как выглядят операционные системы снаружи (то есть мы знакомы с профаммным интерфейсом), самое время заглянуть внутрь. Чтобы получить представление обо всем спектре возможных вариантов, в следующих разделах мы исследуем четыре различные использующиеся (или использовавшихся ранее) структуры. Исследование это нельзя назвать всесторонним, здесь лишь рассматриваются несколько моделей, применявшихся на практике в разных системах. Их четыре - монолитные системы, многоуровневые системы, виртуальные машины и модель клиент-сервер.

1.5.1. Монолитные системы

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

Для построения монолитной системы необходимо скомпилировать все отдельные процедуры, а затем связать их в единый объектный файл с помощью компоновщика. Здесь, по существу, полностью отсутствует сокрытие деталей реализации -



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

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

Эта команда переключает машину из режима пользователя в режим ядра и передает управление операционной системе, что видно на шаге 1 рис. 1.12 (у большинства процессоров есть два режима работы: режим ядра, предназначенный для ОС, и пользовательский режим, в котором запрещен ввод/вывод и некоторые другие инструкции).

Затем операционная система проверяет параметры вызова, чтобы определить, какой системный вызов должен быть выполнен (шаг 2). После этого операционная система обращается к таблице как к массиву с номером системного вызова в качестве индекса. В fe-м элементе таблицы содержится ссылка на процедуру обработки системного вызова k (шаг 3 на рис. 1.12). После того, как работа завершена, управление возвращается в пользовательскую программу, которая продолжит свою работу со следующего оператора (шаг 4).

Пользовательская программа 1

Пользовательская программа 2 .Вызов ядра


Процедура обработки системного вызова

Табпица процедур

Программы выполняются в режиме пользователя

Операционная

система

работает

в режиме ядра

Рис. 1.12. Выполнение системного вызова: 1 - пользовательская программа вызывает прерывание; 2 - операционная система определяет номер процедуры обработчика; 3 - Операционная система вызывает обработчик; 4 - управление возвращается

в основную программу

Такая организация операционной системы предполагает следующую структуру:

1. Главная программа, которая вызывает требуемую служебную процедуру.

2. Набор служебных процедур, выполняющих системные вызовы.

3. Набор утилит, обслуживающих служебные процедуры.

В этой модели для каждого системного вызова имеется одна служебная процедура. Утилиты выполняют функции, которые нужны нескольким служебным процедурам. Деление процедур на три уровня показано на рис. 1.13.



1 2 3 4 5 6 7 8 9 10 11 12 13 [ 14 ] 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.