Linux内核slub_debug内存错误检测实战

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

  1. 越界访问;
  2. 访问已经被释放的内存;
  3. 重复释放;
  4. 内存泄漏;
  5. 栈溢出;

slub_debug 工具

在 Linux 内核中,对于小块内存的分配,大量使用 slab/slub 分配器,slab/slub 分配器提供了一个内存检测功能,很方便在产品开发阶段进行内存检查。

1. 配置和编译内核

重新配置内核选项:

shell 复制代码
CONFIG_SLUB=y
CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y

重新编译内核并更新文件系统,注意文件系统安装需要 root 用户。

2. 添加 slub_debug 选项

在内核 commandline 中添加 slub_debug 字符串打开 slub_debug 功能。

追加:slub_debug=UFPZ

3. 编译 slabinfo 工具

该工具在 tools/vm/slabinfo.c 目录下。

4. 编写一个slub测试内核模块

slub_test.c

c 复制代码
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>

static char *buf;

static void create_slub_error(void)
{
	buf = kmalloc(32, GFP_KERNEL);
	if (buf) {
		memset(buf, 0x55, 130);
	}
}

static int __init my_test_init(void)
{
	printk("benshushu: my module init\n");
	create_slub_error();
	return 0;
}
static void __exit my_test_exit(void)
{
	printk("goodbye\n");
	kfree(buf);
}
MODULE_LICENSE("GPL");
module_init(my_test_init);
module_exit(my_test_exit);

Makefile

Makefile 复制代码
BASEINCLUDE ?= /lib/modules/$(shell uname -r)/build
slub-objs := slub_test.o 

obj-m	:=   slub.o
all : 
	$(MAKE) -C $(BASEINCLUDE) SUBDIRS=$(PWD) modules;

clean:
	$(MAKE) -C $(BASEINCLUDE) SUBDIRS=$(PWD) clean;
	rm -f *.ko;

make 编译内核模块 slub.ko

加载 slub 测试的内核模块:

运行 slabinfo 工具查看内存分配后的结果。

