Чтение онлайн

на главную

Жанры

Архитектура операционной системы UNIX
Шрифт:

На Рисунке 7.25 приведена программа, демонстрирующая использование функции setuid. Предположим, что исполняемый файл, полученный в результате трансляции исходного текста программы, имеет владельца с именем «maury» (код идентификации 8319) и установленный бит setuid; право его исполнения предоставлено всем пользователям. Допустим также, что пользователи «mjb» (код идентификации 5088) и «maury» являются владельцами файлов с теми же именами, каждый из которых доступен только для чтения и только своему владельцу. Во время исполнения программы пользователю «mjb» выводится следующая информация:

uid 5088 euid 8319

 fdmjb -1 fdmaury 3

 after setuid(5088): uid 5088 euid 5088

 fdmjb 4 fdmaury -1

 after setuid(8319): uid 5088 euid 8319

Системные функции getuid и geteuid возвращают значения реального и исполнительного кодов идентификации пользователей процесса, для пользователя «mjb» это, соответственно, 5088

и 8319. Поэтому процесс не может открыть файл «mjb» (ибо он имеет исполнительный код идентификации пользователя (8319), не разрешающий производить чтение файла), но может открыть файл «maury». После вызова функции setuid, в результате выполнения которой в поле исполнительного кода идентификации пользователя («mjb») заносится значение реального кода идентификации, на печать выводятся значения и того, и другого кода идентификации пользователя "mjb": оба равны 5088. Теперь процесс может открыть файл „mjb“, поскольку он исполняется под кодом идентификации пользователя, имеющего право на чтение из файла, но не может открыть файл „maury“. Наконец, после занесения в поле исполнительного кода идентификации значения, сохраненного функцией setuid (8319), на печать снова выводятся значения 5088 и 8319. Мы показали, таким образом, как с помощью программы setuid процесс может изменять значение кода идентификации пользователя, под которым он исполняется.

#include ‹fcntl.h›

main
{

 int uid, euid, fdmjb, fdmaury;

 uid = getuid; /* получить реальный UID */

 euid = geteuid; /* получить исполнительный UID */

 printf("uid %d euid %d\n", uid, euid);

 fdmjb = open("mjb", O_RDONLY);

 fdmaury = open("maury", O_RDONLY);

 printf("fdmjb %d fdmaury %d\n", fdmjb, fdmaury);

 setuid(uid);

 printf("after setuid(%d): uid %d euid %d\n", uid, getuid, geteuid);

 fdmjb = open("mjb", O_RDONLY);

 fdmaury = open("maury", O_RDONLY);

 printf("fdmjb %d fdmaury %d\n", fdmjb, fdmaury);

 setuid(uid);

 printf("after setuid(%d): uid %d euid %d\n", euid, getuid, geteuid);

}

Рисунок 7.25. Пример выполнения программы setuid

Во время выполнения программы пользователем „maury“ на печать выводится следующая информация:

uid 8319 euid 8319

 fdmjb -1 fdmaury 3

 after setuid(8319): uid 8319 euid 8319

 fdmjb -1 fdmaury 4

 after setuid(8319): uid 8319 euid 8319

Реальный и исполнительный коды идентификации пользователя во время выполнения программы остаются равны 8319: процесс может открыть файл „maury“, но не может открыть файл „mjb“. Исполнительный код, хранящийся в пространстве процесса, занесен туда в результате последнего исполнения функции или программы setuid; только его значением определяются права доступа процесса к файлу. С помощью функции setuid исполнительному коду может быть присвоено значение сохраненного кода (из таблицы процессов), т. е. то значение, которое исполнительный код имел в самом начале.

Примером программы, использующей вызов системной функции setuid, может служить программа регистрации пользователей в системе (login). Параметром функции setuid при этом является код идентификации суперпользователя, таким образом, программа login исполняется под кодом суперпользователя из корня системы. Она запрашивает у пользователя различную информацию, например, имя и пароль, и если эта информация принимается системой, программа запускает функцию setuid, чтобы установить значения реального и исполнительного кодов идентификации в соответствии с информацией, поступившей от пользователя (при этом используются данные файла „/etc/passwd“). В заключение программа login инициирует запуск командного процессора shell, который будет исполняться под указанными пользовательскими кодами идентификации.

Примером setuid-программы является программа, реализующая команду mkdir. В разделе 5.8 уже говорилось о том, что создать каталог может только процесс, выполняющийся под управлением суперпользователя. Для того, чтобы предоставить возможность создания каталогов простым пользователям, команда mkdir была выполнена в виде setuid-программы, принадлежащей корню системы и имеющей права суперпользователя. На время исполнения команды mkdir процесс получает права суперпользователя, создает каталог, используя функцию mknod, и предоставляет права собственности и доступа к каталогу истинному пользователю процесса.

7.7 ИЗМЕНЕНИЕ РАЗМЕРА ПРОЦЕССА

С помощью системной функции brk процесс может увеличивать и уменьшать размер области данных. Синтаксис вызова функции:

brk(endds);

где endds —

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

oldendds = sbrk(increment);

