2013-11-14 4 views
4

Предположим, у меня есть код устаревшего кода, который был написан с использованием небезопасных вызовов функций C STL, таких как strcpy. Мы все знаем, что strcpy небезопасно, потому что он оставляет программу уязвимой для проблем с переполнением буфера. Предположим, я хочу заменить все звонки на strcpy с звонками на strncpy. Метод замены всех вызовов на strcpy(dest, src) будет включать в себя вызов strncpy с параметрами (dest, src, length of dest - 1), а затем завершение dest с \0. Я знаю, что проблема заключается в том, что мы не всегда знаем длину dest, потому что это может быть указатель на память, выделенную в куче.Замена strcpy на strncpy

Предположим, что я могу вычислить длину dest на каждом из этих сайтов вызова. Я мог бы заменить все вызовы на strcpy с помощью вызовов strncpy, которые гарантируют, что моя программа невосприимчива к атакам переполнения буфера (по крайней мере, от неправильного использования strcpy). Тем не менее, этот подход может незаметно обрезать данные и изменять поведение программы нежелательным образом. Это лучший подход, чем обнаружение усечения и прерывание программы? Или лучше разрешить усечение, но также записать его?

Я спрашиваю с точки зрения того, кто заинтересован в разработке автоматизированного метода для исправления устаревшего кода. У кого-нибудь есть мысли о том, как наилучшим образом подойти к этой проблеме?

+0

strncpy() намного хуже. Посмотрите на свою реализацию CRT для альтернатив. Или просто напишите свое. Это не простая подстановка, вам нужно знать размер буфера, и это может потребовать изменения сигнатур функций, поэтому размер буфера передается в качестве аргумента. –

+0

Я бы не стал изменять исходный код для реализации этих изменений. Я бы модифицировал программу на промежуточном языке, который позволяет получить доступ к этим размерам буфера. Я бы хотел, чтобы возвращаемый тип этих вызовов оставался прежним, поэтому альтернативы CRT не хватит. – RouteMapper

+0

Я не могу себе представить, что тихое усечение данных всегда хорошо. Я согласен с @HansPassant, что реализация вашей собственной strncpy может быть правильным путем. Затем вы можете поместить (как минимум) ведение журнала, когда усечение происходит прямо внутри этой функции. – Jud

ответ

6

Мы все знаем, что strcpy небезопасно, потому что он оставляет программу уязвимой для проблем с переполнением буфера.

Это не вина strcpy в малейшем: это до программистов, чтобы гарантировать, что строка будет вписываться в их буфер, например, путем вызова strlen перед копированием, или обеспечения того, чтобы строки который входит, не может быть длиннее, чем их буфер.

Скажем, я хочу, чтобы заменить все вызовы strcpy с призывами strncpy

Вы не должны сделать это, если вы не работаете со строками фиксированного размера: помните, что strncpy не только копии вверх к завершающему нулю, но также заполняет остальную часть строки нулевыми байтами. Если вы ищете «современную замену» strcpy, попробуйте вместо этого использовать strlcpy.

Этот подход может бесшумно усекать данные и изменять поведение программы нежелательным образом. Это лучший подход, чем обнаружение усечения и прерывание программы? Или лучше разрешить усечение, но также записать его?

Это полностью зависит от вас. Это зависит от места в вашем дизайне, где бы произошло такое усечение: если это происходит в коде, который отправляет информацию аутентификации в веб-службу, вам лучше прекратить процесс прямо тогда; если это происходит в коде, который записывает сообщение трассировки в журнал, вероятно, стоит игнорировать проблему или занести ее в журнал и продолжить. К сожалению, вы не можете решить это автоматически, потому что требуется определенный уровень понимания программы.

+0

Я понимаю, что 'strcpy' делает то, что он обещает, и не« виноват »за все, что делает программист. Как заряженный пистолет в руке неопытного оператора, он считается «небезопасным».« Причина, по которой я спрашиваю об этом, заключается в том, что я изучаю способы переоснащения функций безопасности в существующие кодовые базы. Я полагаю, что с исследовательской точки зрения я мог бы просто объяснить плюсы/минусы ведения журнала и прерывания. не привязаны к выбору конкретного подхода. Я просто хочу удостовериться, что я слышу другие мнения по этой проблеме и довольный подход ко всем сторонам. – RouteMapper

+0

Это заявление «strncpy не только копирует до конечного нуля, но также заполняет остальную часть строка с нулевыми байтами "неверна. Из стандарта C:" символы, следующие за нулевым символом, не копируются " –

+0

@ RouteMapper Продолжая аналогию с оружием, у вас есть как минимум два способа устранить проблему: обучите оператора или возьмите – dasblinkenlight

1

strncpy не является функцией STL. :) C не имеет библиотеки STL. Я не думаю, что это хорошая идея, чтобы заменить все вхождения strcpy на strncpy. Такой подход должен быть различным в зависимости от ситуации. В большинстве случаев достаточно использовать strcpy.

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