微软的strncat读取超出源缓冲区边界的字节 [英] Microsoft's strncat reads bytes beyond source buffer boundaries

查看:137
本文介绍了微软的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的几种描述,但可以根据您的初衷而以两种方式解释它们.)

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

Update2 (有关编译器的信息) MS Visual Studio 2005版本8.0.50727.867. 构建平台:64位发行版(32位无复制版). 用来修复崩溃的操作系统:Windows Server 2008 R2.

更新3 该问题也通过使用MS Visual Studio 2012 11.0.50727.1内置的二进制文件得以重现.

更新4

文档对于strncat 状态:

src -指向要从

复制的以空终止的字节字符串的指针

因此,该实现可以假定src输入参数实际上是NUL终止的,即使它长于count字符.

为进一步确认, Microsoft自己的文档声明:

strSource

以空终止的源字符串.

另一方面,实际的C标准声明如下:

strncat函数追加不超过n个字符(空字符和 从s2指向的数组的末尾不附加) s1指向的字符串.

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

这当然可以通过参考C运行时库源代码针对特定于 的Microsoft实现来解决.

I observe an interesting problem with the Microsoft implementation of strncat. It touches 1 byte beyond the source buffer. Consider the following code:

#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 reads 1 byte after 112 byte block. So if you are unlucky enough to get allocation on an invalid page boundary, your application crashes. Large applications can crash intermittently in such places. (Note that such condition can be simulated with gflags PageHeap setting; block size has to be divisible by pointer size for proper alignment.)

Is this the expected behavior or a bug? Any links confirming that? (I read several descriptions of strncat but they can be interpreted both ways depending on your initial set of mind...)

Update (to answer questions about evidence): I apologize if it is not clear from the text above, but this is an experimental fact. I observe intermittent crashes in an application at strncat reading address src+srcBufSize. In this small example run with gflags PageHeap on crash reproduces consistently (100%). So as far as I can see the evidence is very solid.

Update2 (info on compiler) MS Visual Studio 2005 Version 8.0.50727.867. Build platform: 64 bit release (no repro for 32 bit). OS used to repro the crash: Windows Server 2008 R2.

Update 3 The problem also reproduces with a binary built in MS Visual Studio 2012 11.0.50727.1

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

Update 5 The problem will be fixed in the next VS release. No fix is planned for old versions. See the "Microsoft Connect" link above.

解决方案

The documentation for strncat states:

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

Therefore, the implementation can assume that the src input parameter is in fact NUL-terminated, even if it is longer than count characters.

For further confirmation, Microsoft's own documentation states:

strSource

Null-terminated source string.

On the other hand, the actual C standard states something like:

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.

As pointed out in the comments below, this identifies the second parameter s2 as an array and not a NUL-terminated string. However, this is still ambiguous with respect to the original question, because this documentation describes the ultimate effect on s1, rather than the behaviour of the function when reading from s2.

This could of course be settled with respect to the specific Microsoft implementation by consulting the C Runtime Library source code.

这篇关于微软的strncat读取超出源缓冲区边界的字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