目录
实践原理
用户空间可用通过系统调用可以将一个或多个字符串数据传递给内核空间。对于
字符串参数,用户空间必须通过指针的方式传到内核空间,由于这样的方式导致
内核空间不能直接访问用户空间的数据,会导致内核非法访问。因此对于这种情况,
内核首先将用户空间的数据拷贝到内核空间,这样才能安全使用数据。内核也可以
将内核字符串数据传递给用户空间,此时也不能直接传,也需要通过安全的拷贝
操作才能完整任务。用户空间的系统调用部分传递的是一个指针,因此内核向
用户空间传递字符串时,可以使用安全的拷贝函数将字符串放置到用户空间指针
对应的位置。字符串相关的参数可以是一个字符串常量、字符数组、字符、字符
指针,字符串相关的结构体. 用户空间使用格式如下:
int main(void)
{
const char *strings = "Hello BiscuitOS";
char *buffer[128];
char ch = 'B';
char *ptr;
struct BiscuitOS_node node = {
.nr = 20,
};
int ret;
/* malloc */
ptr = (char *)malloc(128);
/*
* sys_hello_BiscuitOS: String paramenter
* kernel:
* SYSCALL_DEFINE5(hello_BiscuitOS,
* char, ch,
* char __user *, const_string,
* char __user *, string_array,
* char __user *, string_ptr,
* struct BiscuitOS_node __user *, string_struct);
*/
ret = syscall(__NR_hello_BiscuitOS,
ch,
strings,
buffer,
ptr,
&node);
return 0;
}
内核空间系统调用部分接受上面的参数时,可以使用如下格式:
SYSCALL_DEFINE5(hello_BiscuitOS,
char, ch,
char __user *, const_strings,
char __user *, string_array,
char __user *, string_ptr,
struct BiscuitOS_node __user *, string_struct)
{
....
}
从上面的定义可以出,只要是从用户空间传递的指针参数,都需要添加
“__user” 进行强制说明,这是内核检测机制使用的符号,不影响函数的实际
功能。从上述也看到不论是字符串常量,还是数据结构都需要指针方式传递,
只有字符不需要。对于系统调用传递多个整形参数的方法,开发者可以参考如下文档:
对于系统调用的返回值&#x