首页 > 代码库 > 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)