- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
嵌入式系统内存破坏问题定位方法
Linux是当今应用最为广泛的服务器及嵌入式设备操作系统。作为一款开源通用操作系统,Linux具备多平台兼容性、多线程支持、多核支持、虚拟内存管理、良好的文件系统支持、丰富的硬件外设支持等特性。在消费级和企业级嵌入式设备中,Linux都扮演者重要的角色。在嵌入式系统开发中,通常涉及到Linux用户态的应用程序开发,以及内核态的设备驱动程序开发。如无线接入点设备,为了拥有网络通信能力,需要开发和适配无线网卡的内核驱动,同时又需要开发面向用户的Linux用户态应用。在内核驱动程序的开发过程中,自研或移植代码可能出现不规范的内存操作,出现内存越界访问,内存释放后重用等行为。由于内核内存缺乏保护机制,所有模块共用一个地址空间,因此上述的不规范操作通常会导致系统的数据被破坏、改写,引发系统崩溃。当前Linux内核支持一些内存问题的定位和调试手段,但对于复杂嵌入式系统中的改写问题,存在一定的限制。本文研究了当前的调试方法,并提出一种针对内核模块内内存监控和调试的改进方法,对于复杂内存改写问题,具有很好的改进作用。
1研究现状
当前应用在嵌入式Linux系统内核态的常用内存越界、改写的定位手段有以下5种(为了简化描述,本文限定在ARM32平台上)。
1.1Oops信息分析
内存改写通常会触发系统异常、崩溃。通过Linux的Oops调试信息可以分析导致崩溃的直接原因。但对于改写类问题,Oops调试信息中的堆栈和寄存器都不是源自第一现场,大部分情况是改写后的内存在下一次被使用时才会触发异常打印调试信息,因此这种方法分析出改写源头的成功率很低。
1.2DEBUG_PAGEALLOC
Linux的基本内存单元称为页(page),页的管理系统采用BuddyMemoryAllocation的算法,降低了碎片页产生的概率。内核中直接对于页的申请一般是针对大块的连续物理内存的申请,如Slab的内存池或网络设备收发的Buffer区域等。对于页的访问,BuddyAllocator提供了对于空闲页的监控功能。该调试功能会在内存释放回系统时修改对应内存的页表属性,将该区域置为不可访问。这样在有异常访问到这段空闲内存的时候就会触发MMU异常,抓取第一现场。ARM平台在Kernel4.6版本提供了对该功能的完整支持。此外,该功能有2个限制:①使能该功能会导致所有内存页按照4kB的粒度进行页表映射,以确保每个内存页的访问属性可以精细控制,这在一定程度上增加了TLB缺页交换的开销;②擅长空闲内存区域的监控和问题定位,对于模块内申请的内存区域不适用。
1.3SLAB_DEBUG/SLUB_DEBUG
SLAB/SLUB是构建于页管理系统之上的另一层内存管理系统,通常用于小块的物理内存的申请。SLUB是SLAB更新的一代的实现方式,优点是性能更好、扩展性更强,简化的数据结构使得管理的开销更小。SLUB和SLAB通过申请大块的物理页内存,构建用于申请不同大小内存块的内存池,提高了内存申请的效率和空间利用率。同时,SLUB也提供了丰富的调试支持。通过SLUB_DEBUG宏,可以在SLUB的关键数据结构中增加Redzone和Poisoning操作,用于定位区域内的越界改写问题以及UAF(use-after-free)问题,并能在监测到问题时提供消息的错误提示。但是这种调试方式也有限制:①不能用于监测越界读取的异常,只能监测越界改写;②只能在内存申请/释放的动作时对特定的内存区块进行监测,难以发现改写的第一现场,如果改写的内容不具备足够的规律,很难和特定的模块联系起来。
1.4Kmemcheck
可以用于监测UAF类型的错误,以及对未初始化内存的读操作。Kmemcheck能够准确定位到这些异常操作的源头,但是也有很大的使用限制。由于其实现的原理是在每次内存访问时产生pagefault异常,在异常处理中监测当前的访问是否合法,会带来巨大的处理开销;同时为了记录内存状态,会增加一倍的内存消耗。因此对于嵌入式设备来说,该手段可操作性差,一方面设备的计算能力有限,正常处理被严重拖慢,会影响系统的行为和问题的复现;另一方面大部分嵌入式系统没有那么充裕的空闲内存。
1.5KASAN
KASAN(KernelAddressSANitizer)比上述几种调试方式出现的更晚。它利用了GCC编译器的特殊调试功能,可以在每次内存访问前插入检查程序。它提供了相对快速和全面的内存异常访问行为的调试手段。相比Kmemcheck,KASAN优势有:可以全面地对堆栈或全局变量的溢出、UAF、User-memory-access问题进行监控;运行速度比Kmemleak快,Kmemleak的开销为10倍,KASAN仅为1.5倍。但是KASAN也有限制:①内核版本(K
文档评论(0)