这是我的实验室任务:我是内核空间的初学者。
我做了一个简单的系统调用实现,它按预期工作。但是,我想更进一步,研究向我的系统调用提供不正确的数据,看看它是否能处理它。
例如,我在系统调用中使用了 access_ok。我真的想传递一个无效的用户空间指针,看看我是否在系统调用中正确使用了 access_ok。
这个怎么做?我看到了,如果我传递内核空间指针,access_ok 将失败。但是我该如何编写驱动程序来做到这一点呢?
这是我的实验室任务:我是内核空间的初学者。
我做了一个简单的系统调用实现,它按预期工作。但是,我想更进一步,研究向我的系统调用提供不正确的数据,看看它是否能处理它。
例如,我在系统调用中使用了 access_ok。我真的想传递一个无效的用户空间指针,看看我是否在系统调用中正确使用了 access_ok。
这个怎么做?我看到了,如果我传递内核空间指针,access_ok 将失败。但是我该如何编写驱动程序来做到这一点呢?
当您尝试将无效的用户空间指针传递给宏access_ok(type,addr,size); .
所以它只是检查提供的指针是否不在内核空间区域中,如果它在内核空间内存中,那么它将返回零(0),否则它将返回 true,因此您可以通过这种方式检查您想要的结果。如果您是可以接受在内核内存之外提供任何地址(提供的地址可能不是调用此系统调用的进程的地址空间,在这种情况下,作为 VERIFY_READ 或 VERIFY_WRITE 提供的类型将决定做什么)。
从 access_ok() 的手册页参考http://mirror.linux.org.au/linux-mandocs/2.6.12.6/access_ok.html。请注意,根据架构,此函数可能只是检查指针是否在用户空间范围内 - 调用此函数后,内存访问函数可能仍会返回 -EFAULT
如果你想将指针传递给内核,那么你可以这样做 1-> 定义一个包含指针地址的结构。2-> 在内核模块或驱动程序中添加相同的结构。所以内核和用户知道这个结构。3-> 在系统调用中添加一个参数为char __user var
. 4->在定义结构的用户空间中创建一个结构变量,并在您在用户空间应用程序中调用时将其传递给系统调用。5-> 在为您的系统调用定义代码的内核模块或驱动程序中,创建一个与您在用户空间中使用的结构相同的结构变量。现在做任何你想做的事。
`
struct new_struct
{
void *p; //set this pointer which you want to send...
};
//from user-application...
int main()
{
....
struct new_struct req_kernel;
your_system_call_function(...,(void *)&req_kernel,...);
}
//this is inside your kernel...
your_system_call(...,char __user optval,...)
{
.....
struct new_struct req;
if (copy_from_user(&req, optval, sizeof(req)))
return -EFAULT;
//now you have the address or pointer which you want in kernel with struct req...
}
`