【双语视界】Linux信号机制:我花了两年才搞懂的核心原理(附ARM64内核源码解析)
欢迎点赞、投币、收藏一键三连,或点个关注支持我~
1. 信号触发与中断劫持
硬件中断机制:外部事件(如键盘输入)触发CPU跳转至内核中断处理程序,自动保存用户态程序计数器(PC)至elr_el1寄存器
寄存器保存:内核第一时间将用户态全部寄存器(X0-X30)存入内核栈的pt_regs结构体
2. 信号派发流程
信号注册:用户程序通过signal()系统调用注册信号处理函数(如SIGUSR1)
信号发送:其他进程通过kill()系统调用发送信号,内核标记目标进程的signal pending状态
延迟执行:信号处理函数仅在目标进程再次进入内核时(通过系统调用/中断)被触发
3. 上下文篡改与恢复
PC替换:内核在返回用户态前,将pt_regs->pc修改为信号处理函数地址
用户栈魔法:
原始寄存器副本存入用户栈的sigframe结构
信号处理函数返回时通过SIGRETURN系统调用触发内核恢复原始上下文
4. ARM64内核代码实探
中断入口:vbar_el1寄存器指向中断向量表(entry.s),通过stp指令链式保存寄存器
信号派发点:do_notify_resume()函数检测signal pending标志,调用handle_signal()篡改PC
蹦床机制:内核映射rt_sigreturn代码到用户空间,通过svc指令触发上下文恢复
5. 安全隐患与实战案例
内核栈隔离:用户栈(SP_EL0)与内核栈(SP_EL1)物理隔离,防止数据泄露
编译器陷阱:局部变量若存放于用户栈顶之上,可能被信号处理覆盖(需-fstack-check编译选项)
感谢大家观看!若内容对你有启发,欢迎点赞、投币、收藏一键三连,或点个关注支持我~
立即观看