2009-05-18 2 views
10

Как вы знаете, Microsoft banned memcpy() from their Security Development Lifecycle, заменив его на memcpy_s().Отказ Microsoft SDL и memcpy

void *memcpy(void *dest, const void *src, size_t n); 

/* simplified signature */ 
errno_t memcpy_s(void *dst, size_t dstsize, const void *src, size_t n); 

Так что, если ваш код раньше:

if (in_len > dst_len) { 
    /* error */ 
} 
memcpy(dst, src, in_len); 

становится:

if (memcpy_s(dst, dst_len, src, src_len)) { 
    /* error */ 
} 

Или, с усечением,

memcpy(dst, src, min(in_len, dst_len)); 

против

(void)memcpy_s(dst, dst_len, src, src_len); 

Вопрос: как дополнительный параметр длины делает код более безопасным? Чтобы использовать memcpy(), я должен был уже знать все четыре параметра и передавать соответствующую длину в качестве третьего аргумента. Что мешает мне совершить ту же ошибку, просчитав размер буфера назначения и пропуская неправильный знак dst_size? Я не понимаю, почему он отличается от memcpy() и почему он устарел. Есть ли какой-либо общий вариант использования, который я не вижу? Что мне здесь не хватает?

+0

Имейте в виду, что memcpy_s() является частью C11 приложения К, что только * продается отдельно * часть C11 спецификация. Некоторые разработчики компиляторов отклонили Приложение K и никогда не будут реализовывать его. Поэтому используйте его только в том случае, если определен '__STDC_LIB_EXT1__'. Redhat рекомендовал удалить его из будущих спецификаций C. – DavidJ

ответ

14

Ничто не мешает вам получить неправильные параметры в «защищенной» версии. Microsoft, похоже, думает, что вы всегда будете использовать что-то вроде:

errno_t e = memcpy_s (&dstbuff, sizeof(dstbuff), &srcbuff, sizeof(srcbuff)); 

и проверьте его.

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

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

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

+3

«Этот костыль в конце концов не делает им никаких пользы ...» полностью согласен, Пакс. – ninesided

+3

Первая часть справа, вторая часть неправильная - это не костыль, и это на самом деле предназначено больше для тех, кто считает себя экспертами «как работает язык» и всегда ищет ярлыки. Новая «безопасная» версия, как сказал @ninesided, заставляет задуматься о том, что вы делаете, и (надеюсь) перестать пытаться работать с языком. – AviD

+0

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

4

Ты ничего не хватает, я думаю, что этот отрывок из статьи, которую вы связаны в значительной степени покрывает его:

Если ничего другого, memcpy_s заставляет вас думать о размере целевого буфера ,

6

Вы абсолютно правы. Если вы отслеживаете длину обоих буферов, memcpy безопасен в использовании. Если вы этого не сделаете, memcpy_s не спасет вас.

1

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

Важнейшим из всех, memcpy_s возвращает код ошибки, указывающий, удалась ли вся копия, но с memcpy нет способа быть уверенным в этом. Это - это то, что Microsoft чувствует, делает memcpy_s более безопасным, чем memcpy.

+0

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

+0

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

8

Дублирование информации - это всегда плохая конструкция - это просто дает вам больше шансов получить что-то неправильно. У Microsoft есть приложение appaling, когда дело доходит до разработки API, и были сохранены в прошлом только благодаря превосходству их документации. Удовлетворительная вещь заключается в том, что они не могут удалить оригинальную функцию memcpy() - она ​​является частью ANSI C.

+1

+1 Согласен. Я думаю, что основной проблемой безопасности MS и другими низкоуровневыми «хардкорными» программистами должно быть дело с переполнением буфера. Все, что может (должно) быть проверено сильными типизированными языками (C#, Java, Ada и т. Д.). – ATorras

+1

"они не могут удалить оригинальную функцию memcpy()", однако, что они могут сделать, это заставить выплевывать предупреждения. И если они этого хотят, они могут сделать эти предупреждения трудными или невозможными игнорировать. –

-1

Я действительно иногда заказываю, действительно многие из нас, настоящие программисты, больше не видят в мире машина для чего она есть, и любовь смещается вокруг. Немного от темы, которую я знаю, но мне нравится точно знать, что происходит, и определенно не хочет, чтобы какой-нибудь хромой сборщик мусора, обходящий фон, отчаянно пытаясь разобраться в неряшливых программистах грязных куч. Я имею в виду, насколько сложно сопоставлять вызовы free() с вызовами в malloc()/strdup(), насколько сложно удостовериться, что вы выделили достаточное пространство для буфера, чтобы знать, что вы можете вызвать memcpy() saefly? Ответ: Не очень, но 99,9% программистов действительно не заботятся о том, что они делают, потому что они просто в этом за деньги, а не в страсти писать добросовестно секретную часть кода.

End Rant.

0

C, как сборки для людей, которые знают, что они делают, я помню, чтобы прочитать что-то подобное direcly из K & R