Microsoft SDL和memcpy弃用

Ale*_*x B 10 c security memcpy

正如你们中的一些人所知,微软已经取消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);
Run Code Online (Sandbox Code Playgroud)

因此,如果您的代码曾经是:

if (in_len > dst_len) {
    /* error */
}
memcpy(dst, src, in_len);
Run Code Online (Sandbox Code Playgroud)

它成为了:

if (memcpy_s(dst, dst_len, src, src_len)) {
    /* error */
}
Run Code Online (Sandbox Code Playgroud)

或者,截断,

memcpy(dst, src, min(in_len, dst_len));
Run Code Online (Sandbox Code Playgroud)

VS

(void)memcpy_s(dst, dst_len, src, src_len);
Run Code Online (Sandbox Code Playgroud)

问题:额外长度参数如何使代码更安全?要使用memcpy(),我应该已知所有四个参数,并将适当的长度作为第三个参数传递.什么阻止我犯错误计算目标缓冲区大小并传递错误的价值dst_size?我不明白为什么它memcpy()与它有任何不同以及它被弃用的原因.有没有我看不到的常见用例?我在这里错过了什么?

pax*_*blo 14

没有什么能阻止你在"安全"版本中获取参数错误.微软似乎认为你总会使用类似的东西:

errno_t e = memcpy_s (&dstbuff, sizeof(dstbuff), &srcbuff, sizeof(srcbuff));
Run Code Online (Sandbox Code Playgroud)

并检查错误.

但这只能帮助那些不知道他们用语言做什么的人.在我看来,这群人要么不应该使用这种语言,要么应该学习它是如何正常运作的.

从长远来看,这种拐杖不会对它们有任何好处,因为它们的代码不可移植.

现在可能是微软做了一些分析,发现人们滥用导致了很多问题memcpy(),他们认为这会解决问题.但是,如果是这种情况,我怀疑更好的解决方案是教育开发人员而不是强迫他们使用标准编译器中不可用的非标准功能.

  • "从长远来看,这种拐杖对他们没有任何好处......"完全同意,Pax. (3认同)
  • 第一部分是右边,第二部分是错误的 - 它不是拐杖,它实际上更适合那些认为自己是"语言如何运作"的专家,并且总是在寻找捷径.正如@ninesided所说,新的"安全"版本会让你思考你正在做什么,并(希望)停止尝试解决这门语言问题. (3认同)
  • 鼓励程序员编写非可移植代码对微软非常有帮助. (2认同)

小智 8

信息重复总是糟糕的设计 - 它只会让你有更多机会弄错.在API设计方面,微软拥有适当的记录,并且过去仅通过其优秀的文档保存.令人欣慰的是,它们无法删除原始的memcpy()函数 - 它是ANSI C的一部分.


Mat*_*hen 6

你是绝对正确的.如果要跟踪两个缓冲区的长度,memcpy可以安全使用.如果你不是,memcpy_s将不会救你.