死机重启问题中,有部分是访问了已释放的内存导致,这就是典型的use after free问题.

打开CONFIG_SLUB_DEBUG和CONFIG_SLUB_DEBUG_ON宏开关后,系统就可以监测内存的释放与分配调用栈.

1. slab 内存布局

slub的内存管理原理这里就不在详述.直接给出slabobject对象的内存布局,object内存包含下面四个部分:

object_size +Redzone + Freepointer +2*track+pading

object_size :待分配内存的大小,alloc时为0x5a,free后为0x6b,但是最后一个Byte为0xa5表示object的结束,之后的数据都为metadata.

Redzone : 标记区.alloc填充0xcc,free后填充0xbb

Freepointer :指向下一个空闲的object

2个structtrack结构,用于跟踪内存的分配与释放栈

pading :填充区,为了内存对齐,填充为0x5a

下表为典型的object内存布局

2. 相关变量

kmem_cache->inuse= object_size + Redzone

kmem_cache->offset= inuse or =0

kmem_cache->size= object_size +Redzone+Freepointer+2*track+pading

3. 查找track信息

当系统出现KE时,用gdb调试打印内存,发现访问的内存全变成了0x6b,则可以怀疑是userafter free。

这里以skb为例,假如skb->protocol开始的内存全变成0x6b,获取protocol的地址

(gdb) p&(skb->protocol)

$6 = (__be16 *)0xffffffc02a3020c0

输出从0xffffffc02a3020c0地址开始的512Byte内容

(gdb) x /512xb0xffffffc02a3020c0

0xffffffc02a3020c0: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a3020c8: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a3020d0: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a3020d8: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a3020e0: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0xa5

0xffffffc02a3020e8: 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb

0xffffffc02a3020f0: 0x80 0x21 0x30 0x2a 0xc0 0xff 0xff 0xff

0xffffffc02a3020f8: 0x90 0xdb 0xa8 0x00 0xc0 0xff 0xff 0xff

0xffffffc02a302100: 0x9c 0x96 0x1e 0x04 0x58 0x9d 0x1e 0x04

0xffffffc02a302108: 0x3c 0xb0 0x1e 0x04 0x8c 0xdb 0xa8 0x04

0xffffffc02a302110: 0x28 0x0f 0xba 0x04 0x8c 0x36 0xba 0x04

0xffffffc02a302118: 0xb8 0x37 0xba 0x04 0x6c 0x16 0xba 0x04

0xffffffc02a302120: 0x00 0x00 0x00 0x00 0x11 0x55 0x00 0x00

0xffffffc02a302128: 0xc4 0x29 0x4e 0x01 0x01 0x00 0x00 0x00

0xffffffc02a302130:0x04 0xce 0xa8 0x00 0xc0 0xff 0xff 0xff

0xffffffc02a302138: 0x14 0xa0 0x1e 0x04 0xb8 0xa3 0x1e 0x04

0xffffffc02a302140: 0x6c 0xb8 0x1e 0x04 0x00 0xce 0xa8 0x04

0xffffffc02a302148: 0xb4 0xe3 0xa8 0x04 0x38 0x53 0xa9 0x04

0xffffffc02a302150: 0xb0 0x96 0xb8 0x04 0x3c 0x33 0xa8 0x04

0xffffffc02a302158: 0x03 0x00 0x00 0x00 0x29 0x01 0x00 0x00

0xffffffc02a302160: 0xc2 0x29 0x4e 0x01 0x01 0x00 0x00 0x00

0xffffffc02a302168: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a

0xffffffc02a302170: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a

0xffffffc02a302178: 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a

0xffffffc02a302180: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a302188: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a302190: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

…...............................................................省去部分内存..................................................................

0xffffffc02a302258: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b

0xffffffc02a302260: 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0x6b 0xa5

0xffffffc02a302268: 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb

0xffffffc02a302270: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

0xffffffc02a302278: 0x90 0xdb 0xa8 0x00 0xc0 0xff 0xff 0xff

0xffffffc02a302280: 0x9c 0x96 0x1e 0x04 0x58 0x9d 0x1e 0x04

0xffffffc02a302288: 0x3c 0xb0 0x1e 0x04 0x8c 0xdb 0xa8 0x04

0xffffffc02a302290: 0xcc 0x43 0xa9 0x04 0xcc 0xa3 0xa8 0x04

0xffffffc02a302298: 0x68 0x9e 0xb8 0x04 0x44 0x32 0xa8 0x04

0xffffffc02a3022a0: 0x03 0x00 0x00 0x00 0xeb 0x02 0x00 0x00

0xffffffc02a3022a8: 0xc2 0x29 0x4e 0x01 0x01 0x00 0x00 0x00

0xffffffc02a3022b0: 0x04 0xce 0xa8 0x00 0xc0 0xff 0xff 0xff

0xffffffc02a3022b8: 0x14 0xa0 0x1e 0x04 0xb8 0xa3 0x1e 0x04

从内存中查找关键字0xa5,0xbb,再参考slabobject的内存布局,很容易找到alloctrack和freetrack的地址,再用gdb打印出内存

free:0xffffffc02a302130

p /x *((struct track*)0xffffffc02a302130)

$13 = {addr =0xffffffc000a8ce04, addrs = {0x41ea014, 0x41ea3b8, 0x41eb86c,0x4a8ce00, 0x4a8e3b4, 0x4a95338, 0x4b896b0, 0x4a8333c}, cpu = 0x3,pid = 0x129,

when =0x1014e29c2}

同理,也可以打印出alloctrack的内存。

4. 转换track信息

track 的定义

