kernel panic 分析(NULL pointer dereference)

It is another typical kernel panic due to invalid address.

Panic log:

[   20.896935] c3 554 (netd) Unable to handle kernel NULL pointer dereference at virtual address 00000012

[   20.906200] c3 554 (netd) pgd = ffffffc02f746000

[   20.910793] c3 554 (netd) SEH:seh_api_ioctl_handler 7

[   20.910793] 

[   20.917357] c3 554 (netd) [00000012] *pgd=0000000000000000

[   20.922798] c3 554 (netd) Internal error: Oops: 96000005 [#1] PREEMPT SMP

[   20.929523] Modules linked in: audiostub cidatattydev gs_modem ccinetdev cci_datastub citty iml_module seh cploaddev msocketk tzdd galcore(O)

[   20.942183] c3 554 (netd) CPU: 3 PID: 554 Comm: netd Tainted: G           O 3.10.33 #1

[   20.950030] c3 554 (netd) task: ffffffc02e0a0000 ti: ffffffc029b0c000 task.ti: ffffffc029b0c000

[   20.958659] c3 554 (netd) PC is at __kill_pgrp_info+0x1c/0x84

[   20.964360] c3 554 (netd) LR is at kill_orphaned_pgrp+0xa4/0xb8

[   20.970232] c3 554 (netd) pc : [<ffffffc0000b39f0>] lr : [<ffffffc0000a3d10>] pstate: 80000145

[   20.978769] c3 554 (netd) sp : ffffffc029b0fc40

[   20.983257] R29: ffffffc029b0fc40 R28: ffffffc02e0a0200

[   20.988537] R27: 0000000000000001 R26: 00000000fffffff6

[   20.993819] R25: ffffffc00072f000 R24: ffffffc029b0fda8

[   20.999100] R23: ffffffc029b0c000 R22: 0000000000000001

[   21.004381] R21: 0000000000000001 R20: ffffffc029b0fd80

[   21.009663] R19: ffffffc02356eb40 R18: 0000000000000000

[   21.014935] R17: 0000000000000000 R16: ffffffc000102988

[   21.020216] R15: 0000000000000000 R14: 00000000f755fdb7

[   21.025497] R13: 00000000f6f0bb78 R12: 0000000000000000

[   21.030778] R11: 00000000f6f0bb9c R10: 0000000000000fff

[   21.036060] R9 : 00000001ffffffff R8 : 0000000033ffff7f

[   21.041342] R7 : 00000000000185ad R6 : ffffffc02f14614c

[   21.046623] R5 : 0000000000000000 R4 : 0000000000000000

[   21.051903] R3 : ffffffc02f146140 R2 : 0000000000000002

[   21.057185] R1 : 0000000000000001 R0 : 0000000000000001

PC is at __kill_pgrp_info, disassemble it.

 

1333int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)

1334{

1335    struct task_struct *p = NULL;

1336    int retval, success;

1337

1338    success = 0;

1339    retval = -ESRCH;

1340    do_each_pid_task(pgrp, PIDTYPE_PGID, p) {

1341           int err = group_send_sig_info(sig, info, p);

1342           success |= !err;

1343           retval = err;

1344    } while_each_pid_task(pgrp, PIDTYPE_PGID, p);

1345    return success ? 0 : retval;

1346}

 

crash> dis __kill_pgrp_info

