_s функции, такие как scanf_s
, printf_s
, кажется необязательным стандартом. MSVC реализовал эти функции, а gcc - нет.
Есть ли конкретная причина не реализовывать безопасные функции? Достаточно ли безопасен scanf
glibc?
_s функции, такие как scanf_s
, printf_s
, кажется необязательным стандартом. MSVC реализовал эти функции, а gcc - нет.
Есть ли конкретная причина не реализовывать безопасные функции? Достаточно ли безопасен scanf
glibc?
_s
функции не являются обязательными (Приложение K стандарта C11). Многие считают их «не очень полезными».
В ответах на мой вопрос Используете ли вы безопасные функции TR-24731? вы можете найти информацию о том, где возникают проблемы. со стандартной спецификацией - например, важные различия между стандартом и реализацией Microsoft. TR 24731-1 был техническим отчетом комитета по стандартизации C. Отчет был включен почти дословно - с дополнительной, ранее опущенной функцией IIRC - в стандарт C11 как (необязательное, но «нормативное») Приложение K. Также есть TR 24731-2 для другого набора функций - без суффикса _s
. . Он столкнулся с сопротивлением по другому набору причин.
Кроме того, перед комитетом по стандартизации C есть предложение удалить эти функции из следующей редакции стандарта:
Этот документ является прямым и убедительным прочтением причин, по которым функции TR-24731 (*_s()
) не получили широкого распространения.
Основные причины включают:
*_s()
не нужна.*_s()
функций или кода, который их использует.См. Статью для более подробной информации. Статья заканчивается разделом:
Предлагаемое техническое исправление
Несмотря на то, что прошло более десяти лет с момента первоначального предложения и почти десять лет с момента ратификации ISO / IEC TR 24731-1: 2007, а также почти пять лет с момента введения интерфейсов проверки границ в стандарт C, жизнеспособных соответствующих реализаций не появилось. . API-интерфейсы по-прежнему вызывают споры, и разработчики продолжают отклонять запросы на реализацию.
Дизайн интерфейсов проверки границ, хотя и сделан из лучших побуждений, страдает от слишком большого количества проблем, которые необходимо исправить. Было замечено, что использование API-интерфейсов приводит к ухудшению качества и безопасности программного обеспечения, чем использование установленных подходов или современных технологий. Более эффективные и менее навязчивые подходы стали обычным явлением, и им часто отдают предпочтение как пользователи, так и эксперты по безопасности.
Поэтому мы предлагаем либо исключить Приложение K из следующей версии стандарта C, либо исключить его из употребления, а затем удалить.
memset_s
и только для поддержки кода, чувствительного к безопасности. Тем не менее, было бы неплохо иметь strtok
замену, тоже кроссплатформенную.
- person Mgetz; 27.06.2018
strtok_r()
в Unix и strtok_s()
в Windows; в остальном они совместимы. Или, если хотите, всегда вызывайте strtok_s()
и используйте static inline char *strtok_s(char **ptr, const char *delim) { return strtok_r(ptr, delim); }
в Unix.
- person Jonathan Leffler; 27.06.2018
strtok
было бы просто хорошо, если бы это было частью стандарта, а не счастливой случайностью. Я действительно поддерживаю потребность в memset_s
, который нельзя оптимизировать.
- person Mgetz; 27.06.2018
memset
функция и §K.3.7.4.1 memset_s
функция, и полезное различие действительно является требованием: В отличие от memset
, любой вызов функции memset_s
должен оцениваться строго в соответствии с правилами абстрактной машины, как описано в (5.1.2.3). То есть любой вызов функции memset_s
должен предполагать, что память, обозначенная s
и n
, может быть доступна в будущем и, следовательно, должна содержать значения, указанные c
.
- person Jonathan Leffler; 27.06.2018
memset_s()
нельзя оптимизировать, даже если на задаваемую переменную больше не ссылаются. Это, в свою очередь, позволяет программисту гарантировать, что пароли обнуляются, когда они больше не нужны, и выполнять другие подобные операции. Дополнительный аргумент на самом деле не нужен; дополнительная семантика, связанная с (не) оптимизацией, безусловно, полезна в небольшом, но значительном наборе вариантов использования.
- person Jonathan Leffler; 27.06.2018
memset_s
, было бы общее средство, заставляющее компилятор синхронизировать состояния объектов абстрактной машины и состояние памяти, видимое ЦП. Использование обычного memset
с последующей принудительной синхронизацией было бы эквивалентно memset_s
, но код, заботящийся о безопасности, также нуждается в синхронизации для других целей. Например, что-то вроде unsigned u = *p; if (u < ARRAY_SIZE) array[u]++;
может привести к уязвимости системы безопасности, если *p
загружается один раз для сравнения и еще раз на этапе индексации.
- person supercat; 28.06.2018
gcc
вы используете? У меня версия 4.7.2, и она знает о_s
безопасных версиях. - person lurker   schedule 06.06.2018*_s()
тесно связаны с*_s()
функциями, которые Microsoft добавила в MSVC, но существенно отличаются от них. Да, я считаю, что Microsoft сыграла важную роль в создании отчета TR 24731-1, но результат отличался по ключевым аспектам от того, что MS уже выпустила в дебрях, и обратная совместимость тогда стала проблемой. MS не могла легко соответствовать стандарту, потому что это нарушило бы их обещания обратной совместимости. - person Jonathan Leffler   schedule 06.06.2018*_s()
- полезно знать. Однако он подчеркивает разницу между «компилятором» и «библиотеками», а также не переносится в большинство других сред. Функции*_s()
по существу недоступны, кроме как на платформе MS. - person Jonathan Leffler   schedule 06.06.2018gcc
он поставляется с соответствующим набором конкретных библиотек (что все это часть пакета), что, очевидно, не так. - person lurker   schedule 06.06.2018scanf
в glibc действительно включает модификатор выделения памяти Posix / TR-24731-2 (m
), который во многих отношениях является превосходным интерфейсом. - person rici   schedule 06.06.2018