struct track {

unsigned longaddr; /* Called from address */

#ifdefCONFIG_STACKTRACE

u32addrs[TRACK_ADDRS_COUNT]; //函数调用栈信息

/* we store theoffset after MODULES_VADDR for kernel module and kernel text address */

#endif

int cpu; /* Wasrunning on cpu */

int pid; /* Pidcontext */

unsigned longwhen; /* When did the operation occur */

};

为了节省空间,存储地址时,去掉了内核code起始地址,也就是需要addrs的值加上MODULES_VADDR,(MODULES_VADDR+t->addrs[i]),在这里MODULES_VADDR=0xffffffbffc000000,最后通过addr2line打印出free的调用栈为:

kernel-3.18/net/socket.c:791

kernel-3.18/net/unix/af_unix.c:1914

kernel-3.18/net/core/datagram.c:243

/kernel-3.18/net/core/skbuff.c:630

kernel-3.18/net/core/skbuff.c:561

kernel-3.18/mm/slub.c:2923

另外,需要说明MODULES_VADDR的值,每个平台都可能不一样,所有要根据实际情况取值.

用slub track调试use after free问题相关推荐

  1. Linux中使用Systemtap调试SLUB

    <Linux指令:SystemTap内核跟踪和探测工具> 之前的文章曾利用systemtap的"watchpoint"功能来监测变量数值的变化,但systemtap在内 ...

  2. 谷歌浏览器bug调试快捷键_Bug压榨初学者指南:如何使用调试器和其他工具查找和修复Bug

    谷歌浏览器bug调试快捷键 As web developers, it often feels like we spend more time fixing bugs and trying to so ...

  3. (转)Linux SLUB 分配器详解

    原文网址:https://www.ibm.com/developerworks/cn/linux/l-cn-slub/ 多年以来,Linux 内核使用一种称为 SLAB 的内核对象缓冲区分配器.但是, ...

  4. linux slub分配器,Vi Linux内存 之 Slub分配器(六)

    再来看内置式对象,如下图所示.指针位于对象的头部,与对象共用存储空间.这是因为对象被分配出去之前,其存储空间是空闲的可用状态,可用于存放空闲对象指针.对象被分配出去后,也不再需要这个指针了,可以被对象 ...

  5. linux 内核调试信息在哪里,Linux kernel debug技巧----开启DEBUG选项

    Linux kernel debug技巧----开启DEBUG选项 作者:wowo 发布于:2016-11-1 19:39 分类:Linux应用技巧 kernel的source code中有很多使用p ...

  6. 如何超越console.log并充分利用浏览器的调试控制台

    by Gilad Dayagi 通过吉拉德·达亚吉 The console object is a very useful feature of browsers that has been arou ...

  7. javascript调试_如何提高JavaScript调试技能

    javascript调试 Almost all software developers who have written even a few lines of code for the Web ha ...

  8. RPi 2B UART作为调试口或者普通串口

    /*************************************************************************************** RPi 2B UART ...

  9. 写了一个将VxWorks的shell打印输出到指定内存中的接口,可广泛用于CLI下的调试函数显示以及故障自动捕获等功能,稍作修改可以适合其它嵌入式OS...

    本代码在Tornado2.0的Simu下调试通过,原理上与CPU架构无关,应该都适用. 如果引用的话,请告诉我,或者评论一句[页面最下方],不要一声不吭 /* usrAppInit.c - stub ...

  10. 物理机_双机调试_资料

    1.http://www.cnblogs.com/Sonic2007/category/127341.html 1.1.Windbg内核调试之一_ Vista Boot Config设置 - Da V ...

最新文章

  1. openstack nova-compute 组件无法启动
  2. hdu 5037 Frog 贪心 dp
  3. 兴义智力象机器人_兴义向阳路小学在第十八届全国青少年机器人竞赛贵州区选拔赛夺冠...
  4. LEGO EV3 通信开发者套件
  5. JavaScript基础知识(Date 的方法)
  6. Ubuntu Vi 编辑器 命令(转)
  7. 数据清洗工具OpenRefine
  8. TC SRM 665 DIV2 A LuckyXor 暴力
  9. winrar加密压缩
  10. 《软件开发的形式化方法-古天龙》笔记(1)
  11. ps怎么缩放图层大小_PS怎么快速修改图层大小|Adobe Photoshop CS6图层大小尺寸调整--系统之家...
  12. 深富策略:险资密集调研 周期股板块能否崛起?
  13. eclipse解决中文乱码
  14. swift网络请求封装(Moya)
  15. day03 数据预处理
  16. 基带丢失、IMEI丢失、手机无信号--高通通用解决办法
  17. c语言编写万年历课程设计,用C语言编写万年历 C课程设计.pdf
  18. 【Java8 环境安装】Java1.8JDK环境安装jdk-8u361-windows-x64
  19. ORA-00257: archiver error. Connect internal only, until freed 的解决方法
  20. Python 奇淫技巧,助你更好的摸鱼

热门文章

  1. 基于Android P,自定义Android开机动画的方法
  2. 杭电计算机组成原理实践课 实验2 一位全加器构成的四位全加器
  3. 互联网广告类型的分析--弹出式广告【3】
  4. CEO的行为风格会影响公司业绩吗?
  5. Ubuntu18.04(Gnome桌面)主题美化,Mac私人定制
  6. SD卡、TF卡坏道及容量检测
  7. android imagebutton的点击事件,Android 点击ImageButton时有“按下”的效果的实现
  8. 全球最大同性交友网站 GitHub 10 岁了!
  9. 关于body.clientHeight,body.clientWidht获取的不是可视高度的问题
  10. latex如何取消自动编号_latex 取消自动编号