用slub_track调试use after free问题

死机重启问题中,有部分是访问了已释放的内存导致,这就是典型的userafter 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后填充0bb

Freepointer :指向下一个空闲的object

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

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

典型的object内存布局

slub info

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。

分析下述案例:

crash_arm64> musb_qh 0xffffffc0640ebc80 -x
struct musb_qh {
  hep = 0x6b6b6b6b6b6b6b6b,
  dev = 0x6b6b6b6b6b6b6b6b,

这个地址0xffffffc0640ebc80出问题了,下面看是slub分配的,所以可以用slub track分析了。

crash_arm64> kmem 0xffffffc0640ebc80

CACHE            NAME                 OBJSIZE  ALLOCATED     TOTAL  SLABS  SSIZE
ffffffc079007980 kmalloc-256              256       5184      5208    248    16k
  SLAB              MEMORY            NODE  TOTAL  ALLOCATED  FREE
  ffffffbdc1903a00  ffffffc0640e8000     0     21         19     2
  FREE / [ALLOCATED]
  [ffffffc0640ebc00]


      PAGE               PHYSICAL      MAPPING       INDEX CNT FLAGS
ffffffbdc1903ac0         e40eb000                0        1  0 0

struct kmem_cache {
  cpu_slab = 0xffffff8008e6bc30,
  flags = 0x80010d00,

crash_arm64> p kmalloc_caches  -x
kmalloc_caches = $1 =

 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffc079004380, 0xffffffc079007980, 0xffffffc079004680, 0xffffffc079007680, 0xffffffc079004980, 0xffffffc079007380, 0xffffffc079004c80}

struct kmem_cache {
  cpu_slab = 0xffffff8008e6bc30,
  flags = 0x80010d00,                //这个flag 表明当前debug等级信息,
  min_partial = 0x5,
  size = 0x300,
  object_size = 0x100,
  offset = 0x108,
  cpu_partial = 0x0,
  oo = {
    x = 0x20015
  },
  max = {
    x = 0x20015
  },
  min = {
    x = 0x5
  },
  allocflags = 0x4000,
  refcount = 0x1,
  ctor = 0x0,
  inuse = 0x108,
  align = 0x80,
  reserved = 0x0,

  name = 0xffffff8008c8ef4f "kmalloc-256",

/*
 * Flags to pass to kmem_cache_create().
 * The ones marked DEBUG are only valid if CONFIG_DEBUG_SLAB is set.
 */
#define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */
#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */

这里slub track 就是需要SLAB_STORE_USER 这个flag,满足条件。  此slub 肯定包含了alloc和free的track。

分析内存里object的内存布局,找到这个track地址:

ffffffc0640ebbd0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebbe0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebbf0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebc00:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc10:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc20:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc30:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc40:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc50:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc60:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc70:  bbbbbbbbbbbbbbbb bbbbbbbbbbbbbbbb   ................
ffffffc0640ebc80:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebc90:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebca0:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebcb0:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebcc0:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebcd0:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebce0:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebcf0:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd00:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd10:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd20:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd30:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd40:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd50:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd60:  6b6b6b6b6b6b6b6b 6b6b6b6b6b6b6b6b   kkkkkkkkkkkkkkkk
ffffffc0640ebd70:  6b6b6b6b6b6b6b6b a56b6b6b6b6b6b6b   kkkkkkkkkkkkkkk.
ffffffc0640ebd80:  bbbbbbbbbbbbbbbb ffffffc0640eb680   ...........d....                 //used  after free的slub好像一般都有这些信息。
ffffffc0640ebd90:  ffffff80085e3724 ffffff80081cb79c   $7^.............
ffffffc0640ebda0:  ffffff80081cbe6c ffffff80081cbf58   l.......X.......
ffffffc0640ebdb0:  ffffff80081cc27c ffffff80085e3724   |.......$7^.....
ffffffc0640ebdc0:  ffffff800859d374 ffffff800859e7c4   t.Y.......Y.....
ffffffc0640ebdd0:  ffffff80087a37f8 ffffff80087ac584   .7z.......z.....
ffffffc0640ebde0:  ffffff80087ae554 ffffff80087932cc   T.z......2y.....
ffffffc0640ebdf0:  ffffff8008792d3c ffffff8008795bd8   <-y......[y.....
ffffffc0640ebe00:  ffffff8008796778 ffffff8008797200   xgy......ry.....
ffffffc0640ebe10:  ffffff800822ee1c 000003a200000003   ..".............
ffffffc0640ebe20:  000000010028dde4 ffffff80085e3250   ..(.....P2^.....
ffffffc0640ebe30:  ffffff80081cd008 ffffff80081cd18c   ................
ffffffc0640ebe40:  ffffff80081cdec0 ffffff80085e3250   ........P2^.....
ffffffc0640ebe50:  ffffff800859d530 ffffff800859e27c   0.Y.....|.Y.....
ffffffc0640ebe60:  ffffff80087a29e4 ffffff80087a39f8   .)z......9z.....
ffffffc0640ebe70:  ffffff80087ad5d0 ffffff80087ad730   ..z.....0.z.....
ffffffc0640ebe80:  ffffff8008792fb8 ffffff8008792d3c   ./y.....<-y.....
ffffffc0640ebe90:  ffffff8008792dc8 ffffff8008792ec4   .-y.......y.....
ffffffc0640ebea0:  ffffff8008794d70 ffffff8008794dbc   pMy......My.....
ffffffc0640ebeb0:  00000dfc00000003 000000010028df1a   ..........(.....            //大致一看cpu和pid就是他了
ffffffc0640ebec0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebed0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebee0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebef0:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf00:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf10:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf20:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf30:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf40:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf50:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf60:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf70:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ
ffffffc0640ebf80:  5a5a5a5a5a5a5a5a 5a5a5a5a5a5a5a5a   ZZZZZZZZZZZZZZZZ

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

crash_arm64> track -ox
struct track {
   [0x0] unsigned long addr;
   [0x8] unsigned long addrs[16];
  [0x88] int cpu;
  [0x8c] int pid;
  [0x90] unsigned long when;
}
SIZE: 0x98

crash_arm64> track ffffffc0640ebe28  -x
struct track {
  addr = 0xffffff80085e3250,
  addrs = {0xffffff80081cd008, 0xffffff80081cd18c, 0xffffff80081cdec0, 0xffffff80085e3250, 0xffffff800859d530, 0xffffff800859e27c, 0xffffff80087a29e4, 0xffffff80087a39f8, 0xffffff80087ad5d0, 0xffffff80087ad730, 0xffffff8008792fb8, 0xffffff8008792d3c, 0xffffff8008792dc8, 0xffffff8008792ec4, 0xffffff8008794d70, 0xffffff8008794dbc},
  cpu = 0x3,
  pid = 0xdfc,
  when = 0x10028df1a
}

dis这些地址就知道是谁释放的了。也可以看alloc的调用栈。
————————————————
版权声明:本文为CSDN博主「chenpuo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenpuo/article/details/80885789

原文地址:https://www.cnblogs.com/smilingsusu/p/14479938.html