shell 复制代码
benshushu:~# /mnt/slabinfo -v
[  671.388357] =============================================================================
[  671.393422] BUG kmalloc-128 (Tainted: G           OE    ): Redzone overwritten
[  671.393965] -----------------------------------------------------------------------------
[  671.393965] 
[  671.394793] Disabling lock debugging due to kernel taint
[  671.396280] INFO: 0x000000002320e91b-0x00000000ec1b97ed. First byte 0x55 instead of 0xcc
[  671.398522] INFO: Allocated in create_slub_error+0x30/0x78 [slub] age=17178 cpu=1 pid=4380
[  671.400878] 	__slab_alloc+0x64/0xb0
[  671.401178] 	__kmalloc+0x560/0xf0c
[  671.401322] 	create_slub_error+0x30/0x78 [slub]
[  671.401661] 	0xffff0000098f5020
[  671.401766] 	do_one_initcall+0x494/0xad8
[  671.401865] 	do_init_module+0xb4/0x2f8
[  671.402251] 	load_module+0x940/0xc50
[  671.402364] 	__se_sys_finit_module+0x148/0x184
[  671.402484] 	__arm64_sys_finit_module+0x40/0x48
[  671.402606] 	__invoke_syscall+0x24/0x2c
[  671.402714] 	invoke_syscall+0xa4/0xd8
[  671.402878] 	el0_svc_common+0x100/0x1e4
[  671.403012] 	el0_svc_handler+0x418/0x444
[  671.403140] 	el0_svc+0x8/0xc
[  671.403291] INFO: Freed in free_modprobe_argv+0x28/0x40 age=17240 cpu=2 pid=589
[  671.403494] 	kfree+0xd84/0xdc8
[  671.403603] 	free_modprobe_argv+0x28/0x40
[  671.403732] 	call_usermodehelper_freeinfo+0x34/0x48
[  671.403849] 	call_usermodehelper_exec+0x2f4/0x33c
[  671.403956] 	call_modprobe+0x110/0x144
[  671.404046] 	__request_module+0x114c/0x11d0
[  671.404147] 	dev_load+0x80/0xc4
[  671.404228] 	dev_ioctl+0xc0/0x2e4
[  671.404314] 	sock_do_ioctl+0x730/0x96c
[  671.404403] 	sock_ioctl+0xa08/0xa5c
[  671.404490] 	vfs_ioctl+0x54/0x88
[  671.404571] 	do_vfs_ioctl+0x654/0x690
[  671.404661] 	ksys_ioctl+0xb4/0xec
[  671.404744] 	__se_sys_ioctl+0x4c/0x60
[  671.404963] 	__arm64_sys_ioctl+0x40/0x48
[  671.405089] 	__invoke_syscall+0x24/0x2c
[  671.405439] INFO: Slab 0x00000000d2d49de4 objects=25 used=25 fp=0x          (null) flags=0xffff00000010201
[  671.406208] INFO: Object 0x00000000c052bc65 @offset=14848 fp=0x          (null)
[  671.406208] 
[  671.407056] Redzone 000000000becbf55: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.407871] Redzone 00000000e6fc236b: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.408835] Redzone 00000000d0bb8058: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.409898] Redzone 000000008534dc07: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.410555] Redzone 000000009b9c45b6: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.411406] Redzone 00000000cbb54c78: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.412205] Redzone 00000000f95c8135: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.412996] Redzone 00000000bed0bde2: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc  ................
[  671.413825] Object 00000000c052bc65: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.414904] Object 0000000030ffab7e: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.415570] Object 00000000a609489d: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.416345] Object 00000000f66b0715: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.417812] Object 00000000afd73ae0: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.418196] Object 00000000b6209964: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.418477] Object 0000000070d14a83: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.418750] Object 00000000484fdfe2: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
[  671.419125] Redzone 000000002320e91b: 55 55 cc cc cc cc cc cc                          UU......
[  671.420348] Padding 00000000d774902d: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a  ZZZZZZZZZZZZZZZZ
[  671.421066] Padding 00000000148dff6b: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a  ZZZZZZZZZZZZZZZZ
[  671.421754] Padding 00000000a30f7e51: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a  ZZZZZZZZZZZZZZZZ
[  671.422500] Padding 00000000ce303c9a: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a  ZZZZZZZZZZZZZZZZ
[  671.423682] CPU: 0 PID: 4805 Comm: slabinfo Kdump: loaded Tainted: G    B      OE     5.0.0+ #2
[  671.424297] Hardware name: linux,dummy-virt (DT)
[  671.425095] Call trace:
[  671.425339]  dump_backtrace+0x0/0x528
[  671.425483]  show_stack+0x24/0x30
[  671.425650]  __dump_stack+0x20/0x2c
[  671.425990]  dump_stack+0x25c/0x388
[  671.426092]  print_trailer+0x340/0x34c
[  671.426184]  check_bytes_and_report+0x108/0x134
[  671.426286]  check_object+0xe8/0x4bc
[  671.426374]  validate_slab+0x2a0/0x30c
[  671.426466]  validate_slab_slab+0x264/0x418
[  671.426608]  validate_slab_node+0x390/0x6a0
[  671.426721]  validate_slab_cache+0xa8/0xf0
[  671.426828]  validate_store+0x3c/0x60
[  671.426924]  slab_attr_store+0x74/0x16c
[  671.427038]  sysfs_kf_write+0x80/0x88
[  671.427161]  kernfs_fop_write+0x3bc/0x448
[  671.427291]  __vfs_write+0x54/0x90
[  671.427407]  vfs_write+0x16c/0x2f4
[  671.427736]  ksys_write+0xb4/0x164
[  671.427892]  __se_sys_write+0x48/0x58
[  671.428019]  __arm64_sys_write+0x40/0x48
[  671.428317]  __invoke_syscall+0x24/0x2c
[  671.428463]  invoke_syscall+0xa4/0xd8
[  671.428571]  el0_svc_common+0x100/0x1e4
[  671.428674]  el0_svc_handler+0x418/0x444
[  671.428776]  el0_svc+0x8/0xc
[  671.429183] FIX kmalloc-128: Restoring 0x000000002320e91b-0x00000000ec1b97ed=0xcc
[  671.429183] 

上述 slabinfo 信息显示这是一个 Redzone overwritten 错误,内存访问越界了。

相关推荐
小白同学_C9 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖9 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
不做无法实现的梦~10 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
默|笙12 小时前
【Linux】fd_重定向本质
linux·运维·服务器
陈苏同学13 小时前
[已解决] Solving environment: failed with repodata from current_repodata.json (python其实已经被AutoDL装好了!)
linux·python·conda
“αβ”13 小时前
网络层协议 -- ICMP协议
linux·服务器·网络·网络协议·icmp·traceroute·ping
不爱学习的老登14 小时前
Windows客户端与Linux服务器配置ssh无密码登录
linux·服务器·windows
小王C语言15 小时前
进程状态和进程优先级
linux·运维·服务器
xlp666hub15 小时前
【字符设备驱动】:从基础到实战(下)
linux·面试
弹幕教练宇宙起源16 小时前
cmake文件介绍及用法
android·linux·c++