内核栈溢出例子

来源:互联网 发布:python dict items 编辑:程序博客网 时间:2024/06/06 05:29
内核栈溢出分析例子
1.栈溢出日志
[  151.986352] Unable to handle kernel NULL pointer dereference at virtual address 00000124
[  151.990030] pgd = c0004000
[  151.990030] [00000124] *pgd=00000000
[  151.990030] Internal error: Oops: 5 [#1] ARM
[  151.990030] Modules linked in: sw_device
[  151.990030] CPU: 0    Not tainted  (3.4.39 #378)
[  151.990030] PC is at do_page_fault+0x40/0x260
[  151.990030] LR is at do_translation_fault+0x24/0xb8
[  151.990030] pc : [<c00146c0>]    lr : [<c001498c>]    psr: 00000193
[  151.990030] sp : c9a1e010  ip : c9a1e050  fp : c9a1e04c
[  151.990030] r10: 00000028  r9 : c9a1e22d  r8 : 00000005
[  151.990030] r7 : c9a1e120  r6 : 00000080  r5 : c9a1e120  r4 : 00000148
[  151.990030] r3 : c9a1e000  r2 : 00000193  r1 : c9a1e010  r0 : 00000148
[  151.990030] Flags: nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[  151.990030] Control: 10c5387d  Table: 49a24059  DAC: 00000015
[  151.990030] 
......
[  151.990030] Process sw_wq (pid: 54, stack limit = 0xc9a1c2f0)
[  151.990030] Stack: (0xc9a1e010 to 0xc9a1e000)
[  151.990030] Backtrace: 
[  151.990030] [<c0014680>] (do_page_fault+0x0/0x260) from [<c001498c>] (do_translation_fault+0x24/0xb8)
[  151.990030] [<c0014968>] (do_translation_fault+0x0/0xb8) from [<c0008358>] (do_DataAbort+0x3c/0xa0)
[  151.990030]  r8:c049fbcd r7:c9a1e120 r6:00000148 r5:c04694c8 r4:00000005
[  151.990030] r3:c0014968
[  151.990030] [<c000831c>] (do_DataAbort+0x0/0xa0) from [<c000d698>] (__dabt_svc+0x38/0x60)
[  151.990030] Exception stack(0xc9a1e120 to 0xc9a1e168)
[  151.990030] e120: 0000001d 01400002 01400001 00000080 c9a1e000 c9a1e900 c9a1e1b8 c9a1e1ec
[  151.990030] e140: c049fbcd c9a1e22d 0000000f c9a1e17c c9a1e168 c9a1e168 c00215e8 c00215f8
[  151.990030] e160: 00000193 ffffffff
[  151.990030]  r7:c9a1e154 r6:ffffffff r5:00000193 r4:c00215f8
[  151.990030] [<c00215d8>] (irq_enter+0x0/0x5c) from [<c000e9c4>] (handle_IRQ+0x20/0x8c)
[  151.990030]  r5:c9a1e900 r4:0000001d
[  151.990030] [<c000e9a4>] (handle_IRQ+0x0/0x8c) from [<c0008498>] (gic_handle_irq+0x3c/0x54)
[  151.990030]  r5:c0466054 r4:f1c82000
[  151.990030] [<c000845c>] (gic_handle_irq+0x0/0x54) from [<c000d700>] (__irq_svc+0x40/0x50)
[  151.990030] Exception stack(0xc9a1e1b8 to 0xc9a1e200)
[  151.990030] e1a0:                                                       c0469ef0 c0469ef4
[  151.990030] e1c0: c0469f00 c0469f00 00000003 0000003a 60000113 60000113 c049fbcd c9a1e22d
[  151.990030] e1e0: 0000000f c9a1e284 c9a1e1c0 c9a1e200 c001cda8 c001d21c 60000113 ffffffff
[  151.990030]  r6:ffffffff r5:60000113 r4:c001d21c r3:c001cda8
[  151.990030] [<c001cef4>] (vprintk+0x0/0x364) from [<c031e4cc>] (printk+0x24/0x2c)
[  151.990030] [<c031e4a8>] (printk+0x0/0x2c) from [<c001c2b0>] (warn_slowpath_common+0x28/0x6c)
[  151.990030]  r3:00000009 r2:c0021570 r1:0000009f r0:c03cd555
[  151.990030] [<c001c288>] (warn_slowpath_common+0x0/0x6c) from [<c001c318>] (warn_slowpath_null+0x24/0x2c)
[  151.990030]  r8:d0e81000 r7:d0e822b0 r6:c9ec5720 r5:d0ec3544 r4:c049f049
[  151.990030] r3:00000009
[  151.990030] [<c001c2f4>] (warn_slowpath_null+0x0/0x2c) from [<c0021570>] (local_bh_enable+0x54/0xbc)
[  151.990030] [<c002151c>] (local_bh_enable+0x0/0xbc) from [<bf2426e0>] (rtw_free_xmitframe+0xec/0x110 [8821au])
[  151.990030]  r4:d0e822fc r3:00000100
[  151.990030] [<bf2425f4>] (rtw_free_xmitframe+0x0/0x110 [8821au]) from [<bf2baa34>] (rtw_dump_xframe+0x184/0x1bc [8821au])
[  151.990030]  r8:00000001 r7:00000606 r6:00000001 r5:d0ece638 r4:d0ec3544
[  151.990030] r3:00000001
[  151.990030] [<bf2ba8b0>] (rtw_dump_xframe+0x0/0x1bc [8821au]) from [<bf2bb0a4>] (rtl8812au_hal_xmit+0x9c/0x148 [8821au])
[  151.990030] [<bf2bb008>] (rtl8812au_hal_xmit+0x0/0x148 [8821au]) from [<bf27bd94>] (rtw_hal_xmit+0x18/0x1c [8821au])
分析:
内核栈一般结构如下,如下这个空间一般为2个页=8K,current地址小,stack base地址大,两者空间大小为8K,stack limit 是thread_info数据结构的顶部,sp必须在stack limt和stack base之间,不能上溢或者下溢
stack base ->

stack limt --->

current-------->

[  151.990030] Process sw_wq (pid: 54, stack limit = 0xc9a1c2f0)
[  151.990030] Stack: (0xc9a1e010 to 0xc9a1e000)
上述日志表示:进程sw_wq的内核栈的底部应该是0xc9a1c2f0,Stack的范围应该是
SP<->0xc9a1e000,则SP的范围应该是在0xc9a1c2f0和0xc9a1e000之间才合理,现在却在0xc9a1e000之上,可能是由于SP下溢之后导致指针错乱,从而导致上溢。

但也有可能出现下溢的情况,这需要分析日志。

2.解决方法
1)导致堆栈溢出可能得原因:a.代码错误,b.分配了较大的局部变量空间
2)如果原因是b,则可以让内核分配较大的内核栈来规避
修改arch/arm/include/asm/thread_info.h ,把1改成2.
#define THREAD_SIZE_ORDER1
#define THREAD_SIZE_ORDER 2
3)如下方法可以排查哪里
请在内核目录下, 进行以下操作,可以找出哪个模块使用的大的局部变量。
arm-non-linux-gnueabi-objdump -d vmlinux | ./scripts/checkstack.pl arm

原创粉丝点击