Майкл Джонсон - Разработка приложений в среде Linux. Второе издание
- Название:Разработка приложений в среде Linux. Второе издание
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2007
- Город:Москва
- ISBN:978-5-8459-1143-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Майкл Джонсон - Разработка приложений в среде Linux. Второе издание краткое содержание
Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет собой отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из других операционных систем. Подробно рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование свободно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Изобилие хорошо документированных примеров кода помогает лучше усвоить особенности программирования в Linux.
Книга рассчитана на разработчиков разной квалификации, а также может быть полезна для студентов и преподавателей соответствующих специальностей.
Разработка приложений в среде Linux. Второе издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
#include
char * strdup(const char * src);
char * strdupa(const char * src);
char * strndup(const char * src, int max);
char * strndupa(const char * src, int max);
Первая из приведенных функций, strdup()
, копирует строку src
в буфер, выделенный методом malloc()
, и возвращает буфер вызывающему оператору. Вторая функция, strdupa()
, выделяет буфер с помощью alloca()
. При этом обе функции выделяют буфер, в точности достаточный для хранения строки и замыкающего символа '\0'
.
Остальные две функции, strndup()
и strndupa()
, копируют не более чем max байтов из str
в буфер вместе с замыкающим '\0'
(и выделяют не более чем max
+1 байтов). При этом выделение буфера происходит при помощи метода malloc()
(для strndup()
) или alloca()
(для strndupa()
).
Функция sprintf()
также входит в число тех, которые часто вызывают переполнение буфера. Так же как strcat()
и strcpy()
, функция sprintf()
имеет разновидность, позволяющую облегчить защиту от перегрузок.
#include
int snprintf(char * str, size_t max, char * format, ...);
Попытки определить размер буфера, необходимый для sprintf()
, могут оказаться слишком сложными. Он зависит от таких элементов, как значения всех форматируемых чисел (для которых могут быть нужны или не нужны знаки чисел), используемые аргументы форматирования и длины всех строк, которые были затронуты форматированием. Для того чтобы избежать переполнения буфера, функция snprintf()
помещает в str
не более чем max символов, включая замыкающий '\0'
. В отличие от strcat()
и strncat()
, функция snprintf()
корректно завершает строку, при необходимости пренебрегая символом из форматируемой строки. Она возвращает количество символов, которые будет занимать конечная строка при наличии доступного пространства. Также сообщается, нужно ли усекать строку до max
символов (не считая последний '\0'
) [162] В некоторых устаревших версиях библиотеки С вместо этого возвращается -1 (если строка не помещается). Старая версия библиотеки С уже не поддерживается и не используется в защищенных программах, однако на man-странице по функции snprintf() демонстрируется код, обрабатывающий оба варианта.
. Если возвращаемое значение меньше чем max
, значит, функция успешно завершила свою работу. Если же равно или больше, значит, предел max
превышен.
Функция vsprintf()
несет те же проблемы, a vsnprintf()
предлагает способ их преодоления.
22.3.2. Разбор имен файлов
Абсолютно обычным действием для привилегированных приложений является предоставление доступа к файлам ненадежным пользователям и разрешение этим пользователям передавать имена файлов, к которым необходим доступ. Хорошим примером служит Web-сервер. URL-адрес HTTP содержит имя файла, полученное сервером как запрос на передачу удаленному (ненадежному) пользователю. На Web-сервере необходимо убедиться, что возвращаемый файл — это именно тот, который был сконфигурирован на отправку, а также внимательно проверить правильность имен файлов.
Представьте Web-сервер, обслуживающий файлы из home/httpd/html
, выполняющий это посредством простого добавления имени файла из URL, который требуется предоставить, концу /home/httpd/html
. Такой процесс дает правильный файл, однако это также позволяет удаленным пользователям увидеть любой файл системы, к которой Web-сервер имеет доступ, просто запросив, к примеру, файл ../../.. /etc/passwd
. Подобные каталоги ..
необходимо явно проверять и отклонять. Системный вызов chroot()
предоставляет хороший способ, позволяющий сделать обработку имен файлов в программах более простой.
Если имена файлов передаются в другие программы, то необходима еще более тщательная проверка. Например, если в имени файла используется начальный символ -
, то весьма вероятно, что другая программа интерпретирует его как опцию командной строки.
22.3.3. Переменные окружения
В программах, работающих с возможностями setuid или setgid, нужно проявлять особую осторожность с установками окружения. Эти переменные определяются пользователем, активизировавшим программу, тем самым открывается путь для атак. Самая явная атака может пройти через переменную окружения PATH
, изменяющую те каталоги, в которых функции execlp()
и execvp()
отыскивают программы. Если привилегированная программа запускает другие программы, то она должна убедиться, что это именно те программы, которые нужны! Пользователь, который имеет возможность подменить программный путь поиска, легко может подвергнуть программу опасности.
Существуют и другие переменные окружения, которые могут оказаться опасными. Например, переменная LD_PRELOAD
позволяет пользователю указать некоторую библиотеку для загрузки до стандартной библиотеки С. Это может быть полезным, но одновременно и очень опасным в привилегированных приложениях (по этой же причине переменная окружения игнорируется, если реальное и эффективное универсальные имена совпадают).
Если программа локализована, то переменная NLSPATH
также становится проблемной. Она позволяет пользователю переключать используемый программой языковой каталог, который определяет способ перевода строк. Это означает, что в переводных программах пользователь имеет возможность указать значение для любой переводимой строки. Строку можно сделать сколько угодно длинной, вынуждая программу быть крайне осторожной при выделении буфера. Еще более опасным является то, что при переводе форматирующих строк для таких функций, как printf()
, можно изменить формат. Например, строка Hello World, today is %s
может превратиться в Hello World, today is %c%d%s.
Трудно предсказать, какое воздействие могут оказать подобные изменения на функционирование программы!
Все это сводится к тому, что наилучшим решением для переменных окружения setuid- или setgid-программ является исключение этих переменных. Функция clearenv()
[163] К сожалению, функция clearenv() не очень хорошо стандартизирована. Она входит в последние версии POSIX, однако она была выброшена из стандарта Single Unix Standard и не доступна во всех системах типа Unix. Если вам необходимо поддерживать операционную систему, не включающую эту переменную, установите environ=NULL; .
стирает все значения из окружения, оставляя его пустым. После этого программа может заполнить любые необходимые ей переменные окружения известными значениями.
22.3.4. Запуск командной оболочки
Запуск системной командной оболочки из любой программы, в которой важен вопрос безопасности, является плохой идеей. При этом защита от тех проблем, которые мы уже обсуждали, становится еще более трудной.
Читать дальшеИнтервал:
Закладка: