硬汉嵌入式论坛

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

[STM32H7] 大家有没有好点的机制,有效检测局部变量操作越界

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
发表于 2021-11-23 08:57:23 | 显示全部楼层 |阅读模式


我发现这是一个很容易出错的地方,比如sprintf函数,用户给的buf缓冲不足,又比如数据复制粘贴不小心越界了。



回复

使用道具 举报

0

主题

216

回帖

216

积分

高级会员

积分
216
发表于 2021-11-23 09:08:21 | 显示全部楼层
这些函数都有替代的,比如sprintf可以用snprintf,需要传入buf的长度,超过了就截断
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-23 09:18:08 | 显示全部楼层
regbbs 发表于 2021-11-23 09:08
这些函数都有替代的,比如sprintf可以用snprintf,需要传入buf的长度,超过了就截断

这种的有必要求下字符串长度。
回复

使用道具 举报

1

主题

369

回帖

372

积分

高级会员

积分
372
发表于 2021-11-23 14:18:51 | 显示全部楼层
好像每年都中过一次招
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-23 14:24:15 | 显示全部楼层
挖东衣宇 发表于 2021-11-23 14:18
好像每年都中过一次招

C库里面这种函数很多,不小心就中招了,最近在找一个靠谱的方法解决下。
回复

使用道具 举报

335

主题

2037

回帖

3047

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3047
发表于 2021-11-23 14:56:23 | 显示全部楼层
eric2013 发表于 2021-11-23 14:24
C库里面这种函数很多,不小心就中招了,最近在找一个靠谱的方法解决下。

先用sizeof来确定字符串的长度,再用malloc来分配对应的内存给buf指针,再使用这个这个指针即可。

sizeof是预编译的,也不影响运算速度。缺点是,搞多了,heap中有碎片,而且不能忘了释放掉内存占用。
似乎,只有高级一些的语言(C++,Python)才可以不管buf越界这些问题。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-23 14:57:51 | 显示全部楼层
caicaptain2 发表于 2021-11-23 14:56
先用sizeof来确定字符串的长度,再用malloc来分配对应的内存给buf指针,再使用这个这个指针即可。

siz ...

谢谢,这种方法考虑过,不够安全。
回复

使用道具 举报

335

主题

2037

回帖

3047

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3047
发表于 2021-11-23 15:06:45 | 显示全部楼层
eric2013 发表于 2021-11-23 14:57
谢谢,这种方法考虑过,不够安全。

http://c.biancheng.net/c/memory/
这里有个文章解释了安全使用内存分配的一些要求。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-23 15:13:25 | 显示全部楼层
caicaptain2 发表于 2021-11-23 15:06
http://c.biancheng.net/c/memory/
这里有个文章解释了安全使用内存分配的一些要求。

C库函数的,一般我们都是使用几十个字节做缓冲。无论是安全性还是效率,使用malloc之类的函数都不太划算。用这种方案就不如把缓冲做大点,直接考虑最坏执行情况的1.5倍缓冲大小。

比如:sprintf(buf, "buf = %d\r\n",  a); 使用malloc就不太方便,也需要估算大小申请,所以不如直接给个大小。
回复

使用道具 举报

0

主题

59

回帖

59

积分

初级会员

积分
59
发表于 2021-11-23 16:31:47 | 显示全部楼层
如果是字符串再后面人为再加个0,结束字符串。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-23 16:49:23 | 显示全部楼层
zhousun 发表于 2021-11-23 16:31
如果是字符串再后面人为再加个0,结束字符串。

这个解决不了缓冲不足的问题。
回复

使用道具 举报

41

主题

215

回帖

338

积分

高级会员

积分
338
发表于 2021-11-23 18:26:07 | 显示全部楼层
snprintf
回复

使用道具 举报

25

主题

287

回帖

367

积分

高级会员

积分
367
发表于 2021-11-23 20:06:07 | 显示全部楼层
这个问题似乎无法解决,C语言天生就这样
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-24 01:29:18 | 显示全部楼层

不太好使,不灵活。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-24 01:29:35 | 显示全部楼层
爱恋之燕 发表于 2021-11-23 20:06
这个问题似乎无法解决,C语言天生就这样

发现还是加大缓冲直接。
回复

使用道具 举报

41

主题

215

回帖

338

积分

高级会员

积分
338
发表于 2021-11-25 19:52:59 | 显示全部楼层
asprintf函数试下。不过此函数还是分配一个大函数。
linux这种操作系统,在它的底层,准备了好多内存块,用的时候直接给。所以又快又好的代价,就是内存大。
用snprinf安全。
安全第一。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-25 22:37:17 | 显示全部楼层
snakeemail 发表于 2021-11-25 19:52
asprintf函数试下。不过此函数还是分配一个大函数。
linux这种操作系统,在它的底层,准备了好多内存块, ...

不方便,放弃这种方案了。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-11-26 10:20:25 | 显示全部楼层
C语言天生自带的问题,很难处理。
定义一个安全字符串 buf,前2个byte写入长度,从第三个byte开始是内容
然后重写要用到的相关函数,做边界检查。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-27 08:52:51 | 显示全部楼层
hhxb 发表于 2021-11-26 10:20
C语言天生自带的问题,很难处理。
定义一个安全字符串 buf,前2个byte写入长度,从第三个byte开始是内容
...

还别说,这个还真是个好办法
回复

使用道具 举报

0

主题

100

回帖

100

积分

初级会员

积分
100
发表于 2021-11-27 09:34:31 | 显示全部楼层
eric2013 发表于 2021-11-27 08:52
还别说,这个还真是个好办法

请问您认为snprintf这种传入buffer大小参数的方式不方便的具体指哪方面?按我理解18楼的方案只是把大小参数写在buffer里面而已,操作上没太大区别。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
 楼主| 发表于 2021-11-27 09:40:29 | 显示全部楼层
ilcvm 发表于 2021-11-27 09:34
请问您认为snprintf这种传入buffer大小参数的方式不方便的具体指哪方面?按我理解18楼的方案只是把大小参 ...

因为传递进来的字符大小是不定长的。如果显示的内容超过了buf大小,需要截取一段展示。
本质跟snprintf没啥区别,也会截取显示,但更灵活了。
回复

使用道具 举报

0

主题

100

回帖

100

积分

初级会员

积分
100
发表于 2021-11-27 09:53:09 | 显示全部楼层
eric2013 发表于 2021-11-27 09:40
因为传递进来的字符大小是不定长的。如果显示的内容超过了buf大小,需要截取一段展示。
本质跟snprintf ...

对于snprintf来说只需要传入buffer大小,传入字符串大小是不需要知道的,也无法计算最终转化完格式后会用到的大小。

如果要灵活,标准C库本身就提供了很灵活的办法fprintf,通过自己实现的fputc和FILE结构体就可以做边界检查或其他操作(如使用环形FIFO buffer)。
回复

使用道具 举报

9

主题

103

回帖

130

积分

初级会员

积分
130
发表于 2021-11-27 19:03:26 | 显示全部楼层
一般都是定义一个比较大的数组给sprintf函数用。然后随时观察最后几个字节是不是初始值。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-10 14:28 , Processed in 0.364983 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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