目录

一、slub内存检测

1、越界访问

2、释放后再访问

3、无效的释放

4、实验输出

二、KASAN 内存检测

1、数组越界

2、栈的越界访问

3、实验输出


一般的内存访问错误如下:

  • 越界访问
  • 访问已经释放的内存
  • 重复释放
  • 内存泄露
  • 栈溢出

在内核中提供了内存检测的工具slub与kasan,在开发时可以将检测的功能打开。

一、slub内存检测

在linux内核中,对于小块内存分配,大量使用slab/slub分配器,在内存访问中比较容易出错的地方如下:

  • 访问已经释放的内存
  • 越界访问
  • 重复释放

内核配置

CONFIG_SLUB=y

CONFIG_SLUB_DEBUG_ON=y

CONFIG_SLUB_STATS=y

使用的工具tools/vm/slabinfo

1、越界访问

static noinline void __init kmalloc_pagealloc_oob_right(void)
{char *ptr;size_t size = KMALLOC_MAX_CACHE_SIZE + 10;/* Allocate a chunk that does not fit into a SLUB cache to trigger* the page allocator fallback.*/pr_info("kmalloc pagealloc allocation: out-of-bounds to right\n");ptr = kmalloc(size, GFP_KERNEL);if (!ptr) {pr_err("Allocation failed\n");return;}ptr[size] = 0;kfree(ptr);
}

2、释放后再访问

static noinline void __init kmalloc_pagealloc_uaf(void)
{char *ptr;size_t size = KMALLOC_MAX_CACHE_SIZE + 10;pr_info("kmalloc pagealloc allocation: use-after-free\n");ptr = kmalloc(size, GFP_KERNEL);if (!ptr) {pr_err("Allocation failed\n");return;}kfree(ptr);ptr[0] = 0;
}

3、无效的释放

static noinline void __init kmalloc_pagealloc_invalid_free(void)
{char *ptr;size_t size = KMALLOC_MAX_CACHE_SIZE + 10;pr_info("kmalloc pagealloc allocation: invalid-free\n");ptr = kmalloc(size, GFP_KERNEL);if (!ptr) {pr_err("Allocation failed\n");return;}kfree(ptr + 1);
}

4、实验输出

  • 内存越界访问Redzone overwritten、Object padding overwritten
  • 重复释放Object already free
  • 访问已释放内存为Posion overwritten
# insmod slub3.ko
[  997.342740] :access free memory
benshushu:slub_test_3# [  997.436270] =============================================================================
[  997.437705] BUG kmalloc-128 (Tainted: G    B      OE    ): Redzone overwritten
[  997.438153] -----------------------------------------------------------------------------
[  997.438153]
[  997.440009] INFO: 0x000000001c0937b9-0x0000000065391b57. First byte 0x55 instead of 0xcc
[  997.442519] INFO: Allocated in create_slub_error+0x30/0x94 [slub3] age=63120 cpu=1 pid=1602

有的时候需要使用slabinfo -v才能输出错误

slub_test# ./slabinfo -v
[ 1112.602383] =============================================================================
[ 1112.602945] BUG kmalloc-128 (Tainted: G    B      OE    ): Redzone overwritten
[ 1112.603254] -----------------------------------------------------------------------------
[ 1112.603254]
[ 1112.603773] INFO: 0x00000000583020f8-0x00000000583020f8. First byte 0x55 instead of 0xcc
[ 1112.604214] INFO: Allocated in create_slub_error+0x34/0xdc [slub4] age=4071 cpu=0 pid=1687
[ 1112.604661]  __slab_alloc+0x64/0xb0
[ 1112.604822]  __kmalloc+0x558/0xee4
[ 1112.605002]  create_slub_error+0x34/0xdc [slub4]

二、KASAN 内存检测

KASAN(Kernal Address SANtizer)在Linux4.0版本中合并到官方的内核。是动态检测内存错误的工具。可以检查内存越界和使用已经释放的内存等问题。KASAN比kmemcheck工具检测速度快。

内核配置

CONFIG_HAVE_ARCH_KASAN=y

CONFIG_KASAN=y

CONFIG_KASAN_OUTLINE=y

CONFIG_KASAN_INLINE=y

CONFIG_TEST_KASAN=m //编译test_kasan.ko测试模块

内核源码中的测试程序/lib/test_ksacn.c

