Имеет смысл рассмотреть, что происходит в ваших и, что более важно, в подобных случаях. Как отмечали другие авторы, это вызывает UB. Это, вероятно, правда. Однако мир не останавливается просто потому, что кто-то не определил, что именно должно произойти дальше. И то, что физически происходит дальше, вполне может быть серьезной дырой в безопасности .
Если ваша строка XXX...
поступает из неконтролируемых источников, вы очень близки к созданию уязвимости переполнения буфера.
(1) Ваш стек обычно «увеличивается» назад, то есть чем меньше адреса, тем больше заполнен стек.
(2) В строках ожидается, что символы, принадлежащие этой строке, будут сохранены, чтобы символ n + 1 сохранялся после символа n.
(3) Когда вы вызываете функцию, адрес возврата, т. Е. Адрес инструкции, которая должна быть выполнена после возврата функции, помещается в стек (среди прочего, как правило).
Теперь рассмотрим стек стека вашей функции.
|----------------|
| buf [size 8] |
|----------------|
| (func args) |
|----------------|
| (other stuff) |
|----------------|
| return address |
|----------------|
Узнав, каково смещение между buf
и обратным адресом в стеке, злонамеренный пользователь может манипулировать вводом в ваше приложение таким образом, чтобы строка XXX...
содержала адрес, выбранный злоумышленником, всего за точка, в которой неуправляемая функция sprintf
перезапишет адрес возврата в стеке. (Примечание: лучше использовать snprintf
, если оно доступно для вас). Тем самым злоумышленник осуществил атаку переполнения буфера . Он может использовать что-то вроде NOP sled техника , чтобы ваше приложение запустило для него shell . Если бы вы писали приложение, которое запускалось под учетной записью привилегированного пользователя, вы бы просто предоставили злоумышленнику первоклассную запись в систему вашего клиента, если хотите, - дыру ACE .
Обновление
Ошибка времени выполнения может возникать из-за перезаписанного адреса возврата. Поскольку вы заполнили его, в основном, gargabe, адрес, на который перескочил процессор, вероятно, содержал байтовые последовательности, которые, интерпретируемые как программный текст, вызывают недопустимый доступ к памяти (или сам адрес уже был неправильным).
Следует отметить, что некоторые компиляторы могут помочь против ошибок такого рода. GCC, например, имеет -fstack-protector
. Я не знаю, насколько хороши эти функции.