Microsoft SDL и устаревшие memcpy - PullRequest
10 голосов
/ 18 мая 2009

Как некоторые из вас могут знать, Microsoft запретила memcpy() их жизненный цикл разработки безопасности , заменив его на memcpy_s().

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() и почему он устарел. Есть ли какой-либо общий вариант использования, который я не вижу? Что мне здесь не хватает?

Ответы [ 7 ]

14 голосов
/ 18 мая 2009

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

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

и проверьте ошибку.

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

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

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

8 голосов
/ 18 мая 2009

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

6 голосов
/ 18 мая 2009

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

4 голосов
/ 18 мая 2009

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

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

1 голос
/ 18 мая 2009

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

Самое главное, memcpy_s возвращает код ошибки, указывающий, была ли успешной вся копия, но с memcpy невозможно быть уверенным в этом. * * * * * * * * * * * * * * * * * * * * * * * * * * * memcpy * * * * * * * * * * * * * * * * * 100 * *.

0 голосов
/ 25 октября 2009

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

0 голосов
/ 24 июля 2009

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

End Rant.

...