static int __init kmalloc_tests_init(void)
{/** Temporarily enable multi-shot mode. Otherwise, we'd only get a* report for the first case.*/bool multishot = kasan_save_enable_multi_shot();kmalloc_oob_right();kmalloc_oob_left();kmalloc_node_oob_right();
#ifdef CONFIG_SLUBkmalloc_pagealloc_oob_right();kmalloc_pagealloc_uaf();kmalloc_pagealloc_invalid_free();
#endifkmalloc_large_oob_right();kmalloc_oob_krealloc_more();kmalloc_oob_krealloc_less();kmalloc_oob_16();kmalloc_oob_in_memset();kmalloc_oob_memset_2();kmalloc_oob_memset_4();kmalloc_oob_memset_8();kmalloc_oob_memset_16();kmalloc_uaf();kmalloc_uaf_memset();kmalloc_uaf2();kmem_cache_oob();memcg_accounted_kmem_cache();kasan_stack_oob();kasan_global_oob();kasan_alloca_oob_left();kasan_alloca_oob_right();ksize_unpoisons_memory();copy_user_test();use_after_scope_test();kmem_cache_double_free();kmem_cache_invalid_free();kasan_memchr();kasan_memcmp();kasan_strings();kasan_restore_multi_shot(multishot);return -EAGAIN;
}

从上选择其中两个解析

1、数组越界

static noinline void __init kmalloc_oob_right(void)
{char *ptr;size_t size = 123;pr_info("out-of-bounds to right\n");ptr = kmalloc(size, GFP_KERNEL);if (!ptr) {pr_err("Allocation failed\n");return;}ptr[size] = 'x';kfree(ptr);
}

2、栈的越界访问

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;
}

3、实验输出

1)在内核中同时开启ksasn与slub的检测的检测,内存错误优先被kasan检测到,如下所示:

slub_test_1# insmod slub1.ko
[  744.870946] slub1: loading out-of-tree module taints kernel.
[  744.886482] slub1: module verification failed: signature and/or required key missing - tainting kernel
[  744.958499] module init
[  744.959688] ==================================================================
[  744.962726] BUG: KASAN: slab-out-of-bounds in create_slub_error+0x6c/0x78 [slub1]
[  744.963528] Write of size 130 at addr ffff800019ea1200 by task insmod/1602
[  744.964141] 
slub_test_2# insmod slub2.ko
[  874.303487]  my module init
[  874.304834] ben:double free test
[  874.305266] ==================================================================
[  874.306672] BUG: KASAN: double-free or invalid-free in create_slub_error+0x98/0xa4 [slub2]
[  874.307269]

2)将test_kasan.ko加载后,所有的打印输出有所缩减,把检测到的提示错误保留

slab-out-of-bounds, use-after-free,double-free or invalid-free,alloca-out-of-bounds

