[内核内存] linux内核态内存检测技术


linux常见的内存错误访问:

  • 越界访问(out of bounds)
  • 访问已经释放的内存(use after free)
  • 重复释放
  • 内存泄露(memory leak)
  • 栈溢出(stack overflow)
a. 对于内核内存泄露问题--->kmemleak工具

b. 对越界访问,重复释放,栈溢出和访问已经释放内存等问题:
	1.若是slab/slub分配器分配的内存:slub_debug
	2.KASAN是比slub_debug强大的功能,但资源消耗更大

1 slub_debug

slub_debug可以检测内核态内存越界(out-of-bounds)和访问已经释放的内存(use-after-free)等问题,部分的slub_debug问题需要通过slabinfo工具去发现(该工具在内核源码的tools/vm目录下gcc编译),但是仅仅针对从slub/slab分配器分配的内存,对于从栈中或者数据区中分配的内存,slub_debug就不能进行检测,可以利用KANSAN等其他内存检测工具。

内核配置

CONFIG_SLUB=y

CONFIG_SLUB_DEBUG=y

CONFIG_SLUB_DEBUG_ON=y

CONFIG_SLUB_STATS=y

slabinfo工具编译

在linux内核源码tools/vm目录下执行:
	***gcc -o slabinfo slabinfo.c
程序执行后,可以通过slabinfo -v查看日志结果

系统加载内核启动参数

​ 如qemu启动内核cmd的–append里面添加"slub_debug=UFPZ"如:

sudo qemu-system-x86_64 -kernel ./bzImage -initrd ./cgel-image-virt-generic-pc-x86-64.cpio -net nic -net 
	tap -m 1024M -smp 4 -append "root=/dev/ram rw console=ttyS0 slub_debug=UFPZ" -nographic  -cpu max
  • F:在free的时候会执行检查。
  • Z:表示Red Zone的意思。
  • P:是Poison的意思。
  • U:会记录slab的使用者信息,如果打开,会会显示分配释放对象的栈回溯。

功能

  1. 越界访问
    1. 左越界:Object padding overwritten
    2. 右越界:Redzone overwritten
  2. 重复释放:Object already free
  3. 访问已释放内存:Posion overwritten

实例

