lo网卡注册系统卡滞漏洞分析及其解决
lo网卡注册系统卡滞漏洞分析及其解决
问题描述:
向kernel注册lo网卡驱动后,启动kernel后系统卡滞。
Debug过程:
- 初步发现系统停滞在用户层,怀疑是内核切换成用户态时出现问题
- 输出用户态的init程序发现proc_name输出为空,开始怀疑是free before use
- free before use的原因通常为不能正确使用unsafe代码块操控内存导致内存错误。
- 开始检查lo网卡实现代码中有关unsafe的部分
- 检查到问题出现在驱动包裹器上
- 通过输出日志发现代码停滞在lo的NetDerive层中的poll方法,怀疑是内部调用了包裹器内部的驱动的可变引用导致的,这是一个unsafe代码
- 检查但没发现存在内存错误的可能,重新把目光放回poll方法
- 发现系统会定时重复调用poll方法,存在定期调用网卡的poll的机制
- 思考如果重复调用poll方法,为什么会导致系统停滞
- 通过对系统的网络子系统的学习,发现系统如果发现网卡内的rxqueue有未接收的数据包会启用中断来接收,怀疑系统认为lo网卡内一直存在未接受的数据包,导致一直中断接收数据包。
- 认识到系统认为网卡没有数据包的手段是调用网卡内部设备驱动时返回none,所以在receive函数中先检查queue是否为空,如果为空返回none
- 重启系统,发现系统正常启动。
- bug修复完成。
反思:
- 问题出现的第一场所不是导致问题的第一场所!!!因为操作系统中存在大量的中断和调度活动,并不是顺序执行的,输出日志所定位到的地方并不一定是问题导致的地方,要重新分析问题,思考系统反常的原因。
- 输出日志确实是一个非常有力的工具,但是不能依赖他,不能完全靠他定位!
This post is licensed under CC BY 4.0 by the author.