strndup 调用正在破坏堆栈帧
我在 AIX 5.3 和 6.1 上看到了“strndup”调用的奇怪行为。 如果我调用 strndup 的大小大于实际源字符串长度的大小,则该调用后会出现堆栈损坏。
以下是可能出现此问题的示例代码:
int main ()
{
char *dst_str = NULL;
char src_str[1023] = "sample string";
dst_str = strndup(src_str, sizeof(src_str));
free(dst_str);
return 0;
}
有人经历过这种行为吗?
如果是,请告诉我。
根据我的观察,操作系统中一定有一个补丁解决了这个问题。但我无法获得该补丁(如果有的话)。请照亮一些。
谢谢&问候, 图姆贝蒂
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的代码中缺少
#include
。请尝试一下——我相当确定它会起作用。原因是,如果没有#include
,作用域内就没有strndup()
的原型,因此编译器会假设strndup( )
返回一个int
,并采用未指定数量的参数。这显然是错误的。 (我假设您正在 POSIX 兼容模式下进行编译,因此可以使用strndup()
。)因此,在启用警告的情况下编译代码始终很有用。
如果更改后问题仍然存在,则可能存在错误。
编辑:看起来可能有一个 strndup() 的问题:问题似乎出在 AIX 上损坏的
strnlen()
函数中。如果即使在#include
之后您仍看到问题,则您很可能遇到了该错误。 Google 搜索 显示一长串相关结果。编辑2:
您可以尝试以下程序并发布结果吗?
(取自 https://bugzilla.samba.org/show_bug.cgi?id =1097#c10。)
编辑 3:看到输出后,即
>01234567890123456789012345678<
,且没有strndup 损坏,我认为您的 AIX 版本没有
strndup
bug。最有可能的是你在某个地方破坏了内存(考虑到问题只在某些条件下出现在大型程序中)。您能制作一个小型、完整、可编译的示例来展示堆栈损坏问题吗?否则,您将必须调试程序中的内存分配/释放。有许多程序可以帮助您做到这一点,例如 valgrind、valgrind、glibc mcheck, dmalloc、electricfence 等。
You are missing a
#include <string.h>
in your code. Please try that—I am fairly sure it will work. The reason is that without the#include <string.h>
, there is no prototype forstrndup()
in scope, so the compiler assumes thatstrndup()
returns anint
, and takes an unspecified number of parameters. That is obviously wrong. (I am assuming you're compiling in POSIX compliant mode, sostrndup()
is available to you.)For this reason, it is always useful to compile code with warnings enabled.
If your problem persists even after the change, there might be a bug.
Edit: Looks like there might be a problem with
strndup()
on AIX: the problem seems to be in a brokenstrnlen()
function on AIX. If, even after#include <string.h>
you see the problem, it is likely you're seeing the bug. A google search shows a long list of results about it.Edit 2:
Can you please try the following program and post the results?
(Taken from https://bugzilla.samba.org/show_bug.cgi?id=1097#c10.)
Edit 3: After seeing your output, which is
>01234567890123456789012345678<
, and with nostrndup is broken
, I don't think your version of AIX has thestrndup
bug.Most likely you are corrupting memory somewhere (given the fact that the problem only appears in a large program, under certain conditions). Can you make a small, complete, compilable example that exhibits the stack corruption problem? Otherwise, you will have to debug your memory allocation/deallocation in your program. There are many programs to help you do that, such as valgrind, glibc mcheck, dmalloc, electricfence, etc.
老话题了,不过我也遇到过这个问题。 AIX 6.1 上的一个简单测试程序结合 AIX 的 MALLOCDEBUG 证实了该问题。
编译并运行带有缓冲区溢出检测的程序:
现在运行 dbx 来分析核心:
跟踪 strndup 中的指令,看起来它分配了一个缓冲区,该缓冲区的大小刚好足以处理 s 中的字符串加上 NULL 终止符。但是,它总是将 n 个字符复制到新缓冲区,必要时用零填充,如果 strlen(s) < 则导致缓冲区溢出。名词
Old topic, but I have experienced this issue as well. A simple test program on AIX 6.1, in conjunction with AIX's MALLOCDEBUG confirms the issue.
Compile and run the program with buffer overflow detection:
Now run dbx to analyze the core:
Tracing through the instructions in strndup, it appears that it mallocs a buffer that is just large enough to handle the string in s plus a NULL terminator. However, it will always copy n characters to the new buffer, padding with zeros if necessary, causing a buffer overflow if strlen(s) < n.
阿洛克是对的。使用glibc下的gcc工具链,您需要定义_GNU_SOURCE来获取strndup的decl,否则它不会被decl'd,例如:
compilo:
Alok is right. and with the gcc toolchain under glibc, you would need to define _GNU_SOURCE to get the decl of strndup, otherwise it's not decl'd, e.g.:
compilo:
非常感谢您的及时回复。
我已经尝试过给定的程序。
以下是结果:
在我包含的程序中,问题仍然存在。
以下是前置代码中的 strndup 声明。
我想澄清一件事,对于小程序,我不会受到堆栈损坏的影响。它始终出现在我的产品中,该产品具有大量函数调用。
按以下方式使用 strndup 解决了问题:
请注意:使用 strlen 而不是 sizeof,因为我只需要有效的字符串。
我试图理解为什么会发生这种情况。
当我使用大尺寸的 strndup 时,我在产品中看到的行为:
所有这些问题只需根据源字符串的实际大小修改 strndup 的使用即可解决。
谢谢&问候,
图姆贝蒂
Thanks a lot for your prompt responses.
I have tried the given program.
following is the result:
In my program I have included , still problem is persistent.
Following is the strndup declaration in prepossessed code.
I would like to clarify one thing, with small program I don't get effect of stack corruption. It is consistently appearing in my product which has huge amount of function calls.
Using strndup in the following way solved the problem:
Please note: used strlen instead of sizeof as i need only the valid string.
I am trying to understand why it is happening.
Behavior i am seeing with my product when i use strndup with large size:
All these issues are resolved by just modifying the usage of strndup with actual size of source string.
Thanks & Regards,
Thumbeti