You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux内核模块调用strsep()分割字符串触发死机问题咨询

代码存在的核心问题

1. 字符串终止符补全逻辑完全错误

你当前补\0的代码存在本质问题:

  • 调用strlen(decrypt)的前提是decrypt已经是合法的C字符串(自带终止符),但你之前往decrypt写入密钥内容时没有主动加终止符,strlen会越界扫描数组外的内存,计算出的长度完全不可靠,甚至直接触发缺页异常导致死机。
  • 硬编码2361这个长度值没有任何通用性,代入公式decrypt[lenght - N]实际等价于decrypt[2361] = '\0',不管实际内容多长都固定在2361位写终止符,要么截断有效内容,要么终止符位置不对,后续字符串操作还是会越界。

2. strsep()返回值未判空直接使用,触发空指针引用

这是你模块死机的直接原因:

  • 你只在进入while循环时判断了s3 != NULL,但循环内连续三次调用strsep()完全没有检查返回值。strsep()扫描到字符串末尾时会返回NULL,并把传入的指针设为NULL,后续对NULL指针调用strlen()会直接触发内核态空指针panic。
  • 单步调试时内存布局、执行时序和正常运行不同,刚好没触发到异常路径,所以看起来运行正常,正常加载运行时走到字符串末尾就会直接崩溃。

3. 分割逻辑鲁棒性不足

你默认每一行严格遵循X = Y\n、中间只有单个空格、没有空行的格式,只要实际内容里多一个空格、末尾多一个换行、某行格式有偏差,三次strsep()调用拿到的内容就完全不符合预期,甚至返回空指针。


内核中可用的线程安全字符串分割方案

strsep()本身就是Linux内核推荐的线程安全、可重入的字符串分割函数,它不依赖任何全局静态变量,只要多个线程不操作同一个字符串缓冲区,就不会有竞态问题。

注意:绝对不要使用内核的strtok()函数,它内部维护了静态状态指针,不可重入,多线程/嵌套调用场景会直接出错。

如果不想手动处理分割逻辑,针对你这种固定格式的键值对行,也可以搭配内核自带的strim()(去除字符串首尾空白字符)简化逻辑,参考修正后的代码:

// 注意:写入decrypt时一定要记录实际写入的字节数,存在decrypt_len变量中
// 不要用strlen计算未终止的字符串长度!
if (decrypt_len >= KEY_SIZE)
    decrypt_len = KEY_SIZE - 1; // 预留终止符位置,防止数组越界
decrypt[decrypt_len] = '\0'; // 正确补终止符

char *cur = decrypt;
char *line, *key, *val;

while (cur != NULL) {
    line = strsep(&cur, "\n");
    if (!line || *line == '\0') // 跳过空行、末尾无效内容
        continue;

    key = strsep(&line, "=");
    if (!key)
        continue;
    strim(key); // 去除key首尾的空格、制表符

    val = line;
    if (!val)
        continue;
    while (*val && isspace(*val)) // 跳过值前面的空白
        val++;

    // 此时key就是N/E/D,val就是对应的十六进制值
    size_t val_len = strlen(val);
    printk(KERN_DEBUG "key: %s, value len: %zu, content: %s\n", key, val_len, val);
}

如果你的行格式完全固定,也可以直接用sscanf()按格式匹配读取,不需要手动分割,但要注意指定缓冲区宽度防止溢出。

内容的提问来源于stack exchange,提问作者user45698746

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:18:20