$ ls -l /tmp/myfileic7xCy /* Снова проверить владельца и доступ */
-rw------- 1 arnold devel 28 Sep 18 09:28 /tmp/myfileic7xCy
Все кажется работающим замечательно, mktemp()
возвращает уникальное имя, ch12-mktemp
создает файл с нужными правами доступа, и содержание то самое, которое ожидалось. Так в чем же проблема со всеми этими функциями?
Исторически mktemp()
использовала простой, ХХХХХХ
' в шаблоне. Более того, интервал между временем, когда
Как? Ну, Linux и Unix являются системами с
Теперь рассмотрите программу профессора для отслеживания оценок студентов. Как профессор, так и злоумышленный студент в одно и то же время используют сильно нагруженную многопользовательскую систему. Программа профессора использует для создания временных файлов mktemp()
, видевший в прошлом, как оценивающая программа создает и удаляет временные файлы, выяснил алгоритм, который использует mktemp()
. (В версии GLIBC нет этой проблемы, но не все системы используют GLIBC!) Рис 12.2 иллюстрирует состояние гонки и то, как студент его использует.
Рис. 12.2. Состояние гонки с mktemp()
Вот что случилось.
1. Оценивающая программа использует mktemp()
для создания имени файла. По возвращении из mktemp()
открыто окно состояния гонки (строка 19 в ch12-.mktemp.c
).
2. Ядро останавливает оценивающую программу, чтобы могли поработать другие программы в системе. Это происходит до вызова open()
.
Пока оценивающая программа остановлена, студент создает файл с тем же самым именем, которое вернула mktemp()
. (Помните, выяснить алгоритм было просто.) Студент создает файл с дополнительной ссылкой, так что когда оценивающая программа удаляет файл, он все еще будет доступен для прочтения.
3. Теперь оценивающая программа открывает файл и записывает в него данные. Студент создал файл с правами доступа -rw-rw-rw-
, поэтому это не представляет проблему.
4. Когда оценивающая программа завершает работу, она удаляет временный файл. Однако, у студента все еще есть копия. Например, может быть возможность получения прибыли при заблаговременной продаже своим товарищам их оценок.
Наш пример упрощенный; помимо простого похищения данных с оценками умный (хотя и аморальный) студент мог бы вместо этого
ЗАМЕЧАНИЕ. Мы не рекомендуем делать что-либо из этого! Если вы студент, не пытайтесь сделать что-либо подобное. Первое и самое главное, это неэтично. Во-вторых, вас могут выгнать из школы. В-третьих, ваши профессора, наверное, не сталь наивны, чтобы использовать mktemp()
в своих программах. Этот пример лишь для иллюстрации!
По приведенным и другим причинам, все три описанные в данном разделе функции не следует никогда использовать. Они существуют в POSIX и GLIBC лишь для поддержки старых программ, которые были написаны до того, как была осознана опасность этих процедур С этой целью системы GNU/Linux генерируют во время компоновки сообщение:
$ cc ch12-mktemp.c -о ch12-mktemp /* Компилировать программу */
/tmp/cc1XCvD9.о(.text+0x35): In function 'main':
: the use of 'mktemp' is dangerous, better use 'mkstemp'
(Мы рассмотрим mkstemp()
в следующем подразделе.)
Если бы в вашей системе не было mkstemp()
, подумайте, как вы могли бы использовать эти интерфейсы для ее эмулирования. (См. также «Упражнения» для главы 12 в конце.)
12.3.2. Создание и открывание временных файлов (хорошо)
Есть две функции, не имеющие проблем состояния гонки. Одна из них предназначена для использования с библиотекой
:
#include
FILE *tmpfile(void);
Другая функция для использования с системными вызовами на основе дескрипторов файлов:
#include
int mkstemp(char* template);