где oldendds — текущий адрес верхней границы области, increment — число байт, на которое изменяется значение oldendds в результате выполнения функции. Sbrk — это имя стандартной библиотечной подпрограммы на Си, вызывающей функцию brk. Если размер области данных процесса в результате выполнения функции увеличивается, вновь выделяемое пространство имеет виртуальные адреса, смежные с адресами увеличиваемой области; таким образом, виртуальное адресное пространство процесса расширяется. При этом ядро проверяет, не превышает ли новый размер процесса максимально-допустимое значение, принятое для него в системе, а также не накладывается ли новая область данных процесса на виртуальное адресное пространство, отведенное ранее для других целей (Рисунок 7.26). Если все в порядке, ядро запускает алгоритм growreg, присоединяя к области данных внешнюю память (например, таблицы страниц) и увеличивая значение поля, описывающего размер процесса. В системе с замещением страниц ядро также отводит под новую область пространство основной памяти и обнуляет его содержимое; если свободной памяти нет, ядро освобождает память путем выгрузки процесса (более подробно об этом мы поговорим в главе 9). Если с помощью функции brk процесс уменьшает размер области данных, ядро освобождает часть ранее выделенного адресного пространства; когда процесс попытается обратиться к данным по виртуальным адресам, принадлежащим освобожденному пространству, он столкнется с ошибкой адресации.

алгоритм brk

входная информация: новый адрес верхней границы области данных

выходная информация: старый адрес верхней границы области данных

{

 заблокировать область данных процесса;

 if (размер области увеличивается)

if (новый размер области имеет недопустимое значение)
 {

снять блокировку с области;

return (ошибку);

}

изменить размер области (алгоритм growreg);

обнулить содержимое присоединяемого пространства;

снять блокировку с области данных;

}

Рисунок 7.26. Алгоритм выполнения функции brk

На Рисунке 7.27 приведен пример программы, использующей функцию brk, и выходные данные, полученные в результате ее прогона на машине AT&T 3B20. Вызвав функцию signal и распорядившись принимать сигналы о нарушении сегментации (segmentation violation), процесс обращается к подпрограмме sbrk и выводит на печать первоначальное значение адреса верхней границы области данных. Затем в цикле, используя счетчик символов, процесс заполняет область данных до тех пор, пока не обратится к адресу, расположенному за пределами области, тем самым давая повод для сигнала о нарушении сегментации. Получив сигнал, функция обработки сигнала вызывает подпрограмму sbrk для того, чтобы присоединить к области дополнительно 256 байт памяти; процесс продолжается с точки прерывания, заполняя информацией вновь выделенное пространство памяти и т. д. На машинах со страничной организацией памяти, таких как 3B20, наблюдается интересный феномен. Страница является наименьшей единицей памяти, с которой работают механизмы аппаратной защиты, поэтому аппаратные средства не в состоянии установить ошибку в граничной ситуации, когда процесс пытается записать информацию по адресам, превышающим верхнюю границу области данных, но принадлежащим т. н. „полулегальной“ странице (странице, не полностью занятой областью данных процесса). Это видно из результатов выполнения программы, выведенных на печать (Рисунок 7.27): первый раз подпрограмма sbrk возвращает значение 140924, то есть адрес, не дотягивающий 388 байт до конца страницы, которая на машине 3B20 имеет размер 2 Кбайта. Однако процесс получит ошибку только в том случае, если обратится к следующей странице памяти, то есть к любому адресу, начиная с 141312. Функция обработки сигнала прибавляет к адресу верхней границы области 256, делая его равным 141180 и, таким образом, оставляя его в пределах текущей страницы. Следовательно, процесс тут же снова получит ошибку, выдав на печать адрес 141312. Исполнив подпрограмму sbrk еще раз, ядро выделяет под данные процесса новую страницу памяти, так что процесс получает возможность адресовать дополнительно 2 Кбайта памяти, до адреса 143360, даже если верхняя граница области располагается ниже. Получив ошибку, процесс должен будет восемь раз обратиться к подпрограмме sbrk, прежде чем сможет продолжить выполнение основной программы. Таким образом, процесс может иногда выходить за официальную верхнюю границу области данных, хотя это и нежелательный момент в практике программирования.

Поделиться:
Популярные книги

Треск штанов

Ланцов Михаил Алексеевич
6. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Треск штанов

Низший - Инфериор. Компиляция. Книги 1-19

Михайлов Дем Алексеевич
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
5.00
рейтинг книги
Низший - Инфериор. Компиляция. Книги 1-19

Купеческая дочь замуж не желает

Шах Ольга
Фантастика:
фэнтези
6.89
рейтинг книги
Купеческая дочь замуж не желает

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Фиктивная жена

Шагаева Наталья
1. Братья Вертинские
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Фиктивная жена

Темный Охотник

Розальев Андрей
1. КО: Темный охотник
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Отборная бабушка

Мягкова Нинель
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Отборная бабушка

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Сумеречный Стрелок 2

Карелин Сергей Витальевич
2. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 2

Купидон с топором

Юнина Наталья
Любовные романы:
современные любовные романы
7.67
рейтинг книги
Купидон с топором

Отмороженный 4.0

Гарцевич Евгений Александрович
4. Отмороженный
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Отмороженный 4.0

Черный Маг Императора 5

Герда Александр
5. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 5

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...