我正在编写一个内核函数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?
答案 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仍在访问它时(通过缓存指针),它不会被释放。