Читаем Linux программирование в примерах полностью

$ 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 в конце.)

<p>12.3.2. Создание и открывание временных файлов (хорошо)</p>

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

#include /* ISO С */

FILE *tmpfile(void);

Другая функция для использования с системными вызовами на основе дескрипторов файлов:

#include /* XSI */

int mkstemp(char* template);

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных