什么 C/C++ 函数最常被错误使用并可能导致缓冲区溢出?

发布于 2024-07-06 19:43:04 字数 297 浏览 19 评论 0原文

我被要求维护一个充满内存泄漏的大型 C++ 代码库。 在四处探索时,我发现我们有很多缓冲区溢出导致泄漏(我不想知道它是如何变得如此糟糕的)。

我决定首先消除缓冲区溢出,从危险的函数开始。 哪些 C/C++ 函数最常被错误使用并可能导致缓冲区溢出?

对于用于帮助查找缓冲区溢出的编译器和/或工具,我创建了另一个涉及此问题的问题

I've been asked to maintain a large C++ codebase full of memory leaks. While poking around, I found out that we have a lot of buffer overflows that lead to the leaks (how it got this bad, I don't ever want to know).

I've decided to removing the buffer overflows first, starting with the dangerous functions. What C/C++ functions that are most often used incorrectly and can lead to buffer overflow?

For compiler and/or tools used to help look for buffer overrun, I've created another question that deals with this

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

音栖息无 2024-07-13 19:43:04

一般来说,任何不检查参数范围的函数。 列表将是

  • gets()
  • scanf()
  • strcpy()
  • strcat()

您应该使用大小受限的版本,如 stncpy、strncat、fgets 等。然后在给出大小限制时要小心; 考虑终止字符串的“\0”。

此外,在 C 或 C++ 中,数组不进行绑定检查。 下面的例子会导致错误。 请参阅因一个错误而关闭

int foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

编辑:复制的答案@MrValdez,@Denton Gentry

In general, any function that does not check bounds in the arguments. A list would be

  • gets()
  • scanf()
  • strcpy()
  • strcat()

You should use size limited versions like stncpy, strncat, fgets, etc. Then be careful while giving the size limit; take into consideration the '\0' terminating the string.

Also, arrays are NOT bound checked in C or C++. The following example would cause errors. See off by one error

int foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

edit: Copied answers of @MrValdez , @Denton Gentry

南…巷孤猫 2024-07-13 19:43:04

Valgrind 是你最好的新朋友。

valgrind --tool=memcheck --leak-check=full ./a.out

Valgrind is your new best friend.

valgrind --tool=memcheck --leak-check=full ./a.out

感性 2024-07-13 19:43:04

恐怕这个问题是从错误的一端开始的。 假设其他函数中发生了缓冲区溢出。 根据我的经验,最常见的原因是运算符++,或者缺少运算符!=。

找到一批这些的最佳解决方案是 Visual Studio 2005/8 中的 /GS。 它不会找到所有这些,但这是减少所需手动工作量的一种廉价方法。

The question is starting at the wrong end, I'm afraid. It's presuming that buffer overruns happen in other functions. The most common cause is operator++, in my experience, or alternatively a lack of operator!=.

The best solution to find a batch of those is /GS in Visual Studio 2005/8. It won't find all of them, but it's a cheap way to reduce the amount of manual work needed.

草莓酥 2024-07-13 19:43:04

以下是我发现的一些危险函数:

  • gets() - 它不会检查变量的长度,并且如果输入大于变量的缓冲区,则可能会覆盖内存。
  • scanf() - 我很高兴 Visual Studio 告诉我这个函数已被弃用。 这是一个简单的修复。
  • strcpy() - 如果源的内存空间大于目标的内存空间,则覆盖目标之后的数据。

Here's some functions that I found that are dangerous:

  • gets() - It doesn't check the length of the variable and can overwrite memory if the input is bigger than the variable's buffer.
  • scanf() - I'm so glad that Visual Studio told me this function is deprecated. This was an easy fix.
  • strcpy() - If the source's memory space is bigger than the destination's, the data after the destination is overwritten.
神回复 2024-07-13 19:43:04

不幸的是,任何数组都可能导致缓冲区溢出:

uint32_t foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

就函数而言,sprintf 会很高兴地走出缓冲区的末尾。 可以用snprintf代替。

Unfortunately any array can result in a buffer overflow:

uint32_t foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

In terms of functions, sprintf will happily walk off the end of the buffer. It can be replaced by snprintf.

冷清清 2024-07-13 19:43:04

Memcpy() 是另一个危险的函数。

任何访问数组的循环都是危险点,因为无法停止超出数组末尾。

内存泄漏是由于分配内存而不是释放内存而引起的。 构造函数和析构函数应该是另一个重要的审查点,后者确保释放任何分配的内存。

Memcpy() is another dangerous one.

Any loop accessing an array is a danger point, because there's no stopping going beyond the end of array.

Memory Leaks are caused by allocating memory, and not freeing it. Constructor and destructors should be another strong review point, the latter to make sure any allocated memory is freeded.

墨离汐 2024-07-13 19:43:04

您使用的是哪个版本的 Visual Studio? 在 2008 年,启用所有警告后,您提到的所有功能(以及更多)都会警告您它们已被弃用。

也许您可以检查所有警告是否已打开并让编译器为您完成艰苦的工作?

作为旁注,优秀的 编写安全代码很好地解释了一些旧函数的不同陷阱。

Which version of visual studio are you using? In 2008 with all warnings enabled, all the functions you mention (and more) warn you that they are deprecated.

Perhaps you could check that all warnings are turned on and let the compiler do the hard work for you?

As a side note, the excellent writing secure code does a great job explaining the different the pitfalls of some of the older functions.

霓裳挽歌倾城醉 2024-07-13 19:43:04

我在工作的代码库上也遇到了同样的问题。 我的建议:警惕任何类似 str*() 和 mem*() 的 C 函数。 还要警惕任何带有指向缓冲区的指针但没有长度的内容。 因为看起来你有机会使用 C++,所以在最令人震惊的情况下,我会尝试使用 C++ 容器来处理:向量、字符串、地图等。这些会让你的生活变得更轻松。

此外,自动问题检测工具也很棒。 如果你可以使用 valgrind 我会推荐它。 Rational Purify 的功能也极其强大,但并不便宜。

I have somewhat the same problem on the code base I work on. My advice: be wary of any C functions that look like str*() and mem*(). Also be wary of anything that takes a pointer to a buffer, without a length. Since it seems like you have the chance to use C++ I would in the most egregious cases try to use C++ containers for things: vector, string, map, etc. These make your life a lot easier.

Also, automated problem detection tools are wonderful to have. If you can use valgrind I would recommend it. Also Rational Purify is extremely powerful, though not cheap.

荒岛晴空 2024-07-13 19:43:04

以下链接应该让您全面了解 C++ 中的安全函数(后缀为“_s”以修复溢出等问题):http://msdn.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx

编辑:此链接包含已替换的特定函数:http://msdn.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx

编辑: 我应该提到这些是微软的方法,但是该链接对于识别被视为危险信号的功能仍然有用。

The following link should give you a comprehensive look at security functions in C++ (ones that are post-fixed with '_s' to fix problems like overflows): http://msdn.microsoft.com/en-us/library/8ef0s5kh(VS.80).aspx

EDIT: This link contains the specific functions that have been replaced: http://msdn.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx

EDIT: I should mention these are Microsoft methods, but the link is still useful for identifying functions that were deemed a red flag.

尐偏执 2024-07-13 19:43:04

C 中的另一个问题是“strncpy()”函数。 许多人没有意识到可以自由地返回非空终止的字符串。

An additional gotcha in C is the "strncpy()" function. Many people do not realize that it is free to return a string that is not null terminated.

寂寞清仓 2024-07-13 19:43:04

基本上,任何接受指针并写入它而不检查长度的东西。 比如 strcpy()、sprintf() 等。

Basically, anything which accept a pointer and writes to it, without checking the length. So thing like strcpy(), sprintf() etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文