首页 > 代码库 > kernel panic 分析(NULL pointer dereference)

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;13371338    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_info0xffffffc0000b39d4 <__kill_pgrp_info>:  stp     x29, x30, [sp,#-48]!0xffffffc0000b39d8 <__kill_pgrp_info+4>:        mov     x29, sp0xffffffc0000b39dc <__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, w00xffffffc0000b39e8 <__kill_pgrp_info+20>:       mov     x22, x10xffffffc0000b39ec <__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, #0x2600xffffffc0000b39fc <__kill_pgrp_info+40>:       mov     w20, #0x0                       // #00xffffffc0000b3a00 <__kill_pgrp_info+44>:       b       0xffffffc0000b3a08 <__kill_pgrp_info+52>0xffffffc0000b3a04 <__kill_pgrp_info+48>:       sub     x19, x19, #0x2600xffffffc0000b3a08 <__kill_pgrp_info+52>:       mov     x2, x190xffffffc0000b3a0c <__kill_pgrp_info+56>:       mov     w0, w210xffffffc0000b3a10 <__kill_pgrp_info+60>:       mov     x1, x220xffffffc0000b3a14 <__kill_pgrp_info+64>:       bl      0xffffffc0000b395c <group_send_sig_info>0xffffffc0000b3a18 <__kill_pgrp_info+68>:       cmp     w0, wzr0xffffffc0000b3a1c <__kill_pgrp_info+72>:       ldr     x19, [x19,#608]0xffffffc0000b3a20 <__kill_pgrp_info+76>:       cset    w2, eq0xffffffc0000b3a24 <__kill_pgrp_info+80>:       orr     w20, w20, w20xffffffc0000b3a28 <__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, w190xffffffc0000b3a34 <__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],#480xffffffc0000b3a40 <__kill_pgrp_info+108>:      ret0xffffffc0000b3a44 <__kill_pgrp_info+112>:      mov     w0, #0xfffffffd                 // #-30xffffffc0000b3a48 <__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],#480xffffffc0000b3a54 <__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_pgrp0xffffffc0000a3c6c <kill_orphaned_pgrp>:        stp     x29, x30, [sp,#-32]!0xffffffc0000a3c70 <kill_orphaned_pgrp+4>:      mov     x29, sp0xffffffc0000a3c74 <kill_orphaned_pgrp+8>:      str     x19, [sp,#16]0xffffffc0000a3c78 <kill_orphaned_pgrp+12>:     ldr     x4, [x0,#544]0xffffffc0000a3c7c <kill_orphaned_pgrp+16>:     mov     x3, x00xffffffc0000a3c80 <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                        // #00xffffffc0000a3c8c <kill_orphaned_pgrp+32>:     ldr     x1, [x1,#544]0xffffffc0000a3c90 <kill_orphaned_pgrp+36>:     ldr     x0, [x1,#624]0xffffffc0000a3c94 <kill_orphaned_pgrp+40>:     cmp     x19, x00xffffffc0000a3c98 <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, x00xffffffc0000a3ca8 <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],#320xffffffc0000a3cb4 <kill_orphaned_pgrp+72>:     ret0xffffffc0000a3cb8 <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, x190xffffffc0000a3cc4 <kill_orphaned_pgrp+88>:     mov     x1, x30xffffffc0000a3cc8 <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, #0x2600xffffffc0000a3ce0 <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, #0x2600xffffffc0000a3cfc <kill_orphaned_pgrp+144>:    b       0xffffffc0000a3ce0 <kill_orphaned_pgrp+116>0xffffffc0000a3d00 <kill_orphaned_pgrp+148>:    mov     x2, x190xffffffc0000a3d04 <kill_orphaned_pgrp+152>:    mov     x1, #0x1                        // #10xffffffc0000a3d08 <kill_orphaned_pgrp+156>:    mov     w0, #0x1                        // #10xffffffc0000a3d0c <kill_orphaned_pgrp+160>:    bl      0xffffffc0000b39d4 <__kill_pgrp_info>0xffffffc0000a3d10 <kill_orphaned_pgrp+164>:    mov     x1, #0x1                        // #10xffffffc0000a3d14 <kill_orphaned_pgrp+168>:    mov     x2, x190xffffffc0000a3d18 <kill_orphaned_pgrp+172>:    mov     w0, #0x12                       // #180xffffffc0000a3d1c <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 ffffffc02356eb40struct 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.

kernel panic 分析(NULL pointer dereference)