Вопрос

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

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

Это было полезно?

Решение

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

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

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

Редактировать:Например, в дикой природе Ваше желание для меня закон подход к memcpy, рассмотрите OpenSolaris, где memcpy (для некоторых конфигураций) определено в терминах 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

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

МОВС

Инструкция movs используется для копирования исходной строки в место назначения (да, копировать, а не перемещать).Данная инструкция имеет два варианта:мовсб и мовсв.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).

Другие советы

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

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

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

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

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

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

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

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

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

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

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

Я оставлю в стороне все, что связано с РС и против РС, потому что это не имеет значения.

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

Альтернатива — позвонить memcpy_s

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top