硬汉嵌入式论坛

 找回密码
 立即注册
查看: 565|回复: 16
收起左侧

[其它] 防不胜防,排查程序发现strncpy设置的大小超出了buf缓冲

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
发表于 2025-10-10 09:47:43 | 显示全部楼层 |阅读模式
由于这个buf是个结构体变量,没有看大小就设置了。

类似下面这样,这种问题防不胜防

[C] 纯文本查看 复制代码
char buf[8];
strncpy(buf, src, 16);


改进成类似下面这样了:

[C] 纯文本查看 复制代码
char buf[8];
strncpy(buf, src, sizeof(buf) - 1); // 最多复制7字节
buf[sizeof(buf) - 1] = '\0';        // 手动补齐结尾
回复

使用道具 举报

26

主题

394

回帖

472

积分

高级会员

积分
472
发表于 2025-10-10 09:49:36 | 显示全部楼层
strncpy
https://forum.anfulai.cn/forum.p ... 7&fromuid=41790
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
 楼主| 发表于 2025-10-10 10:11:27 | 显示全部楼层
tovinz 发表于 2025-10-10 09:49
strncpy
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=118087&fromuid=41790
(出处: 硬汉嵌入 ...

我以前回复过你的帖子,我都忘了。

防不胜防。
回复

使用道具 举报

60

主题

689

回帖

874

积分

金牌会员

积分
874
发表于 2025-10-10 10:14:04 | 显示全部楼层
印象中这情况编译的时候是有警告的,以前经常就觉得只要没有错误警告都是忽略的,进了几次坑后警告也要消除才放心
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
 楼主| 发表于 2025-10-10 10:39:56 | 显示全部楼层
ou513 发表于 2025-10-10 10:14
印象中这情况编译的时候是有警告的,以前经常就觉得只要没有错误警告都是忽略的,进了几次坑后警告也要消除 ...

MDK下不提示。

这种问题不去看下buf大小,确实不好查,一些安全分析软件应该可以检测到。
回复

使用道具 举报

107

主题

594

回帖

930

积分

金牌会员

积分
930
QQ
发表于 2025-10-10 14:50:33 | 显示全部楼层
我之前也遇到过类似的。
我是sprintf的buf给的小了,sprintf会最后补0,所以4个字节应该给5个字节的buf。
导致后面的变量被修改,出现了奇怪的问题。

回复

使用道具 举报

3

主题

47

回帖

56

积分

初级会员

积分
56
发表于 2025-10-11 06:59:19 来自手机 | 显示全部楼层
为啥buf才是8要复制16个字节,这种情况就算是memset和memcpy都会出错。
回复

使用道具 举报

3

主题

47

回帖

56

积分

初级会员

积分
56
发表于 2025-10-11 06:59:19 来自手机 | 显示全部楼层
为啥buf才是8要复制16个字节,这种情况就算是memset和memcpy都会出错。

怎么发重复了,不需要审核了?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
 楼主| 发表于 2025-10-11 09:31:39 | 显示全部楼层
spi-sd 发表于 2025-10-11 06:59
为啥buf才是8要复制16个字节,这种情况就算是memset和memcpy都会出错。

怎么发重复了,不需要审核了?

因为没有去看buf的实际大小,错误的记成了也是16字节大小。

这个算是个代码的示意效果,实际代码比较这个稍麻烦些,容易导致错误配置。
回复

使用道具 举报

3

主题

47

回帖

56

积分

初级会员

积分
56
发表于 2025-10-11 10:54:10 来自手机 | 显示全部楼层
本帖最后由 spi-sd 于 2025-10-11 10:56 编辑
eric2013 发表于 2025-10-11 09:31
因为没有去看buf的实际大小,错误的记成了也是16字节大小。

这个算是个代码的示意效果,实际代码比较 ...

strncpy(buf, src, sizeof(buf) - 1); // 最多复制7字节
buf[sizeof(buf) - 1] = '\0';  

这样写会有bug吗?
另外后面那句可以写成下面这种也可以吧?
buf[sizeof(buf) - 1] = 0x00;  


另外sizeof(buf),如果buf里面没有00,会出错吗?
回复

使用道具 举报

5

主题

225

回帖

240

积分

高级会员

积分
240
发表于 2025-10-11 21:49:41 | 显示全部楼层
这种有时候运行的时候,还不一定100%出错。我就遇到过,偶尔出错,最后发现是越界了
回复

使用道具 举报

5

主题

134

回帖

149

积分

初级会员

积分
149
发表于 2025-10-12 01:14:31 | 显示全部楼层
spi-sd 发表于 2025-10-11 10:54
strncpy(buf, src, sizeof(buf) - 1); // 最多复制7字节
buf = '\0';  

'\0' 和 0x00 是完全等价的,可以写作 0x00。

sizeof 是关键字不是函数,除 C99 的可变长数组外,其他获取数据类型或变量长度形式的写法是编译期常量,在运行前就已经确认,与其中存储的数值无关。你所说计算长度而受空字符 '\0' 影响的,应当是计算字符串长度的 strlen,用于返回自指定首地址起的字符串长度(即非零字节长度,不含末尾零)。
回复

使用道具 举报

5

主题

134

回帖

149

积分

初级会员

积分
149
发表于 2025-10-12 01:15:07 | 显示全部楼层
spi-sd 发表于 2025-10-11 06:59
为啥buf才是8要复制16个字节,这种情况就算是memset和memcpy都会出错。

怎么发重复了,不需要审核了?

积分高于 50,初级会员就不用审核了
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119430
QQ
 楼主| 发表于 2025-10-12 10:24:21 | 显示全部楼层
spi-sd 发表于 2025-10-11 10:54
strncpy(buf, src, sizeof(buf) - 1); // 最多复制7字节
buf = '\0';  

12楼坛友回复。
回复

使用道具 举报

3

主题

47

回帖

56

积分

初级会员

积分
56
发表于 2025-10-12 16:07:19 来自手机 | 显示全部楼层
Penguins 发表于 2025-10-12 01:14
'\0' 和 0x00 是完全等价的,可以写作 0x00。

sizeof 是关键字不是函数,除 C99 的可变长数组外,其他 ...

感谢解答,我还以为这个也会去计算长度,原来是在编译的时候就定义好了吗?这算是常量?
回复

使用道具 举报

3

主题

47

回帖

56

积分

初级会员

积分
56
发表于 2025-10-12 16:07:20 来自手机 | 显示全部楼层
Penguins 发表于 2025-10-12 01:14
'\0' 和 0x00 是完全等价的,可以写作 0x00。

sizeof 是关键字不是函数,除 C99 的可变长数组外,其他 ...

感谢解答,我还以为这个也会去计算长度,原来是在编译的时候就定义好了吗?这算是常量?
回复

使用道具 举报

5

主题

134

回帖

149

积分

初级会员

积分
149
发表于 2025-10-12 18:25:06 | 显示全部楼层
spi-sd 发表于 2025-10-12 16:07
感谢解答,我还以为这个也会去计算长度,原来是在编译的时候就定义好了吗?这算是常量?

在编译完成的时候就已经是常量了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-22 04:11 , Processed in 0.047744 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表