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

树莓派5.10内核树内模块注入blkdev submit_bio函数崩溃求助

崩溃根因
  1. 你尝试修改的struct block_device_operations实例默认存放于内核.rodata只读段,无写权限,直接赋值触发页写异常,对应日志中的虚拟地址访问错误。
  2. 5.10版本后多队列块层架构下,大部分IO路径默认直接走blk_mq_submit_bio逻辑,不会调用块设备fops中的submit_bio回调,即使修改成功也无法拦截绝大多数IO请求。
可行的注入方案

方案1:修改request_queue的submit_bio回调(适配5.10+内核)

5.10版本struct request_queue中存在可拦截的submit_bio回调,修改该回调可覆盖绝大多数IO路径,修改前需先解除对应内存页的只读限制:

#include <linux/mm.h>
#include <linux/blkdev.h>
#include <linux/blk-mq.h>

// 先声明原始回调
static blk_qc_t (*orig_submit_bio)(struct bio *bio);

// 你的注入回调
static blk_qc_t injected_submit_bio(struct bio *bio)
{
    pr_emerg("intercepted bio: sector=%llu, dir=%d\n", bio->bi_iter.bi_sector, bio_data_dir(bio));
    return orig_submit_bio(bio);
}

// 注入逻辑
int inject_submit_bio(struct block_device *bdev)
{
    struct request_queue *q = bdev_get_queue(bdev);
    unsigned long addr;
    int ret;

    if (!q)
        return -ENODEV;

    orig_submit_bio = q->submit_bio;
    if (!orig_submit_bio)
        return -EINVAL;

    // 解除submit_bio字段所在页的只读限制
    addr = (unsigned long)&q->submit_bio;
    ret = set_memory_rw(PAGE_ALIGN_DOWN(addr), 1);
    if (ret)
        return ret;

    // 替换回调,替换过程可配合blk_freeze_queue/blk_unfreeze_queue保证SMP安全
    WRITE_ONCE(q->submit_bio, injected_submit_bio);

    // 可选:改完恢复页只读权限,提升安全性
    // set_memory_ro(PAGE_ALIGN_DOWN(addr), 1);

    return 0;
}

// 卸载时恢复回调
void restore_submit_bio(struct block_device *bdev)
{
    struct request_queue *q = bdev_get_queue(bdev);
    unsigned long addr;

    if (!q || !orig_submit_bio)
        return;

    addr = (unsigned long)&q->submit_bio;
    set_memory_rw(PAGE_ALIGN_DOWN(addr), 1);
    WRITE_ONCE(q->submit_bio, orig_submit_bio);
    // set_memory_ro(PAGE_ALIGN_DOWN(addr), 1);
}

注意:ARM架构下需确认内核开启CONFIG_SET_MEMORY_RW_RO配置,否则需手动修改页表属性。

方案2:使用Device Mapper封装(更稳定合规)

如果不需要侵入修改内核内置结构,可实现一个极简的DM target,将所有IO转发到后端块设备,在转发逻辑中完成自定义操作,该方案完全符合内核开发规范,无兼容性风险,适配所有5.0+内核版本。

注意事项
  • 回调替换过程需先冻结队列,避免并发IO触发未定义行为
  • 注入回调中不能随意修改bio的核心字段,除非你完全清楚块层处理逻辑
  • 模块卸载前必须恢复原始回调,否则卸载后会触发Oops

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:45:02