Memcpy() в безопасном программировании?

Недавно я наткнулся на статью, в которой утверждается, что Microsoft запрещает функцию memcpy() в своих магазинах безопасного программирования. Я понимаю уязвимости, присущие функции, но нужно ли полностью запрещать ее использование?

Должны ли программы, которые я пишу, избегать memcpy() полностью или просто обеспечить безопасное использование? Какие существуют альтернативы, которые обеспечивают аналогичную, но более безопасную функциональность?

Ответы

Ответ 1

Microsoft предоставляет альтернативы для memcpy и wmemcpy, которые проверяют их параметры.

memcpy_s говорит: "Хм, прежде чем я прочитаю с этого адреса, позвольте мне убедиться, что это не нулевой указатель, и прежде чем я напишу на этот адрес, я снова повторю этот тест. из числа байтов мне было предложено скопировать на заявленный размер адресата, тогда и только тогда, когда вызов пройдет все эти тесты, я должен выполнить копию".

memcpy говорит: "Поместите пункт назначения в регистр, введите источник в регистр, введите счет в регистр, выполните MOVSB ​​или MOVSW". (Пример по геологам, не долго для этого мира: http://www.geocities.com/siliconvalley/park/3230/x86asm/asml1013.html)

Изменить: для примера в дикой форме "Желание моя команда" к memcpy рассмотрим OpenSolaris, где memcpy (для некоторых конфигураций) определенный в условия bcopy и bcopy (для некоторых конфигураций)...

void
     33 bcopy(from, to, count)
     34 #ifdef vax
     35     unsigned char *from, *to;
     36     int count;
     37 {
     38 
     39     asm("   movc3   12(ap),*4(ap),*8(ap)");
     40 }
     41 #else
     42 #ifdef u3b      /* movblkb only works with register args */
     43     unsigned char *from, *to;
     44     int count;
     45 {
     46     asm("   movblkb %r6, %r8, %r7");
     47 }
     48 #else
     49     unsigned char *from, *to;
     50     int count;
     51 {
     52     while ((count--) > 0)
     53         *to++ = *from++;
     54 }
     55 #endif

Редактировать: Спасибо, Милли Смит! Вот что было на странице географии, которую я связал выше:

MOVS

Команда movs используется для копирования исходной строки в пункт назначения (да, копирование, а не перемещение). Эта инструкция имеет два варианта: movsb и movsw. Movsb ( "перемещать строковый байт" ) перемещает один байт за раз, тогда как movsw перемещает два байта за раз.

Поскольку мы хотели бы перемещать несколько байтов за раз, эти команды movs выполняются партиями с использованием префикса rep. Количество движений задается регистром CX. См. Пример ниже:

:
lds   si, [src]
les   di, [dest]
cld
mov   cx, 100
rep   movsb
:

В этом примере будет скопировано 100 байт из src в dest. Если вы замените movsb на movsw, вместо этого вы копируете 200 байт. Если вы удалите префикс rep, регистр CX не будет иметь никакого эффекта. Вы перемещаете один байт (если это movsb или 2 байта, если это movsw).

Ответ 2

Бензопила, если она используется правильно, безопасна. То же самое с memcpy(). Но в обоих случаях, если вы нажмете гвоздь, он может летать и причинять вам боль.

Короче говоря, memcpy() требуется для низкоуровневых вычислений и не исчезнет, ​​но для высокоуровневого программирования вам это не нужно. В Python отсутствует memcpy().

Ответ 3

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

Ответ 4

Не беспокойтесь. Альтернативы Microsoft не намного лучше. Главное - это то, что ваш код становится неспособен к Linux. Microsoft зарабатывает гораздо больше денег на ОС, которые они продают своим клиентам, чем на копии Visual С++, которую вы купили.

Ответ 5

Я запрещаю memcpy() в моем коде, что делает меня лучшим программистом, а мое приложение более безопасным или просто более несовместимым? Я не уверен, если MS действительно хочет что-то изменить или просто сделать новый код C несовместимым с другими компиляторами. Btw. MS делает этот трюк на многих функциях, и это довольно раздражает. strcpy → strcpy_s → StringCchCopy.

Ответ 6

Я думаю, что C должен оставить возможность программисту стрелять в собственную ногу. ручное управление памятью безопасно, если выполнено правильно.

Ответ 7

Вы сами сказали: "Microsoft запрещает функцию memcpy() в защищенных магазинах программирования, я понимаю уязвимости , присущие функции,

memcpy() и многие другие стандартные функции, как известно, вызывают уязвимости, поэтому почему безопасный магазин программирования позволяет использовать их, когда (хотя и постепенное) улучшение тривиально?

Несомненно, в своих усилиях по повышению безопасности своих продуктов обзоры кода четко указывают на то, что эти функции несут ответственность за значительную долю уязвимостей, переполнение буфера и т.д. Вместо того, чтобы создавать обертки для внутреннего использования, они вводили их в стандартную библиотеку и добавили предупреждение компилятора (а не запрет) на благо всех.

Ответ 8

Альтернативой является вызов memcpy_s

Ответ 9

Если вы используете более старые версии, например C99 или С++ 98, или в Solaris, вы не можете использовать memcpy_s, если у вас нет установленной библиотеки Safe C.

memcpy_s() - это реализация, специфичная для Microsoft, которая не существует в реализациях, отличных от MS, включая ANSI, до C11, по их собственным стандартам.

Я оставлю материал pro-MS и ant-MS в стороне, потому что это не имеет значения.

memmove() - лучшее решение, так как оно затрагивает проблему перекрытия. memmove_s() более надежный, но опять же, только если вы на C11 или новее.

Ответ 10

Вместо этого вы должны использовать memcpy_s(). Такие же версии _s существуют для множества других функций, которые считаются незащищенными.