Linux内核Section Mismatch详解

by falcon [email protected] of TinyLab.org

2014/01/22

Section Mismatch简介

Section Mismatch是非常严重的Bug,可能会导致无法预测的内存访问问题,建议谨慎对待,如果添加的驱动中有类似Warning,可能需要密切关注并解决掉。

下面就该问题的检测、原因、解决思路以及最新前沿进行分析。

Section Mismatch的检测

CONFIG_DEBUG_SECTION_MISMATCH=y

打开上述选项,内核就会调用modpost检测类似问题。

Section Mismatch的原因

Linux为了减少不必要的内存消耗,对于一些仅仅在内核初始化时使用的资源(包括函数和变量等),会放在init sections中,这些init sections会在内核初始化完成以后被内核Free掉。除此之外,考虑到不同模块或者子系统的差异,它们的代码和数据也会放在各自的Section中,交叉的引用也可能出现潜在的问题。

如果一个Section引用了另外一个Section中的变量,就会出现Section Mismatch警告。如果是一个运行时函数引用了一个Init Section段中的函数,那么问题就出现了。

当Linux内核启动完成后,Init Section占用的内存已经被Free掉,如果这部分内存被其他的设备申请,写进了不可预知的内容,那么系统就会存在不可预知的风险,也许有些时候会很幸运,这部分内存从来都没有被其他设备引用,所以,即使编译时看到了Warning,系统也没有崩溃,但是炸弹放在枕头边,很危险,早点搬走为好。

Section Mismatch的解决

有几种情况:

  • 如果运行时函数引用了Init Section中的函数或者变量

如果该运行时函数是必须要在运行时用到的,不能放到Init Section中,那么就把Init Section中的函数的__init*标记去掉,否则给前者加上相应的Init声明。

相关的init标记请参考:include/linux/init.h

  • 如果不同的Section之间存在交叉引用,这个交叉引用是安全的,则用__ref标记让Section Mismatch Detector(modpost)忽略相关检查

比如在cpu hotplug中,__cpuinit不会放在Init section中,在运行时访问是安全的,如果有一个外部函数(无__cpuinit标记)访问了用__cpuinit标记的函数,这个时候就存在交叉引用。因为这种访问是安全的,所以可以让内核忽略对它的检测,用__ref标记该函数即可。

Section Mismatch的近况

在最新的ARM内核中,引入了一个智能检测,该检测是针对Free掉的内存被运行时函数访问的情况,前面的分析提到类似的情况会导致无法预测的风险,而该智能检测则会明确地报告出具体的问题。

该检测的原理是把所有Init Section的内存区域在内核初始化时把这些内存区域初始化为0xe7fddef0 (an undefined instruction (ARM) or a branch to an undefined instruction (Thumb)),如果运行时函数非法访问到了这些区域,会触发一个undef instruction的异常并打印相应的回调,从而辅助开发人员更快地解决相关问题。

当然,这并不意味着我们不需要解决编译时的Warning,把问题Delay到运行时解决是更耗费精力的,应该在编码或者编译等早期开发过程中就解决掉,这样会提高开发效率,这个思路对其他的问题同样适用。

这部分的代码请参考:arch/arm/mm/init.c: poison_init_mem()

时间: 2024-08-03 14:00:33

Linux内核Section Mismatch详解的相关文章

Linux内核ROP姿势详解(二)

/* 很棒的文章,在freebuf上发现了这篇文章上部分的翻译,但作者貌似弃坑了,顺手把下半部分也翻译了,原文见文尾链接 --by JDchen */ 介绍 在文章第一部分,我们演示了如何找到有用的ROP gadget并为我们的系统(3.13.0-32 kernel –Ubuntu 12.04.5 LTS)建立了一个提权ROP链的模型.我们同时也开发了一个有漏洞的内核驱动来允许实现执行任意代码.在这一部分,我们将会使用这个内核模块来开发一个具有实践意义的ROP链:提权,修复系统,纯净退出到用户空

Yahoo Web 应用性能及linux内核优化黄金法则详解

