内核模式访问用户空间变量

时间:2012-10-10 12:01:49

标签: c linux memory-management linux-kernel

我正在编写一个内核函数foo,它将结构指针作为参数

void foo(struct struct1 *param)
{

    if(param!=NULL)
    {
        if(param->param1!=NULL)
        {
            if(param->param1->bool_value)
                Some code
        }
    }
    some code
}

此函数在进程上下文中运行。 我在上面的函数中遇到了崩溃。 if(param->param1->bool_value)。 这次崩溃是一次性崩溃,它再也没有发生过。

BADVA地址指向用户空间地址。这个地址是param1-> bool_value的地址吗?如果是这样,内核模式代码是否可以访问此地址进行读取而无需使用copy_from_user?

2 个答案:

答案 0 :(得分:2)

param->param1可能未经初始化或已被覆盖。

初始化struct1时,是否始终将其成员设置为NULL?如果不这样做,您的问题可能是使用未初始化的数据,并且处理相对简单。如果始终初始化为NULL,则其他一些代码可能会覆盖该成员;这将更难诊断。

答案 1 :(得分:1)

您是否确定(使用锁定)在测试和访问之间不会从您的下方修改结构?也许你可以使用

void foo(struct somestruct *const param)
{
    if (param) {
        struct otherstruct *const param1 = param->param1;

        if (param1 && param1->bool_value) {
            /* Do stuff */
        }
    }
}

请注意,C指定&&的短路逻辑,因此如果最内层测试中param1为NULL,则{strong} 将取消引用。 / p>

这种访问模式(没有最外层的param1)在Linux内核中非常常见。唯一需要注意的是,丢弃if (param)仍然必须受到某种锁的保护,这样当其他一些CPU仍在访问它时(通过缓存指针),它不会被释放。