右越界访问:

  1. ​ 模块文件

    //slub_right_oob.c
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/slab.h>
    #include<linux/delay.h>
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("JingTao");
    MODULE_DESCRIPTION("A simple test program for slub right oob test");
    MODULE_VERSION("0.01");
    
    char *buf;
    void create_slub_error(void)
    {
    	printk(KERN_INFO "hello, master!\n");  
    	buf = kmalloc(32, GFP_KERNEL);
    	if(!buf)
    		return;
    	buf[32] = 0x88;
    	kfree(buf);
    }
    
    static int __init lkm_example_init(void) {
    	create_slub_error();
    	return 0;
    }
    static void __exit lkm_example_exit(void) {
    	printk(KERN_INFO "Goodbye, master!\n");
    }
    module_init(lkm_example_init);
    module_exit(lkm_example_exit);
    
  2. Makefile文件

    obj-m := mySkubRightOob.o
    
    #和mo块c文件名一致
    mySlabRightOob-objs := slub_right_oob.o
    
    #内核源码路径(源码已经make all)
    KERNELDIR := /home/taojing/linux5.11.2/src
    
    ARCH := x86
    
    #工具链路径
    CROSS_COMPILE := /home/taojing/toolchain/x86_64/x86_64_gcc6.2.0_glibc2.24.0/bin/x86_64-pc-linux-gnu-
    
    #当前路径,编译结果存放地,一般和模块c文件在一个目录
    CURENTDIR := $(shell pwd)
    
    default:
            make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(CURENTDIR) modules
    
    clean:
            @rm -rf $(CURENTDIR)/*.ko
            @rm -rf *.order
            @rm -rf Module.symvers
            @rm -rf *.o
            @rm -rf *.mod*
    

    在上述模块c文件和Makefile所在目录执行make,就可生成mySkubRightOob.ko文件。然后将该模块文件插入qemu启动的内核中。

    slub_debug打印日志如下(有些时候需要执行slabinfo -v命令获取到日志信息)

    [  126.790861] mySlabRightOob: loading out-of-tree module taints kernel.
    [  126.840081] hello, master!
    [  126.841079] =============================================================================
    #指明错误类型---Redzone overwritten,(kmalloc分配的内存区域)右越界访问
    [  126.841920] BUG kmalloc-32 (Tainted: G           O     ): Redzone overwritten
    [  126.841920] -----------------------------------------------------------------------------
    [  126.841920]
    [  126.841920] Disabling lock debugging due to kernel taint
    #red zone开头两字节区域的magic num有0xcc变成0x88,异常
    [  126.841920] INFO: 0x000000009363cedd-0x000000009363cedd @offset=3392. First byte 0x88 instead of 0xcc
    #slab的分配栈回溯
    [  126.841920] INFO: Allocated in create_slub_error+0x22/0x3c [mySlabRightOob] age=2 cpu=3 pid=207
    [  126.841920]  __slab_alloc+0x9/0x10
    [  126.841920]  kmem_cache_alloc_trace+0x177/0x1e0
    [  126.841920]  create_slub_error+0x22/0x3c [mySlabRightOob]
    [  126.841920]  lkm_example_init+0x5/0x1000 [mySlabRightOob]
    [  126.841920]  do_one_initcall+0x47/0x1c0
    [  126.841920]  do_init_module+0x56/0x1ff
    [  126.841920]  load_module+0x25f4/0x2920
    [  126.841920]  __do_sys_init_module+0x152/0x170
    [  126.841920]  do_syscall_64+0x33/0x40
    [  126.841920]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    #slab的释放栈回溯
    [  126.841920] INFO: Freed in security_cred_free+0x37/0x50 age=87220 cpu=2 pid=0
    [  126.841920]  security_cred_free+0x37/0x50
    [  126.841920]  put_cred_rcu+0x1e/0x90
    [  126.841920]  rcu_core+0x1cf/0x660
    [  126.841920]  __do_softirq+0xf4/0x283
    [  126.841920]  asm_call_irq_on_stack+0x12/0x20
    [  126.841920]  do_softirq_own_stack+0x32/0x40
    [  126.841920]  irq_exit_rcu+0x93/0xa0
    [  126.841920]  sysvec_apic_timer_interrupt+0x2c/0x80
    [  126.841920]  asm_sysvec_apic_timer_interrupt+0x12/0x20
    [  126.841920]  default_idle+0xe/0x10
    [  126.841920]  default_idle_call+0x2d/0xa0
    [  126.841920]  do_idle+0x1ad/0x270
    [  126.841920]  cpu_startup_entry+0x14/0x20
    [  126.841920]  secondary_startup_64_no_verify+0xc2/0xcb
    #slab的地址,以及其它信息。
    [  126.841920] INFO: Slab 0x0000000005649ac3 objects=19 used=14 fp=0x000000002c2e8a49 flags=0x100000000010201
    # 当前Object起始,及相关信息
    [  126.841920] INFO: Object 0x00000000c5d6d5ae @offset=3360 fp=0x0000000000000000
    [  126.841920]
    # 问题slab对象内容,打印问题slab对象内容之前一些字节。前面的Redzone用于检测左越界访问,magic num为oxcc
    [  126.841920] Redzone 0000000083d35604: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
    [  126.841920] Redzone 00000000218c6dd9: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
    [  126.841920] Object 00000000c5d6d5ae: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    [  126.841920] Object 00000000121b8350: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5  kkkkkkkkkkkkkkk.
    #该Redzone用于检测右越界访问,前两个字节为0x88,不为默认的0xcc,说明右访问越界,问题出在这,容易看出就越界访问了两个字节。
    [  126.841920] Redzone 000000009363cedd: 88 cc cc cc cc cc cc cc                          ........
    # Padding内容,为了对象对齐而补充
    [  126.841920] Padding 00000000a38a7a7b: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a  ZZZZZZZZZZZZZZZZ
    [  126.841920] Padding 00000000893bf7b2: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a  ZZZZZZZZZZZZZZZZ
    #检查问题点的栈打印,这里是由于slabinfo找出来的。
    [  126.841920] CPU: 3 PID: 207 Comm: insmod Tainted: G    B      O      5.11.2 #2
    [  126.841920] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
    [  126.841920] Call Trace:
    [  126.841920]  dump_stack+0x57/0x6a
    [  126.841920]  check_bytes_and_report+0xe6/0x120
    [  126.841920]  check_object+0x1c3/0x270
    [  126.841920]  ? lkm_example_init+0x5/0x1000 [mySlabRightOob]
    [  126.841920]  free_debug_processing+0x136/0x330
    [  126.841920]  __slab_free+0x210/0x3d0
    [  126.841920]  ? __slab_alloc+0xb/0x10
    [  126.841920]  ? 0xffffffffc01a8000
    [  126.841920]  ? 0xffffffffc01a8000
    [  126.841920]  ? lkm_example_init+0x5/0x1000 [mySlabRightOob]
    [  126.841920]  lkm_example_init+0x5/0x1000 [mySlabRightOob]
    [  126.841920]  do_one_initcall+0x47/0x1c0
    [  126.841920]  ? __slab_alloc+0x9/0x10
    [  126.841920]  ? kmem_cache_alloc_trace+0x177/0x1e0
    [  126.841920]  do_init_module+0x56/0x1ff
    [  126.841920]  load_module+0x25f4/0x2920
    [  126.841920]  ? __do_sys_init_module+0x152/0x170
    [  126.841920]  __do_sys_init_module+0x152/0x170
    [  126.841920]  do_syscall_64+0x33/0x40
    [  126.841920]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [  126.841920] RIP: 0033:0x4aabf9
    [  126.841920] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 6b 33 01 00 c3 66 2e 0f 1f 84 00 00 00 00
    [  126.841920] RSP: 002b:00007ffc6da5d0d8 EFLAGS: 00000246 ORIG_RAX: 00000000000000af
    [  126.841920] RAX: ffffffffffffffda RBX: 00007ffc6da5d480 RCX: 00000000004aabf9
    [  126.841920] RDX: 000000000063822b RSI: 0000000000001368 RDI: 0000000001147d20
    [  126.841920] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000001368
    [  126.841920] R10: 0000000001147cc0 R11: 0000000000000246 R12: 00007ffc6da5d469
    [  126.841920] R13: 00007ffc6da5d488 R14: 000000000063822b R15: 0000000000000000
    #问题点是如何被解决的,此处恢复2个字节为0xcc
    [  126.841920] FIX kmalloc-32: Restoring 0x000000009363cedd-0x000000009363cedd=0xcc
    

    slub_debug实现原理

    ​ 参考:https://zhuanlan.zhihu.com/p/103721910

2 kmemleak

linux内核提供了一个方便的内核态内存泄露扫描工具:kmemleak,该工具通过启动一个内核线程对linux系统的内存进行扫描,然后打印它新发现未引用内存对象的数量和相关信息。

内核配置

CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n #打开该选项需要在内核命名行添加kmemleak=on启动参数

qemu启动内核

sudo qemu-system-x86_64 -kernel ./bzImage -initrd ./cgel-image-virt-generic-pc-x86-64.cpio 
						-net nic -net tap -m 1024M -smp 4 
						-append "root=/dev/ram rw console=ttyS0 kmemleak=on" -nographic  -cpu max

系统启动后扫描方式

1.mount -t debugfs debugfs /sys/kernel/debug/
2.执行内核测试程序触发内存泄露
3.echo scan > /sys/kernel/debug/kmemleak(手动触发扫描,需等待一段时间)
4.cat /sys/kernel/debug/kmemleak(查看泄露检测日志打印,并分析原因)

原理

kmemleak通过追踪kmalloc(), vmalloc(), kmem_cache_alloc()等函数,把分配内存的指针和大小、时间、stack trace等信息记录在一个rbtree中,等到调用free释放内存时就把相应的记录从rbtree中删除。也就是说rbtree中的记录就是已经分配出去但尚未释放的内存,其中有些内存尚未释放是因为还在被使用,这属于正常情况,而不正常的情况,即真正“泄漏”的内存都是不会再被使用的,那么如何找出泄漏的内存呢?kmemleak缺省每10分钟对内存做一次扫描,寻找内存中有没有rbtree中记录的地址,如果某个地址在内存中找不到,就认为这个地址是无人引用的,不会再被用到,是“泄漏”了,然后,把这些泄漏的内存地址以及rbtree中记录的相关信息通过 /sys/kernel/debug/kmemleak 这个接口展现给我们。

实例

1.模块c文件

//kmemleak.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include<linux/delay.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("JingTao");
MODULE_DESCRIPTION("A simple test program for kmemleak test");
MODULE_VERSION("0.01");

static char *buf;


void create_kmemleak(void)
{
  buf = kmalloc(120, GFP_KERNEL);
  buf = vmalloc(4096);
}

static int __init lkm_example_init(void) {
        create_kmemleak();
        return 0;
}
static void __exit lkm_example_exit(void) {
        printk(KERN_INFO "Goodbye, master!\n");
}
module_init(lkm_example_init);
module_exit(lkm_example_exit);

2.Makefile文件

obj-m := mykMemLeak.o

#和mo块c文件名一致
mykMemLeak-objs := kmemleak.o

#内核源码路径(源码已经make all)
KERNELDIR := /home/taojing/linux5.11.2/src

ARCH := x86

#工具链路径
CROSS_COMPILE := /home/taojing/toolchain/x86_64/x86_64_gcc6.2.0_glibc2.24.0/bin/x86_64-pc-linux-gnu-

#当前路径,编译结果存放地,一般和模块c文件在一个目录
CURENTDIR := $(shell pwd)

default:
        make -C $(KERNELDIR) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) M=$(CURENTDIR) modules

clean:
        @rm -rf $(CURENTDIR)/*.ko
        @rm -rf *.order
        @rm -rf Module.symvers
        @rm -rf *.o
        @rm -rf *.mod*

3.日志报告

在上述模块c文件和Makefile所在目录执行make,就可生成mykMemLeak.ko文件。然后将该模块文件插入qemu启动的内核中。测试程序执行完后,通过rmmod测试模块。手动触发kmemleak扫描,扫描结束后通过cat /sys/kernel/debug/kmemleak查看日志并分析。

#第一处可疑点,泄露128直接的内存
unreferenced object 0xff29455ffdc2e600 (size 128):
  #相关进程信息
  comm "insmod", pid 231, jiffies 4296287062 (age 195.881s)
  #二进制打印
  hex dump (first 32 bytes):
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
    6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
  #栈回溯
  backtrace:
    [<00000000f6e38ea2>] 0xffffffffc00ce016
    [<000000001aa41d05>] 0xffffffffc00d3005
    [<00000000be0b8009>]  do_one_initcall+0x47/0x1c0
    [<00000000448019b3>] do_init_module+0x56/0x1ff
    [<00000000ca42473a>] load_module+0x2484/0x29b0
    [<000000008b554566>] __do_sys_init_module+0x152/0x170
    [<000000005dc7a0d1>] do_syscall_64+0x33/0x40
    [<00000000e7ec7f2c>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
unreferenced object 0xff41a8e240045000 (size 4096):
  comm "insmod", pid 231, jiffies 4296287066 (age 195.877s)
  hex dump (first 32 bytes):
    85 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00  ................
    50 f0 0c c0 ff ff ff ff 9a 01 00 00 00 00 00 00  P...............
  backtrace:
    [<00000000def4678d>] __vmalloc_node_range+0x1fe/0x250
    [<0000000051e15033>] __vmalloc_node+0x4b/0x60
    [<000000001aa41d05>] 0xffffffffc00d3005
    [<00000000be0b8009>] do_one_initcall+0x47/0x1c0
    [<00000000448019b3>] do_init_module+0x56/0x1ff
    [<00000000ca42473a>] load_module+0x2484/0x29b0
    [<000000008b554566>] __do_sys_init_module+0x152/0x170
    [<000000005dc7a0d1>] do_syscall_64+0x33/0x40
    [<00000000e7ec7f2c>] entry_SYSCALL_64_after_hwframe+0x44/0xa9

3 KASAN内存检查工具

Kasan(Kernel Address Sanitizer)它是一个动态的内核内存错误检测工具,主要功能是检查内存的越界访问和使用已经释放的内存等问题。同SLUB_DEBUG工具比较,kasan具有下列优点:

  1. 可以检测全局变量、栈、堆分配的内存发生越界访问等问题。
  2. 支持内存问题的实时化检测(在程序运行时kasan能动态监测到内存错误访问并立即生成对应的日志报告)。

ps:kasan暂不支持32位ARM,支持ARM64和X86。

内核配置

CONFIG_SLUB_DEBUG=y
CONFIG_KASAN=y

实例

  1. 源文件:将下列程序编译从ko模块文件,插入配置了kasan工具的linux系统中。

    //kasan_stack_oob.c
    #define pr_fmt(fmt) "kasan test: %s " fmt, __func__
    
    #include <linux/kernel.h>
    #include <linux/printk.h>
    #include <linux/slab.h>
    #include <linux/string.h>
    #include <linux/module.h>
    #include <linux/vmalloc.h>
    static noinline void __init kasan_stack_oob(void)
    {
    	char stack_array[10];
    	volatile int i = 0;
    	char *p = &stack_array[ARRAY_SIZE(stack_array) + i];
    
    	pr_info("out-of-bounds on stack\n");
    	*(volatile char *)p;
    }
    
    static int __init kmalloc_tests_init(void)
    {
    	kasan_stack_oob();
    	return -EAGAIN;
    }
    
    module_init(kmalloc_tests_init);
    MODULE_LICENSE("GPL");
    
  2. ko模块插入后会在shell终端实时生成如下错误报告:

    [ 2123.786582] kasan test: kasan_stack_oob out-of-bounds on stack
    [ 2123.789619] ==================================================================
    #错误类型是stack-out-of-bounds,在kasan_stack_oob中产生。
    [ 2123.790271] BUG: KASAN: stack-out-of-bounds in kasan_stack_oob+0x9b/0xb8 [testKasan] at addr ffff88003f517a42
    [ 2123.790271] Read of size 1 by task insmod/1201
    [ 2123.790271] page:ffffea0000fd45c0 count:0 mapcount:0 mapping:          (null) index:0x1
    [ 2123.790271] flags: 0x100000000000000()
    #非法访问(页)
    [ 2123.790271] page dumped because: kasan: bad access detected
    [ 2123.790271] CPU: 0 PID: 1201 Comm: insmod Tainted: G        W  O    4.4.157-rt174-CGELV6.03.50B5.20201124 #1
    [ 2123.790271] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
    [ 2123.790271]  0000000000000000 ffff88003f517928 ffffffff81529f29 0000000000000001
    [ 2123.790271]  ffffed0007ea2f48 ffff88003f5179a8 ffffffff812571fa ffffffff811db813
    [ 2123.790271]  ffff880027802400 0000000000000246 ffffffffa003809b ffff88003f517988
    #问题点的栈回溯
    [ 2123.790271] Call Trace:
    [ 2123.790271]  [<ffffffff81529f29>] dump_stack+0x59/0x80
    [ 2123.790271]  [<ffffffff812571fa>] kasan_report.part.2+0x4ea/0x520
    [ 2123.790271]  [<ffffffff811db813>] ? power_down+0xa4/0xa4
    [ 2123.790271]  [<ffffffffa003809b>] ? kasan_stack_oob+0x9b/0xb8 [testKasan]
    [ 2123.790271]  [<ffffffff8111d897>] ? __trace_hardirqs_off+0x27/0x30
    [ 2123.790271]  [<ffffffffa00380b8>] ? kasan_stack_oob+0xb8/0xb8 [testKasan]
    [ 2123.790271]  [<ffffffff81257490>] kasan_report+0x20/0x30
    [ 2123.790271]  [<ffffffff812564a6>] __asan_load1+0x46/0x50
    [ 2123.790271]  [<ffffffffa003809b>] kasan_stack_oob+0x9b/0xb8 [testKasan]
    [ 2123.790271]  [<ffffffffa0038000>] ? 0xffffffffa0038000
    [ 2123.790271]  [<ffffffff81542aa0>] ? kvasprintf_const+0xc0/0xc0
    [ 2123.790271]  [<ffffffff8100040f>] ? do_one_initcall+0xdf/0x240
    [ 2123.790271]  [<ffffffff8125370d>] ? kfree+0x15d/0x180
    [ 2123.790271]  [<ffffffffa00380c1>] kmalloc_tests_init+0x9/0x10 [testKasan]
    [ 2123.790271]  [<ffffffff81000421>] do_one_initcall+0xf1/0x240
    [ 2123.790271]  [<ffffffff81000330>] ? try_to_run_init_process+0x40/0x40
    [ 2123.790271]  [<ffffffff81256615>] ? kasan_unpoison_shadow+0x35/0x50
    [ 2123.790271]  [<ffffffff81256615>] ? kasan_unpoison_shadow+0x35/0x50
    [ 2123.790271]  [<ffffffff81256615>] ? kasan_unpoison_shadow+0x35/0x50
    [ 2123.790271]  [<ffffffff8125671c>] ? __asan_register_globals+0x7c/0xa0
    [ 2123.790271]  [<ffffffff811dbbd2>] do_init_module+0xf4/0x2c8
    [ 2123.790271]  [<ffffffff8114e1a4>] load_module+0x3694/0x40a0
    [ 2123.790271]  [<ffffffff811488f0>] ? __symbol_put+0xa0/0xa0
    [ 2123.790271]  [<ffffffff8114ab10>] ? module_frob_arch_sections+0x20/0x20
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff81e81fa5>] ? __schedule+0x405/0x8e0
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff81e81fa5>] ? __schedule+0x405/0x8e0
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff81e81fa5>] ? __schedule+0x405/0x8e0
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff81e81fa5>] ? __schedule+0x405/0x8e0
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff81e81fa5>] ? __schedule+0x405/0x8e0
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff81e81fa5>] ? __schedule+0x405/0x8e0
    [ 2123.790271]  [<ffffffff81e81fb1>] ? __schedule+0x411/0x8e0
    [ 2123.790271]  [<ffffffff8114ed35>] SYSC_init_module+0x185/0x1a0
    [ 2123.790271]  [<ffffffff8114ebb0>] ? load_module+0x40a0/0x40a0
    [ 2123.790271]  [<ffffffff8100226c>] ? exit_to_usermode_loop+0x7c/0xd0
    [ 2123.790271]  [<ffffffff8114ee69>] SyS_init_module+0x9/0x10
    [ 2123.790271]  [<ffffffff81e8834a>] entry_SYSCALL_64_fastpath+0x1e/0x8e
    [ 2123.790271] Memory state around the buggy address:#异常点附近的内存dump
    [ 2123.790271]  ffff88003f517900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    [ 2123.790271]  ffff88003f517980: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04
    [ 2123.790271] >ffff88003f517a00: f4 f4 f4 f2 f2 f2 f2 00 02 f4 f4 f3 f3 f3 f3 00
    [ 2123.790271]                                            ^
    [ 2123.790271]  ffff88003f517a80: 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 00 00
    [ 2123.790271]  ffff88003f517b00: 00 00 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
    [ 2123.790271] ==================================================================
    [ 2123.790271] Disabling lock debugging due to kernel taint
    
    

kasan实现原理

后期分析,参考:http://www.wowotech.net/memory_management/424.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值