Ubuntu 20.04 LKM Rootkit插入时内核崩溃问题求助
内核崩溃原因及修复方案
你的update_hex函数存在多处内存安全问题,直接触发内核崩溃,具体问题和修复方案如下:
核心问题点
未初始化目标字符串
kmalloc分配的内存是未初始化的随机值,strcat要求目标字符串以\0结尾才能定位拼接起始位置。未初始化的number->hex会让strcat从随机内存地址查找\0,触发非法内存访问。栈缓冲区溢出
temp[8]的大小不足以容纳uint64_t的十六进制字符串:一个64位无符号整数的十六进制最多需要16个字符(比如0xffffffffffffffff),加上终止符\0需要17字节。temp[8]会导致sprintf写入超出栈缓冲区范围,破坏内核栈结构,直接引发崩溃。循环条件与内存大小计算错误
- 循环条件
i < number->size/64逻辑混乱:如果size是number数组的总字节数,正确的元素个数应为number->size / sizeof(uint64_t)(即size/8);如果size是总位数,才是size/64。错误的循环条件要么导致拼接不完整,要么越界访问number->number数组。 kmalloc分配的number->size字节空间完全不足以存储所有十六进制字符:每个uint64_t需要16个字符,总长度应为「元素个数×16 + 1」(加1是为了存储终止符\0)。
修复后的代码
#include <linux/string.h> #include <linux/slab.h> int update_hex(big_int_t *number) { // 计算所需内存:每个uint64_t对应16个十六进制字符,加1个终止符 int elem_count = number->size / sizeof(uint64_t); int hex_buf_size = elem_count * 16 + 1; // 释放旧内存 kfree(number->hex); // 用kzalloc分配并清零内存,确保初始为空字符串 number->hex = kzalloc(hex_buf_size, GFP_KERNEL); if (!number->hex) { printk(KERN_ERR "big_int: failed to allocate hex buffer\n"); return -ENOMEM; } for (int i = 0; i < elem_count; i++) { char temp[17]; // 足够容纳16个十六进制字符+终止符 // 用snprintf避免缓冲区溢出 snprintf(temp, sizeof(temp), "%llx", number->number[i]); // 用strlcat安全拼接,防止越界写入 strlcat(number->hex, temp, hex_buf_size); } return 0; }
额外注意事项
- 确保
big_int_t的size字段表示number数组的总字节数,如果size是总位数,需将elem_count改为number->size / 64。 - 内核中打印日志建议使用
KERN_*宏指定级别(如KERN_INFO、KERN_ERR),便于日志分类。 - 内核空间中优先使用
snprintf、strlcat这类带长度检查的函数,避免裸用sprintf、strcat引发内存安全问题。
内容的提问来源于stack exchange,提问作者user21382175
相关产品推荐
相关产品推荐