0xffffffc0000b39d4 <__kill_pgrp_info>:  stp     x29, x30, [sp,#-48]!

0xffffffc0000b39d8 <__kill_pgrp_info+4>:        mov     x29, sp

0xffffffc0000b39dc <__kill_pgrp_info+8>:        stp     x21, x22, [sp,#32]

0xffffffc0000b39e0 <__kill_pgrp_info+12>:       stp     x19, x20, [sp,#16]

0xffffffc0000b39e4 <__kill_pgrp_info+16>:       mov     w21, w0

0xffffffc0000b39e8 <__kill_pgrp_info+20>:       mov     x22, x1

0xffffffc0000b39ec <__kill_pgrp_info+24>:       cbz     x2, 0xffffffc0000b3a44 <__kill_pgrp_info+112>

0xffffffc0000b39f0 <__kill_pgrp_info+28>:       ldr     x19, [x2,#16]

0xffffffc0000b39f4 <__kill_pgrp_info+32>:       cbz     x19, 0xffffffc0000b3a44 <__kill_pgrp_info+112>

0xffffffc0000b39f8 <__kill_pgrp_info+36>:       sub     x19, x19, #0x260

0xffffffc0000b39fc <__kill_pgrp_info+40>:       mov     w20, #0x0                       // #0

0xffffffc0000b3a00 <__kill_pgrp_info+44>:       b       0xffffffc0000b3a08 <__kill_pgrp_info+52>

0xffffffc0000b3a04 <__kill_pgrp_info+48>:       sub     x19, x19, #0x260

0xffffffc0000b3a08 <__kill_pgrp_info+52>:       mov     x2, x19

0xffffffc0000b3a0c <__kill_pgrp_info+56>:       mov     w0, w21

0xffffffc0000b3a10 <__kill_pgrp_info+60>:       mov     x1, x22

0xffffffc0000b3a14 <__kill_pgrp_info+64>:       bl      0xffffffc0000b395c <group_send_sig_info>

0xffffffc0000b3a18 <__kill_pgrp_info+68>:       cmp     w0, wzr

0xffffffc0000b3a1c <__kill_pgrp_info+72>:       ldr     x19, [x19,#608]

0xffffffc0000b3a20 <__kill_pgrp_info+76>:       cset    w2, eq

0xffffffc0000b3a24 <__kill_pgrp_info+80>:       orr     w20, w20, w2

0xffffffc0000b3a28 <__kill_pgrp_info+84>:       cbnz    x19, 0xffffffc0000b3a04 <__kill_pgrp_info+48>

0xffffffc0000b3a2c <__kill_pgrp_info+88>:       cbz     w20, 0xffffffc0000b3a34 <__kill_pgrp_info+96>

0xffffffc0000b3a30 <__kill_pgrp_info+92>:       mov     w0, w19

0xffffffc0000b3a34 <__kill_pgrp_info+96>:       ldp     x19, x20, [sp,#16]

0xffffffc0000b3a38 <__kill_pgrp_info+100>:      ldp     x21, x22, [sp,#32]

0xffffffc0000b3a3c <__kill_pgrp_info+104>:      ldp     x29, x30, [sp],#48

0xffffffc0000b3a40 <__kill_pgrp_info+108>:      ret

0xffffffc0000b3a44 <__kill_pgrp_info+112>:      mov     w0, #0xfffffffd                 // #-3

0xffffffc0000b3a48 <__kill_pgrp_info+116>:      ldp     x19, x20, [sp,#16]

0xffffffc0000b3a4c <__kill_pgrp_info+120>:      ldp     x21, x22, [sp,#32]

0xffffffc0000b3a50 <__kill_pgrp_info+124>:      ldp     x29, x30, [sp],#48

0xffffffc0000b3a54 <__kill_pgrp_info+128>:      ret

Kernel panic @yellow line, cpu tried to load the content of address (x2+16) to x19, but x2+16= 0x00000012 is a valid kernel space address, access it caused kernel panic.

Let’s see why x2(struct pid *pgrp) equals to  0x2

 

__kill_pgrp_info is called in function kill_orphaned_pgrp, disassemble it.

 

crash> dis kill_orphaned_pgrp

0xffffffc0000a3c6c <kill_orphaned_pgrp>:        stp     x29, x30, [sp,#-32]!

0xffffffc0000a3c70 <kill_orphaned_pgrp+4>:      mov     x29, sp

0xffffffc0000a3c74 <kill_orphaned_pgrp+8>:      str     x19, [sp,#16]

0xffffffc0000a3c78 <kill_orphaned_pgrp+12>:     ldr     x4, [x0,#544]

0xffffffc0000a3c7c <kill_orphaned_pgrp+16>:     mov     x3, x0

0xffffffc0000a3c80 <kill_orphaned_pgrp+20>:     ldr     x19, [x4,#624]

0xffffffc0000a3c84 <kill_orphaned_pgrp+24>:     cbz     x1, 0xffffffc0000a3cb8 <kill_orphaned_pgrp+76>

0xffffffc0000a3c88 <kill_orphaned_pgrp+28>:     mov     x3, #0x0                        // #0

0xffffffc0000a3c8c <kill_orphaned_pgrp+32>:     ldr     x1, [x1,#544]

0xffffffc0000a3c90 <kill_orphaned_pgrp+36>:     ldr     x0, [x1,#624]

0xffffffc0000a3c94 <kill_orphaned_pgrp+40>:     cmp     x19, x0

0xffffffc0000a3c98 <kill_orphaned_pgrp+44>:     b.eq    0xffffffc0000a3cac <kill_orphaned_pgrp+64>

0xffffffc0000a3c9c <kill_orphaned_pgrp+48>:     ldr     x1, [x1,#648]

0xffffffc0000a3ca0 <kill_orphaned_pgrp+52>:     ldr     x0, [x4,#648]

0xffffffc0000a3ca4 <kill_orphaned_pgrp+56>:     cmp     x1, x0

0xffffffc0000a3ca8 <kill_orphaned_pgrp+60>:     b.eq    0xffffffc0000a3cc0 <kill_orphaned_pgrp+84>

0xffffffc0000a3cac <kill_orphaned_pgrp+64>:     ldr     x19, [sp,#16]

0xffffffc0000a3cb0 <kill_orphaned_pgrp+68>:     ldp     x29, x30, [sp],#32

0xffffffc0000a3cb4 <kill_orphaned_pgrp+72>:     ret

0xffffffc0000a3cb8 <kill_orphaned_pgrp+76>:     ldr     x1, [x0,#496]

0xffffffc0000a3cbc <kill_orphaned_pgrp+80>:     b       0xffffffc0000a3c8c <kill_orphaned_pgrp+32>

0xffffffc0000a3cc0 <kill_orphaned_pgrp+84>:     mov     x0, x19

0xffffffc0000a3cc4 <kill_orphaned_pgrp+88>:     mov     x1, x3

0xffffffc0000a3cc8 <kill_orphaned_pgrp+92>:     bl      0xffffffc0000a3a30 <will_become_orphaned_pgrp>

0xffffffc0000a3ccc <kill_orphaned_pgrp+96>:     cbz     w0, 0xffffffc0000a3cac <kill_orphaned_pgrp+64>

0xffffffc0000a3cd0 <kill_orphaned_pgrp+100>:    cbz     x19, 0xffffffc0000a3cac <kill_orphaned_pgrp+64>

0xffffffc0000a3cd4 <kill_orphaned_pgrp+104>:    ldr     x0, [x19,#16]

0xffffffc0000a3cd8 <kill_orphaned_pgrp+108>:    cbz     x0, 0xffffffc0000a3ce0 <kill_orphaned_pgrp+116>

0xffffffc0000a3cdc <kill_orphaned_pgrp+112>:    sub     x0, x0, #0x260

0xffffffc0000a3ce0 <kill_orphaned_pgrp+116>:    cbz     x0, 0xffffffc0000a3cac <kill_orphaned_pgrp+64>

0xffffffc0000a3ce4 <kill_orphaned_pgrp+120>:    ldr     x1, [x0,#1928]

0xffffffc0000a3ce8 <kill_orphaned_pgrp+124>:    ldr     w1, [x1,#108]

0xffffffc0000a3cec <kill_orphaned_pgrp+128>:    tbnz    w1, #0, 0xffffffc0000a3d00 <kill_orphaned_pgrp+148>

0xffffffc0000a3cf0 <kill_orphaned_pgrp+132>:    ldr     x0, [x0,#608]

0xffffffc0000a3cf4 <kill_orphaned_pgrp+136>:    cbz     x0, 0xffffffc0000a3cac <kill_orphaned_pgrp+64>

0xffffffc0000a3cf8 <kill_orphaned_pgrp+140>:    sub     x0, x0, #0x260

0xffffffc0000a3cfc <kill_orphaned_pgrp+144>:    b       0xffffffc0000a3ce0 <kill_orphaned_pgrp+116>

0xffffffc0000a3d00 <kill_orphaned_pgrp+148>:    mov     x2, x19

0xffffffc0000a3d04 <kill_orphaned_pgrp+152>:    mov     x1, #0x1                        // #1

0xffffffc0000a3d08 <kill_orphaned_pgrp+156>:    mov     w0, #0x1                        // #1

0xffffffc0000a3d0c <kill_orphaned_pgrp+160>:    bl      0xffffffc0000b39d4 <__kill_pgrp_info>

0xffffffc0000a3d10 <kill_orphaned_pgrp+164>:    mov     x1, #0x1                        // #1

0xffffffc0000a3d14 <kill_orphaned_pgrp+168>:    mov     x2, x19

0xffffffc0000a3d18 <kill_orphaned_pgrp+172>:    mov     w0, #0x12                       // #18

0xffffffc0000a3d1c <kill_orphaned_pgrp+176>:    bl      0xffffffc0000b39d4 <__kill_pgrp_info>

0xffffffc0000a3d20 <kill_orphaned_pgrp+180>:    b       0xffffffc0000a3cac <kill_orphaned_pgrp+64>

From the above yellow line, we could found that x2 is directly got from x19, but x19(ffffffc02356eb40) is still a valid struct pointer, we could parse it:

crash> struct pid ffffffc02356eb40

struct pid {

  count = {

    counter = 1919380323

  },

  level = 1684960623,

  tasks = {{

      first = 0x702e392e7363695f

    }, {

      first = 0xa02014b50676e

    }, {

      first = 0x373d00000000000a

    }},

  rcu = {

    next = 0x25d4a1869c738f8,

    func = 0x3b0000025d0000

  },

  numbers = {{

      nr = 0,

      ns = 0xbe51300000000,

      pid_chain = {

        next = 0x776172642f736572,

        pprev = 0x70646d2d656c6261

      }

    }}

}

So the question is why x2 suddenly change to 0x2 without any explicit assignment.

It is more like a cpu collapse issue.

posted @ 2014-12-01 11:24  muryo  阅读(3817)  评论(0编辑  收藏  举报