154、【Nuttx】【OS】【启动】栈溢出检测(一)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Nuttx】【OS】【启动】回归!继续 Nuttx 探索(Stack Monitor)

在 Gitee 上新建了个仓库,用来同步 Github Nuttx 源仓库,然后分析了栈溢出检测中的 Stack Monitor 原理,并分析了其中可能会漏掉的栈溢出场景,最后准备开始分析 Per function Call

栈溢出检测

还是 Per function Call 这里

除了保留一个 CPU 寄存器(R10),编译器(GCC)还可以通过 -finstrument-functions 选项,在每个函数的入口和出口自动插入检查代码

  • 入口:插入 __cyg_profile_func_enter
  • 出口:插入 __cyg_profile_func_exit

OK,然后是入口的检查逻辑,在每次函数被调用时,先执行检查如下的伪代码

c 复制代码
if ( (current SP - 安全边距) < rBS ) {
    触发 Hard Fault(硬件故障)
}

这里的安全边距 = 64 字节 + (如果启用 FPU)136 字节 = 最多约 200 字节,其检查过程大致如下

  • 栈底存入 R10 寄存器

  • 发生函数调用时,对 SP 指针进行运算,并和 R10 寄存器进行比较

  • 有两种可能,一种是(SP - 安全距离)< R10 寄存器,意味着 SP 指针的使用已经不在栈空间之内,此时检查函数 __cyg_profile_func_enter 需要上报 Hard Fault 硬件故障通知栈溢出

  • 另一种可能就是 (SP - 安全距离)> R10 寄存器,这时候 SP 指针就还算使用安全,有足够的安全余量

OK,接下来这段话解释了为什么每次函数调用进行栈检查时,要从当前栈指针 SP 减去一个安全距离,再去和栈底 rBS 比较

这里的核心内容是,即使任务栈看起来还没用完,也要预留至少 200 字节的应急空间,以防中断突然发生导致栈溢出

这里需要分成两种系统配置场景来考虑:没有独立的 ISR 中断栈,和有独立的 ISR 中断栈

  • 没有独立中断栈时 :在这种配置下,当中断发生时,CPU 会直接把上下文(比如寄存器信息等)压入当前任务的栈中 ,这里需要保存的内容包括基础寄存器(R0-R3R12LRPCxPSR),大概 32 字节,如果启用了浮点单元 FPU,则还要额外保存 16 个浮点寄存器(S0-S15),大概 64 字节,然后可能还有对齐,嵌套中断等额外开销,可能总计需要 100 ~ 200 字节(这里取了个整数 200 字节)

    所以,如果此时任务栈已经用到了离栈底只剩 50 字节,这时候来个中断,就会直接溢出并破坏内存

    这时候,在检查栈是否安全时,得提前扣除这 200 字节,也就是说,只要(SP - 200)< rBS,就算危险!

  • 有独立的中断栈时 :在这种情况下,中断发生时,CPU 就会切换到专用的中断栈,不再使用任务栈,但切换过程本身还是会需要一点任务栈空间 ,比如保存部分寄存器,跳转到中断处理程序前的准备代码,这部分内容通常只需要几十字节,剩下的 100+ 字节就是额外的安全余量,可以应对如编译器优化导致的栈使用波动,未来代码修改增加局部变量,测量误差或对齐填充等

    所以即使有独立中断栈,这里也建议预留 200 字节,因为多一点安全余量总比溢出强

最后总结下:

  • 安全边距 = 64 + 136(启用 FPU)= 200 字节
  • 没有独立中断栈:CPU 把上下文(包括通用寄存器 + FPU 寄存器)压入当前任务栈,需要预留空间
  • 有独立中断栈:切换到中断栈时,仍需要少量栈空间做跳转,其余作为安全余量

OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Nuttx】【OS】【启动】栈溢出检测(二)

相关推荐
HIT_Weston4 天前
153、【Nuttx】【OS】【启动】回归!继续 Nuttx 探索(Stack Monitor)
os·nuttx·栈监控
啊阿狸不会拉杆24 天前
《计算机操作系统》第十章 - 多处理机操作系统
c++·算法·计算机组成原理·os·计算机操作系统
啊阿狸不会拉杆24 天前
《计算机操作系统》 第十一章 -多媒体操作系统
开发语言·c++·人工智能·os·计算机操作系统
啊阿狸不会拉杆24 天前
《计算机操作系统》 - 第九章 操作系统接口
人工智能·算法·计算机组成原理·os·计算机操作系统
啊阿狸不会拉杆25 天前
《计算机操作系统》第七章 - 文件管理
开发语言·c++·算法·计算机组成原理·os·计算机操作系统
啊阿狸不会拉杆1 个月前
《计算机操作系统》第六章-输入输出系统
java·开发语言·c++·人工智能·嵌入式硬件·os·计算机操作系统
啊阿狸不会拉杆1 个月前
《计算机操作系统》第四章-存储器管理
人工智能·算法·计算机组成原理·os·计算机操作系统
LiRuiJie1 个月前
从OS层面深入剖析JVM如何实现多线程与同步互斥
java·jvm·os·底层
a不是橘子1 个月前
03在Ubuntu中验证PV操作
笔记·ubuntu·操作系统·虚拟机·os·pv操作