Mac для «безопасных» альтернатив «небезопасным» функциям стандартной библиотеки C / C ++?

Какое лучшее одноразовое «безопасное» решение для библиотеки C на Mac? Я использую цитаты «безопасно» / «небезопасно», потому что много дискуссий о преимуществах определенных функций стандартной библиотеки или их предположительно улучшенных альтернатив.

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

В Windows компиляторы Microsoft C / C ++ предоставляют функции «_s» (например, vfprintf_s ) как более безопасную альтернативу вызовам стандартной библиотеки. Эти функции не являются заменой замены, так как они имеют разные сигнатуры, необходимые для обеспечения дополнительной информации о безопасности (например, длина буфера). Они также предоставляют другие функции, такие как неверное определение строки формата, различная защита файлов и т. Д. Насколько мне известно, эта реализация недоступна на Mac.

Является ли Apple (или сторонняя организация) чем-то аналогичным для использования с GCC на OSX?

В частности, я ищу «безопасные» реализации, по крайней мере, следующих функций:

fopen vfprintf vsprintf sprintf strncpy strcpy strcat

Обратите внимание: этот вопрос касается Mac. Я НЕ прошу вашего мнения о внедрении Microsoft (если только он не доступен на Mac.) Хотя некоторые из этих функций могут быть легко написать сами, не все. Я НЕ спрашиваю, как писать их сам. Я не прошу советов о том, как использовать classы STL для этого. Я не спрашиваю, как отключить предупреждения. Мои особые потребности очень специфичны. Я пытаюсь идентифицировать Mac API с лучшей практикой, который по возможности похож на традиционные вызовы библиотеки C при одновременном добавлении безопасности. Конечно, портативная реализация, которая работает на Mac и Windows (и других операционных системах), будет еще лучше.

Прежде всего, распечатайте документацию о «безопасных / небезопасных» функциях из MSDN и сжечь ее!

Еореп

Является настолько же безопасным, как fopen_s … Если вы идиот и считаете, что возвращаемый указатель не является NULL, или укажите NULL в качестве входного параметра.

 vfprintf vsprintf sprintf 

Просто MS не поддерживает C99, используйте семейство snprintf .

  strncpy 

Совершенно безопасно, если вы читаете руководство

 strcpy strcat 

Используйте параметры strncpy и strncat и чтения. (т. е. strncpy может не иметь нулевого завершения)

Итак … еще раз:

Распечатайте документацию о «безопасных / небезопасных» функциях из MSDN и сжечь ее!

РЕЗЮМЕ: на Mac существует несколько API и параметров компилятора, которые обеспечивают более безопасные альтернативы функциям C стандартной библиотеки. Вот некоторые из них по сравнению с «безопасными» API-интерфейсами Microsoft :

    C MSVC ПРОВАЙДЕРЫ MAC SOLUTION
 -------------------------------------------------- -------------------------------
 fopen fopen_s C нет, предположим, что fopen безопасен
 vfprintf vfprintf_s GCC GCC_WARN_TYPECHECK_CALLS_TO_PRINTF (1)
 vsprintf vsprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, vsnprintf (2)
 sprintf sprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, snprintf (3)
 strncpy strncpy_s BSD strlcpy (4)
 strcpy strcpy_s BSD strlcpy
 strcat strcat_s BSD strlcat (5)

(1) GCC_WARN_TYPECHECK_CALLS_TO_PRINTF – это параметр конфигурации XCode, который соответствует опции командной строки GCC -Wformat . Этот параметр предоставляет предупреждения компилятора о несогласии между типами аргументов и строками статического формата. Существует множество других опций для контроля обработки строк в формате GCC. Вы даже можете использовать атрибут функции format GCC, чтобы включить проверку строки формата на свои собственные функции.

(2) vsnprintf и (3) snprintf – из C99-версии стандартной библиотеки C (доступно в GCC на Mac, но не в MSVC в Windows).

(4) strlcpy и (5) strlcat – это библиотечные функции BSD, доступные на Mac.

Вместо sprintf и vsprintf вы хотите использовать:

 snprintf(buffer, buffer_size, fmt_string, args, ...); vsnprintf(buffer, buffer_size, fmt_string, valist); 

