微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Microsoft的strncat读取源缓冲区边界之外的字节

我观察到strncat的Microsoft实现有一个有趣的问题.它接触源缓冲区之外的1个字节.请考虑以下代码
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

void main()
{
    char dstBuf[1024];
    char* src = malloc(112);
    memset(src,'a',112);
    dstBuf[0] = 0;
    strncat(dstBuf,src,112);
}

strncat在112字节块后读取1个字节.因此,如果您不幸在无效页面边界上进行分配,则应用程序崩溃.大型应用程序可能会在这些地方间歇性地崩溃. (请注意,可以使用gflags PageHeap设置模拟此类条件;块大小必须能够被指针大小整除才能正确对齐.)

这是预期的行为还是错误?任何确认的链接? (我阅读了strncat的几个描述,但它们可以通过两种方式解释,具体取决于你的初始思路……)

更新(回答有关证据的问题):
如果从上面的文字中不清楚,我道歉,但这是一个实验性的事实.我在strncat读取地址src srcBufSize的应用程序中观察到间歇性崩溃.在这个小例子中,gflags PageHeap在崩溃时运行一致(100%).所以据我所知,证据非常可靠.

Update2(关于编译器的信息)
MS Visual Studio 2005版本8.0.50727.867.
构建平台:64位版本(32位无repro).
用于重现崩溃的操作系统:Windows Server 2008 R2.

更新3此问题还使用MS Visual Studio 2012 11.0.50727.1中内置的二进制文件重现

更新4 Link to issue on Microsoft Connect; link to discussion on MSDN Forums

更新5问题将在下一个VS版本中修复.旧版本没有计划修复.请参阅上面的“Microsoft Connect”链接.

documentation for strncat声明:

src – pointer to the null-terminated byte string to copy from

因此,实现可以假设src输入参数实际上是NUL终止的,即使它比计数字符长.

为进一步确认,Microsoft’s own documentation规定:

strSource

Null-terminated source string.

另一方面,actual C standard表示:

The strncat function appends not more than n characters (a null character and
characters that follow it are not appended) from the array pointed to by s2 to the end of
the string pointed to by s1.

正如下面的注释中所指出的,这将第二个参数s2标识为数组而不是以NUL结尾的字符串.然而,对于原始问题,这仍然是模棱两可的,因为该文档描述了对s1的最终影响,而不是从s2读取时函数的行为.

当然,这可以通过查阅C运行时库源代码解决特定的Microsoft实现.

原文地址:https://www.jb51.cc/windows/363441.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