安全C和大学 – 训练缓冲区溢出

我最近在C完成了大学课程。所以我当然缺乏经验。

一些大学倾向于教他们的学生安全的编程, 或至少一些元素 。 甚至有一个video (从这里拍摄)。

在C中,复制字符串,据我所知 – strcpy或string.h函数。 如何在日常编程中安全地使用它? 你有一些函数,它们处理分配以防止缓冲区溢出吗? 有C的CERT安全编码标准 。 它提供示例和合规解决方案:

int main(int argc, char *argv[]) { /* ... */ char prog_name[128]; strcpy(prog_name, argv[0]); /* ... */ } 

他们的替代方案是:

 int main(int argc, char *argv[]) { /* ... */ char *prog_name = (char *)malloc(strlen(argv[0])+1); if (prog_name != NULL) { strcpy(prog_name, argv[0]); } else { /* Couldn't get the memory - recover */ } /* ... */ } 

从这里开始, 第二个例子 。

但据我所知,这更具挑战性,更多代码,更多工作。 为什么没有人改变图书馆本身? 或者至少为什么没有人提供安全的替代库或function,以正确的方式处理这个?

谢谢你的阅读,愿

Posix函数(几乎在每个系统上都可用)是strdup() 。 如果您不想分配新内存并且已经有一个想要使用的缓冲区,则使用strcpy() ,但是您可以更好地了解缓冲区的大小以及字符串是否适合它。 如果您不知道字符串是否适合,则strncpy()只复制给定数量的字符。 因此,您可以将复制的数量限制为缓冲区大小。

除此之外,还有许多sting库以不同的方式管理字符串大小。

因为你标记了它C ++:有std::string为你做所有的内存管理,并没有给你这些问题。

OpenBSDl (strlcpy,strlcat)函数通常比n函数更好,它们更安全,更容易使用,但它们是非标准的。 但是,它们是BSD许可的,因此您可以在任何程序中包含已知良好的实现,这样您就可以跨平台和安全。

对于Windows,如果您不关心可移植性,可以使用* _s函数。

使用strncpy

 #define BUFSIZE 127 int main(int argc, char *argv[]) { /* ... */ char prog_name[BUFSIZE + 1]; strncpy(prog_name, argv[0], BUFSIZE); progname[BUFSIZE]= '\0'; /* ... */ } 

大多数str*函数都有*n*版本。

如果我理解正确,那么您真正的问题是为什么API函数不会更安全。

原因之一是C库是遗留的(现在改变它太晚了)。

然而,主要原因是该库设计为简约,因此它只做了最低限度,并且用户有责任确保正确调用它。 如果它正在进行任何过度检查,则每次调用时都会支付价格,即使用户可以确保其他原因不会发生任何问题。 这在许多API中非常常见。

话虽这么说,有足够的库提供更安全的替代品,他们只是不是标准库的一部分。 此外,许多从事更高级别工作的人都使用C ++,其中包含许多标准类库。

实际上,微软确实为CRTfunction提供了安全的替代方案。 我认识的每个人都讨厌他们,并禁用你不应该使用旧function的警告。 如果你想要安全的东西,也许你应该使用C ++。 然后是STL字符串或Qt之类的东西。

好吧,或者你去.NET或Java这样的平台,它们通常不会遇到这些问题(你的应用程序可能会崩溃,但无法通过缓冲区溢出将代码注入你的应用程序)。

编辑:启用数据执行保护/ NX(Vista和.NET的默认设置),这对传统平台来说也不是问题。

 int main ( int argc, char *argV[] ) { char prog_name[128]; if (strlen(argV[0]) < sizeof(prog_name)) { strcpy(prog_name, argV[0]); } else { printf("%s is too large for the internal buffer\n", argV[0]); } return 0; } 

也许你会找到这个问题的有用阅读答案