2013-03-05 3 views
7

Мне кажется, люди, особенно при изучении языка программирования C, все еще используют функцию gets для чтения в данных из stdin. Несмотря на то что он теперь был удален от стандарта C11, и отказ от ответственности на cppreference гласит:Получилось ли когда-нибудь полезно?

получает (функция) не выполняет проверку границ, поэтому эта функция чрезвычайно уязвима для переполнения буфера атаки. Нельзя использовать (если программа не работает в среде, которая ограничивает то, что может появиться на stdin). По этой причине функция устарела в третьем исправлении к стандарту C99 и полностью удалена в стандарте C11. fgets() и gets_s() - рекомендуемые замены .

Никогда не используйте gets().

Однако, похоже, что это не новая проблема, которая придумала более современные философии программирования. Это всегда было бы сломано и вызвало бы крах программ, и я не понимаю, что может означать «среда, которая ограничивает то, что может появиться на stdin».

Значит, было Полезно в прошлом? Или в чем причина, по которой она была добавлена ​​к предыдущим стандартам и пред-стандартным версиям C?


(1) ... или, по крайней мере, изменилось, чтобы иметь дополнительный параметр, указывающий максимальную длину для чтения. Однако я прошу про старую подпись, получая только указатель.

+2

Из [FAQ] (http://stackoverflow.com/faq) * «Вы должны задавать только практические, ответные вопросы ** на основе реальных проблем, с которыми вы сталкиваетесь ** ...» * (мой акцент). –

+0

???? http://stackoverflow.com/questions/3302255/c-scanf-vs-gets-vs-fgets –

+1

@TJCrowder - в нем также говорится «проблемы, которые уникальны для профессии программирования», вы не будете спрашивать об использовании API вне профессии программирования – Mike

ответ

5

Да, это было полезно и «чрезвычайно уязвимо к атакам переполнения буфера» одновременно.

Это всегда было бы сломано и вызвало сбои в работе программ, и я не вижу, что можно было бы подразумевать под «средой, которая ограничивает то, что может появиться на stdin».

No, gets не вызывало сбоев в работе программ. Это прежде всего проблема безопасности. Вы можете прочитать об атаках на переполнение буфера here

Также см этот вопрос: Why is the gets function so dangerous that it should not be used?

+1

Как неявно указано в ОП, это противоречия. Если я выставляю свою программу для переполнения буфера путем вызова 'gets', то это явно ** не ** полезно. В вопросе спрашивается, были ли дополнительные меры предосторожности или нет, почему 'get' был определен так, как он есть. – bitmask

+2

@bitmask Мне «полезно» означает, что он может помочь в достижении некоторых полезных функций для пользователя. Программа может быть полезна и небезопасна одновременно ... – lbalazscs

+1

C был спроектирован в 70-х годах. Тогда сетевые системы были исключением, чем норма, и безопасность не считалась столь же важной, как сегодня. Обычно данные считаются надежными, как программное обеспечение. – Philipp

0

Получает все еще полезно для создания прототипов. Быстро писать и получать ожидаемые результаты для программиста, который ориентирован на решение проблемы, вместо того, чтобы пытаться свернуть свою программу.

+0

'fgets' так же быстро писать. Предоставление размера буфера и стандартного входного ФАЙЛА не является таким препятствием. – bitmask

+0

@bitmask: досада вынуждена использовать strlen для поиска новой строки, чтобы ее можно было отключить. – supercat

5

Когда вы смотрите на остатки с первых дней C, вы должны учитывать исторический фон.

Язык C был разработан в 70-х годах. Тогда сетевые системы были исключением, чем норма, и безопасность не считалась столь же важной, как сегодня. Системы редко работали на недоверенных сторонних данных. И даже когда они это делали, это не считалось большим риском. Информационные технологии все еще находились на самой ранней стадии. Никто не понимал, насколько чувствительны компьютерные системы.

Время CPU, с другой стороны, было драгоценным.Программы должны быть максимально эффективными.

Вот почему большинство функций из стандартной библиотеки C не проводят проверку границ. Производительность имела гораздо более высокий приоритет, чем безопасность. Когда вам нужна безопасность, вы должны были подтвердить свои данные до, подавая их в вашу программу.

Но сегодня, в 21 веке, когда все компьютерные системы взаимосвязаны, все компьютерные системы постоянно обрабатывают информацию из ненадежного или даже неизвестного происхождения, а взлом - это индустрия в миллиард долларов, безопасность стала приоритетом номер один для каждой компьютерной программы ,

+0

Я не говорил о безопасности в сегодняшнем смысле, а о надежности. Но ваш аргумент скорости - очень хороший, который, возможно, имел преимущество перед * безопасностью и надежностью. – bitmask

2

Когда было изобретено gets, очень мало программ, необходимых для приема большого количества входных данных из ненадежных источников. gets подходит для ограниченного ввода от сотрудничающего пользователя. Этот пользователь предоставляет «среду, которая ограничивает то, что может появиться», не набрав много строк в каждой строке. Вы можете в значительной степени рассчитывать на пользователя, сидящего на терминале, чтобы не вводить сотни байтов данных в приглашение «y/n». Если они передали большой файл в вашу программу, когда ваша программа не была разработана для этого, ну, они получили плохие результаты.

Программы, которые должны были обрабатывать произвольные входные данные, не использовали gets.

Теперь злоумышленный ввод распространен на практике и является более разрушительным, поскольку существуют инструменты и методы, позволяющие злоумышленникам легко превращать переполнение буфера в свою пользу. Хорошо обученный пользователь, набравший подсказку, является нишевым случаем. Кроме того, учет вредоносного ввода широко используется в качестве хорошего метода для обеспечения надежного применения программного обеспечения от неожиданного ввода, который не был, предназначенным для атаки. Практически все программы, как ожидается, будут обрабатывать произвольные данные. Значит, gets явно неадекватен.

 Смежные вопросы

  • Нет связанных вопросов^_^