Вместо strcpy, strncpy, strcat и strncat вы хотите нас:

 strlcpy(dest, src, dest_size); strlcat(dest, src, dest_size); 

Существует один важный способ, что функции strn не могут быть заменены функциями strl. Если вы хотите скопировать строки, отличные от 0, функции strn позволяют это сделать, установив длину на меньшее значение объема копии и размера целевого буфера. Функции strl этого не делают и работают только тогда, когда исходная строка 0 завершена.

Не знаете, как fopen или vfprintf считаются небезопасными.

См. Также: SO 327980 .

Комитет Standard C создал технический отчет TR 24731-1 , частично в поддержку Microsoft (я считаю). Он стандартизирует интерфейсы для различных функций, таких как vsnprintf_s() . Однако, к сожалению, интерфейс, определенный стандартом, несовместим с интерфейсом, определенным Microsoft, что делает стандарт в значительной степени несущественным.

Например, TR 24731-1 говорит, что интерфейс vsnprintf_s() :

 #define _ _STDC_WANT_LIB_EXT1_ _ 1 #include  #include  int vsnprintf_s(char * restrict s, rsize_t n, const char * restrict format, va_list arg); 

К сожалению, MSDN говорит, что интерфейс vsnprintf_s() :

 int vsnprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format, va_list argptr ); 

параметры

  • buffer – место хранения для вывода.
  • sizeOfBuffer – размер буфера для вывода.
  • count – Максимальное количество символов для записи (не включая завершающий нуль) или _TRUNCATE.
  • формат – спецификация формата.
  • argptr – указатель на список аргументов.

Обратите внимание, что это не просто вопрос отображения типов: количество фиксированных аргументов различно и, следовательно, непримиримо. Мне также непонятно (и, по-видимому, комитету по стандартам), какая польза от наличия «sizeOfBuffer» и «count»; он похож на ту же информацию дважды (или, по крайней мере, код обычно записывается с тем же значением для обоих параметров).

Поскольку пользовательская база OSX основана на FreeBSD , у вас есть несколько более приятных функций, таких как strlcpy и strlcat .

В стандарте C уже есть набор «безопасной» версии этих функций.
(Для конкретного определения термина safe)

Snprintf () (и семья) предоставляют функции безопасности, которые вы ищете. Проверка переполнения буфера.
Компилятор gcc дополнительно выполняет проверку строки строки (но лучше, чем MS, поскольку проверка выполняется во время компиляции).

 fopen() Not sure how you make that safer? vfprintf -- These are low level functions vsprintf -- These are low level functions sprintf snprintf strncpy Already the safe version strcpy strncpy strcat strncat 

В частности, я ищу «безопасные» реализации, по крайней мере, следующих функций: fopen vfprintf vsprintf sprintf strncpy strcpy strcat …

Я пытаюсь идентифицировать Mac API с лучшей практикой, который по возможности похож на традиционные вызовы библиотеки C при одновременном добавлении безопасности.

Это легко. Ознакомьтесь с руководством по безопасному кодированию Apple . Apple использует BSD «более безопасные» функции.

введите описание изображения здесь


Связано: в то время как Apple и Microsoft обеспечивают более безопасные функции, Linux этого не делает. GNU C не включал «Интерфейсы проверки границ» (ISO TR24731), потому что возражали такие люди, как Ульрих Дреппер (привратник GNU libc). Он возражал, потому что был указан только целевой буфер. Он назвал «безопасную» функцию BSD Crap. Для цитаты Drepper см. Re: PATCH: безопасная копия строки и конкатенация в списке рассылки Sourceware .

Следуя совету Дреппера, он приведет к впечатляющим неудачам. CVE-2012-5958 CVE-2012-5959 CVE-2012-5960 CVE-2012-5961 CVE-2012-5962 CVE-2012-5963 CVE-2012-5964 CVE-2012-5965 (также известный как множественное переполнение буфера в libupnp) для победы! Его слишком плохой libupnp следовал за Drepper’ом и игнорировал лучшие практики и отбрасывал «более безопасные» функции. Интересно, сколько миллионов маршрутизаторов и шлюзов по-прежнему не загружается даже сегодня …

Google Summer of Code 2010: OpenAfs и Google спонсируют порт библиотеки String Safe от Microsoft. См. http://www.openafs.org/pages/gsoc.html .