insmod test_kasan.ko
[   96.717377] test_kasan: module verification failed: signature and/or required key missing - tainting kernel
[   96.788908] kasan test: kmalloc_oob_right out-of-bounds to right
[   96.790675] ==================================================================
[   96.794556] BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xc8/0xe4 [test_kasan]
[   96.796122] Write of size 1 at addr ffff80001cebcffb by task insmod/569
[   96.796619]
[   96.797727] CPU: 0 PID: 569 Comm: insmod Kdump: loaded Tainted: G            E     5.0.0+ #2
[   96.798290] Hardware name: linux,dummy-virt (DT)
[   96.799205] Call trace:
[   96.800667]  dump_backtrace+0x0/0x97c
[   96.801030]  show_stack+0x24/0x30
[   96.801283]  __dump_stack+0x20/0x2c
[   96.801673]  dump_stack+0x318/0x690
[   96.802003]  print_address_description+0x38/0x42c
[   96.802371]  kasan_report+0x194/0x1e8
[   96.802727]  __asan_report_store1_noabort+0x30/0x3c
[   96.803462]  kmalloc_oob_right+0xc8/0xe4 [test_kasan]
[   96.805821]  kmalloc_tests_init+0x14/0x640 [test_kasan]
[   96.806516]  do_one_initcall+0xc8c/0x1ca4
[   96.806802]  do_init_module+0x1d8/0x784
[   96.807130]  load_module+0x1210/0x1920
[   96.808033]  __se_sys_finit_module+0x1c8/0x224
[   96.808527]  __arm64_sys_finit_module+0xbc/0xc8
[   96.809137]  __invoke_syscall+0x24/0x2c
[   96.809389]  invoke_syscall+0xcc/0x128
[   96.809557]  el0_svc_common+0x1c4/0x2d0
[   96.809746]  el0_svc_handler+0x91c/0x960
[   96.809946]  el0_svc+0x8/0xc
[   96.810422]
[   96.810770] Allocated by task 569:
[   96.811245]  __kasan_kmalloc+0x148/0x290
[   96.811886]  kasan_kmalloc+0x30/0x38
[   96.812672]  __kmalloc+0xea4/0xee4
[   96.813049]  kmalloc_oob_right+0x48/0xe4 [test_kasan]
[   96.813561]  kmalloc_tests_init+0x14/0x640 [test_kasan]
[   96.814003]  do_one_initcall+0xc8c/0x1ca4
[   96.814363]  do_init_module+0x1d8/0x784
[   96.814589]  load_module+0x1210/0x1920
[   96.814829]  __se_sys_finit_module+0x1c8/0x224
[   96.815093]  __arm64_sys_finit_module+0xbc/0xc8
[   96.816164]  __invoke_syscall+0x24/0x2c
[   96.816581]  invoke_syscall+0xcc/0x128
[   96.817567]  el0_svc_common+0x1c4/0x2d0
[   96.817836]  el0_svc_handler+0x91c/0x960
[   96.818363]  el0_svc+0x8/0xc
[   96.818832]
[   96.819123] Freed by task 0:
[   96.820128] (stack is not available)
[   96.820582]
[   96.820839] The buggy address belongs to the object at ffff80001cebcf80
[   96.820839]  which belongs to the cache kmalloc-128 of size 128
[   96.821736] The buggy address is located 123 bytes inside of
[   96.821736]  128-byte region [ffff80001cebcf80, ffff80001cebd000)
[   96.823027] The buggy address belongs to the page:
[   96.827418] page:ffff7e000073af00 count:1 mapcount:0 mapping:ffff800021c0c400 index:0xffff80001cebed80 compound_mapcount: 0
[   96.830608] flags: 0xffff00000010200(slab|head)
[   96.831566] raw: 0ffff00000010200 ffff7e0000752f08 ffff800021c03c90 ffff800021c0c400
[   96.833056] raw: ffff80001cebed80 0000000000190012 00000001ffffffff 0000000000000000
[   96.833864] page dumped because: kasan: bad access detected
[   96.834505]
[   96.834866] Memory state around the buggy address:
[   96.836134]  ffff80001cebce80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   96.837813]  ffff80001cebcf00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   96.839023] >ffff80001cebcf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
[   96.840070]                                                                 ^
[   96.840943]  ffff80001cebd000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   96.841405]  ffff80001cebd080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   96.841988] ==================================================================
[   96.842481] Disabling lock debugging due to kernel taint
[   96.844009] kasan test: kmalloc_oob_left out-of-bounds to left
[   96.845114] ==================================================================
[   96.849223] BUG: KASAN: slab-out-of-bounds in kmalloc_oob_left+0xc0/0x134 [test_kasan]
[   96.850317] Read of size 1 at addr ffff80001cebed7f by task insmod/569
[   96.895962] ==================================================================
[   96.898866] kasan test: kmalloc_node_oob_right kmalloc_node(): out-of-bounds to right
[   96.902638] ==================================================================
[   96.905146] BUG: KASAN: slab-out-of-bounds in kmalloc_node_oob_right+0xd0/0xe8 [test_kasan]
[   96.906247] Write of size 1 at addr ffff800015826a80 by task insmod/569
[   96.907658]
[   96.967853] ==================================================================
[   96.970577] kasan test: kmalloc_pagealloc_oob_right kmalloc pagealloc allocation: out-of-bounds to right
[   96.973391] ==================================================================
[   96.974297] BUG: KASAN: slab-out-of-bounds in kmalloc_pagealloc_oob_right+0xc8/0xe0 [test_kasan]
[   96.976085] Write of size 1 at addr ffff80001c0be00a by task insmod/569
[   97.009774] ==================================================================
[   97.013784] kasan test: kmalloc_pagealloc_uaf kmalloc pagealloc allocation: use-after-free
[   97.015457] ==================================================================
[   97.016937] BUG: KASAN: use-after-free in kmalloc_pagealloc_uaf+0xc0/0xd0 [test_kasan]
[   97.018264] Write of size 1 at addr ffff80001c0bc000 by task insmod/569
[   97.021236]
[   97.058048] ==================================================================
[   97.062012] kasan test: kmalloc_pagealloc_invalid_free kmalloc pagealloc allocation: invalid-free
[   97.063042] ==================================================================
[   97.064403] BUG: KASAN: double-free or invalid-free in kmalloc_pagealloc_invalid_free+0x78/0x80 [test_kasan]
[   97.563543] ==================================================================
[   97.565871] kasan test: kmalloc_oob_memset_16 out-of-bounds in memset16
[   97.566822] ==================================================================
[   97.567581] BUG: KASAN: slab-out-of-bounds in kmalloc_oob_memset_16+0x80/0x90 [test_kasan]
[   97.568841] Write of size 16 at addr ffff80001d4bc081 by task insmod/569
[   97.618222] ==================================================================
[   97.620924] kasan test: kmalloc_uaf use-after-free
[   97.622887] ==================================================================
[   97.624507] BUG: KASAN: use-after-free in kmalloc_uaf+0xcc/0xe0 [test_kasan]
[   97.626212] Write of size 1 at addr ffff80001d4bc588 by task insmod/569
[   97.627438]
[   97.672285] ==================================================================
[   97.673872] kasan test: kmalloc_uaf_memset use-after-free in memset
[   97.674501] ==================================================================
[   97.675046] BUG: KASAN: use-after-free in kmalloc_uaf_memset+0x84/0x8c [test_kasan]
[   97.675620] Write of size 33 at addr ffff80001d4bf500 by task insmod/569
[   97.676672] ==================================================================
[   98.023758] kasan test: memcg_accounted_kmem_cache allocate memcg accounted object
[   98.674484] kasan test: kasan_stack_oob out-of-bounds on stack
[   98.675223] ==================================================================
[   98.678286] BUG: KASAN: stack-out-of-bounds in kasan_stack_oob+0xf8/0x144 [test_kasan]
[   98.679094] Read of size 1 at addr ffff8000197df39a by task insmod/569
[   98.679522] [   98.735804]
[   98.867912] ==================================================================
[   98.870386] kasan test: copy_user_test out-of-bounds in copy_from_user()
[   98.871485] ==================================================================
[   98.872960] BUG: KASAN: slab-out-of-bounds in copy_user_test+0x28c/0x8d8 [test_kasan]
[   98.874518] Write of size 11 at addr ffff80001c007000 by task insmod/569
[   98.875381][   98.932274] ==================================================================
[   98.934343] kasan test: copy_user_test out-of-bounds in copy_to_user()
[   98.935494] ==================================================================
[   98.936524] BUG: KASAN: slab-out-of-bounds in copy_user_test+0x500/0x8d8 [test_kasan]
[   98.937066] Read of size 11 at addr ffff80001c007000 by task insmod/569
[   98.938636][   98.993046]
[   99.049702] ==================================================================
[   99.051988] kasan test: copy_user_test out-of-bounds in __copy_to_user()
[   99.052711] ==================================================================
[   99.054365] BUG: KASAN: slab-out-of-bounds in copy_user_test+0x67c/0x8d8 [test_kasan]
[   99.056035] Read of size 11 at addr ffff80001c007000 by task insmod/569
[   99.057768]
[   99.297345] ==================================================================
[   99.303983] kasan test: use_after_scope_test use-after-scope on int
[   99.305426] kasan test: use_after_scope_test use-after-scope on array
[   99.319414] kasan test: kmem_cache_double_free double-free on heap object
[   99.321611] ==================================================================
[   99.322758] BUG: KASAN: double-free or invalid-free in kmem_cache_double_free+0xc4/0xd4 [test_kasan]
[   99.324030]
[   99.718299] ==================================================================
[   99.719678] kasan test: kasan_memcmp out-of-bounds in memcmp
[   99.721512] ==================================================================
[   99.722675] BUG: KASAN: slab-out-of-bounds in memcmp+0x7c/0x138
[   99.723387] Read of size 1 at addr ffff80001d62b798 by task insmod/569
[   99.723956]
[   99.808130] ==================================================================
[   99.810907] kasan test: kasan_strings use-after-free in strchr
[   99.812133] ==================================================================
[   99.812909] BUG: KASAN: use-after-free in strchr+0xd0/0xf4
[   99.813602] Read of size 1 at addr ffff80001d629c10 by task insmod/569
[   99.814186]
[  100.231048] ==================================================================
[  100.232472] kasan test: kasan_strings use-after-free in strncmp
[  100.235615] ==================================================================
[  100.241922] BUG: KASAN: use-after-free in strncmp+0x74/0x148
[  100.243947] Read of size 1 at addr ffff80001d629c10 by task insmod/569
[  100.244851]
[  100.293083]  ffff80001d629c80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  100.293951]  ffff80001d629d00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc

Linux内核中使用内存检测相关推荐

  1. Linux内核中的内存屏障(转)

    转自:http://www.linuxidc.com/Linux/2011-10/44623.htm 前言 之前读了关于顺序一致性和缓存一致性讨论的文章,感觉豁然开朗.对linux内核中出现的种种同步 ...

  2. Linux内核中常见内存分配函数

    1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...

  3. KSM(Kernel Samepage Merging) 剖析:Linux 内核中的内存去耦合

    简介:作为一个系统管理程序(hypervisor),Linux® 有几个创新,2.6.32 内核中一个有趣的变化是 KSM(Kernel Samepage Merging)  允许这个系统管理程序通过 ...

  4. Linux内核中的内存管理(图例解析)

    一 ,内核管理内存的方式 (1)内核把物理页作为内存管理的基本单位,内存管理单元通常以页为单位进行处理,所以,从虚拟内存角度来看,页就是最小单位. 大多数32位系统支持4kb的页,64位系统支持8kb ...

  5. [十月往昔]——Linux内核中的内存管理浅谈

    为什么要叫做"十月往昔"呢,是为了纪念我的原博客,http://www.casual0402.cn. 不知道为什么,突然想来一个新的开始--而那个博客存活至今刚好十个月,也有十个月 ...

  6. Linux内核中Lockdep死锁检测

    目录 一.死锁 检测技术:Lockdep 二.Lockdep 内核配置 输出的报告 三.死锁检测实例 1.试验一:隐藏的加锁 2.试验二:AB-BA锁 四.锁统计 五.lockdep编程的建议 六.l ...

  7. Linux内核中内存分配函数

    1.原理说明 Linux内核 中采 用了一种同时适用于32位和64位系统的内 存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系 统中,用到了四级页表,如图2-1所示.四级页表分别为 ...

  8. 红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理)丨epoll丨c/c++linux服务器开发丨linux后台开发

    红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理) 视频讲解如下: 红黑树在linux内核中的应用场景(红黑树,进程管理CFS,内存管理)丨epoll丨c/c++linux服务器开 ...

  9. Linux内核中内存管理相关配置项的详细解析3

    接前一篇文章:Linux内核中内存管理相关配置项的详细解析2 5. 2:1 compression allocator (zbud) 对应配置变量为:CONFIG_ZBUD. 此项默认为选中(如果前一 ...

最新文章

  1. Qt下一行代码就可以使用的稳定易用的日志log类
  2. 2015 年最受 Linux 爱好者欢迎的软硬件大盘点
  3. 什么是npm package
  4. Pytorch 自定义激活函数前向与反向传播 sigmoid
  5. C++模板类嵌套类内部类局部类的区别
  6. AirPods 3换新外形啦!还增加了防水和主动降噪功能!
  7. 如何修改游戏服务器端的数据,如何修改网络游戏服务器数据
  8. ffmpeg实现各种视频特效
  9. window MFC桌面下雪程序
  10. C语言入门检验身份证号码最后一位
  11. 漫谈程序员系列:看看你离优秀有多远
  12. 硬件故障检测以及故障模拟触发工具
  13. Python之 函数笔记
  14. 微信小程序 图片验证码展示
  15. java 环境变量 locale_locale的设定及其LANG、LC_ALL、LANGUAGE环境变量的区别 zz
  16. arm 协处理器cp14 cp15
  17. BLDC-坐标变换(Clark,Park,反Park)
  18. [XSY 3147]子集计数
  19. SQL2005安装(Server 2003)
  20. delphi 控件大全

热门文章

  1. Python str.isalnum
  2. RESTFul接口规范
  3. 乾坤-vue应用实例
  4. 手把手带你设计接口自动化测试用例:建立数据库实例和测试用例表
  5. rust砖墙_建筑、结构专业图纸说明_All(中英对照)
  6. 小鸣单车:拖欠用户押金未退,却在今天发布债公告这是什么情况?
  7. openCV学习笔记(5):使用sprintf函数实现在窗口连续显示同一文件夹下的图片
  8. python十大框架_python 十大web框架排名总结
  9. PHP八字强弱计算,八字日主强弱衰旺量化计算方法汇总(一
  10. Citus分布式方案(七)- 集群管理