Web 应用性能优化黄金法则:先优化前端程序(front-end) 的性能,因为这是80% 或以上的最终用户响应时间的花费所在. 法则1. 减少HTTP 请求次数80%的最终用户响应时间花在前端程序上,而其大部分时间则花在各种页面元素,如图像.样式表.脚本和Flash等,的下载上.减少页面元素将会减少HTTP请求次数.这是快速显示页面的关键所在.一种减少页面元素个数的方法是简化页面设计.但是否存在其他方式,能做到既有丰富内容,又能获得快速响应时间呢?以下是这样一些技术:Image maps 组合

linux 内核 RCU机制详解

RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用.RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作.这样在同一时间可以有多个线程同时读取该链表,并且允许一个线程对链表进行修改(修改的时候,需要加锁).RCU适用于需要频繁的读取数据,而相应修改数据并不多的情景,例如在文件系统中,经常需要查找定位目录,而对目录的修改相对来说并不多,这就是RCU发挥作用的最佳场景.

Linux基础学习--1:linux内核与发行详解

工欲善其事,必先利其器,linux从技术上面来说是一个内核,这个内核可以提供的功能有: 1:硬件抽象文件 2:磁盘及文件系统控制 3:多任务处理 内核是一个用来和硬件打交道并为用户程序提供一个有限服务集的低级支撑软件,我们完全可以把内核理解成与硬件进行交互的操作过程的封装,实际上一个内核不能算是一整套完整的操作系统,一套完整基于linux内核的操作系统才能叫做linux操作系统. linux内核的功能组成: 进程管理(process management).定时器(timer).中断管理(int

嵌入式Linux内核I2C子系统详解

1.1 I2C总线知识 1.1.1  I2C总线物理拓扑结构     I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成.通信原理是通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递.在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平. 1.1.2  I2C总线特征    I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址(可以从I2C器件的数据手册得知),主

《Linux设备驱动开发详解:基于最新的Linux 4.0内核》china-pub预售

<Linux设备驱动开发详解:基于最新的Linux 4.0内核>china-pub今日上线进入预售阶段: http://product.china-pub.com/4733972 推荐序一 技术日新月异,产业斗转星移,滚滚红尘,消逝的事物太多,新事物的诞生也更迅猛.众多新生事物如灿烂烟花,转瞬即逝.当我们仰望星空时,在浩如烟海的专业名词中寻找,赫然发现,Linux的生命力之旺盛顽强,斗志之昂扬雄壮,令人称奇.它正以摧枯拉朽之势迅速占领包括服务器.云计算.消费电子.工业控制.仪器仪表.导航娱乐等

《Linux设备驱动开发详解:基于最新的Linux 4.0内核》china-pub 预售

<Linux设备驱动开发详解:基于最新的Linux 4.0内核>china-pub今日上线进入预售阶段: http://product.china-pub.com/4733972 推荐序一 技术日新月异,产业斗转星移,滚滚红尘,消逝的事物太多,新事物的诞生也更迅猛.众多新生事物如灿烂烟花,转瞬即逝.当我们仰望星空时,在浩如烟海的专业名词中寻找,赫然发现,Linux的生命力之旺盛顽强,斗志之昂扬雄壮,令人称奇.它正以摧枯拉朽之势迅速占领包括服务器.云计算.消费电子.工业控制.仪器仪表.导航娱乐等

《Linux设备驱动开发详解(基于最新4.0内核)》前言

Linux从未停歇脚步.Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,仍然在没日没夜的合并补丁,升级内核.做技术,从来没有终南捷径,拼的就是坐冷板凳的傻劲. 这是一个连阅读都被碎片化的时代,在这样一个时代,人们趋向于激进.浮躁.内心的不安宁使我们极难静下心来研究什么.我见过许许多多的Linux工程师,他们的简历书写着"精通"Linux内核,有多年的工作经验,而他们的"精通"却只是把某个寄存器从0改成1,从1改成0的不

(转)Linux下PS命令详解

(转)Linux下PS命令详解 整理自:http://blog.chinaunix.net/space.php?uid=20564848&do=blog&id=74654 要对系统中进程进行监测控制,查看状态,内存,CPU的使用情况,使用命令:/bin/ps (1) ps :是显示瞬间进程的状态,并不动态连续: (2) top:如果想对进程运行时间监控,应该用 top 命令: (3) kill 用于杀死进程或者给进程发送信号: (4) 查看文章最后的man手册,可以查看ps的每项输出的含义