下述strcpy_s调用是否会造成不安全的越界数据写入?
strcpy_s使用场景下的越界风险判定
确定性结论
你写的这段代码存在明确的高危越界写入风险,哪怕用了带安全机制的strcpy_s,这个问题依然存在,具体原因如下:
- 堆内存的合法边界:当初给
name指针申请的内存空间,是按照短名称BlueBug的长度计算的,总大小仅为8字节(7个有效字符+1个字符串结束符)。这是操作系统给你划定的合法操作范围,超出这个范围的写入全部属于未授权的越界操作。 - strcpy_s的入参传递错误:第二次调用函数时,你传入的第二个参数(目标缓冲区的声明容量)是
strlen(myNewName) + 1,也就是新字符串本身需要的存储空间大小,完全不是这块目标内存的真实分配容量。
为什么没有触发你预期的安全报错
你原本以为写入超长内容时会自动触发安全拦截,实际上不会触发,核心逻辑是:
strcpy_s的安全校验完全依赖你主动传入的「目标缓冲区大小」参数运行,函数本身没有能力主动探测一块堆内存的真实分配边界。
你传入的容量值和新字符串的实际需求完全匹配(比如新名称长度22,你就传入23字节作为缓冲区容量),函数内部的校验逻辑会判断“源内容需要23字节空间,目标缓冲区声明有23字节容量,校验通过”,随后直接从name指向的内存起始地址,连续写入全部23字节的新名称内容。
这部分写入中,只有前8字节落在你合法申请的内存范围内,剩余的15字节会直接写入你无操作权限的相邻堆内存区域。这些区域可能存储了堆块管理元数据、其他程序变量、函数调用返回地址,被篡改后轻则导致程序随机崩溃,重则被攻击者利用实现任意代码执行。
正确的使用方式
- 调用
strcpy_s时,第二个参数必须填写目标缓冲区的真实分配大小,绝对不能填写源字符串本身的长度。 - 如果新内容长度超过原有缓冲区的容量,必须先重新申请足够的内存空间,释放原有旧内存后再执行复制操作,不能直接向旧缓冲区硬写超长内容。
内容的提问来源于stack exchange,提问作者Blue Bug
相关产品推荐
相关产品推荐

