Решение для Mac для «безопасных» альтернатив «небезопасным» функциям стандартной библиотеки C / C ++? - PullRequest
11 голосов
/ 30 января 2010

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

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

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

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

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

fopen vfprintf vsprintf sprintf strncpy strcpy strcat

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

Ответы [ 8 ]

16 голосов
/ 30 января 2010

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

fopen

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

vfprintf vsprintf sprintf 

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

 strncpy

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

strcpy strcat

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

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

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

9 голосов
/ 31 января 2010

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

   C        MSVC      PROVIDERS  MAC SOLUTION
---------------------------------------------------------------------------------
fopen     fopen_s     C          none, assume fopen is safe
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.

5 голосов
/ 30 января 2010

Вместо 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 считаются небезопасными.

4 голосов
/ 30 января 2010

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

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

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

#define _ _STDC_WANT_LIB_EXT1_ _ 1
#include <stdarg.h>
#include <stdio.h>
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 
);

Параметры

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

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

3 голосов
/ 25 августа 2014

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

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

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

enter image description here


В связи с этим: в то время как Apple и Microsoft предоставляют более безопасные функции, Linux не предоставляет.GNU C не включал «Интерфейсы проверки границ» (TR24731 ISO), потому что такие люди, как Ульрих Дреппер (привратник GNU libc) возражали.Он возражал, потому что был указан только целевой буфер.Он назвал «более безопасную» функцию BSD Crap.Цитату Дреппера см. В 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'у, игнорировал лучшие практики и отбрасывал «более безопасные» функции.Интересно, сколько миллионов маршрутизаторов и шлюзов остаются не исправленными даже сегодня ...

3 голосов
/ 30 января 2010

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

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
3 голосов
/ 30 января 2010

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

1 голос
/ 04 июля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...