【问题标题】:copy data from kernel space to user space将数据从内核空间复制到用户空间
【发布时间】:2016-03-13 14:14:40
【问题描述】:

我正在尝试进行自定义系统调用。

我的系统调用有两个参数struct buffer **mybuffer & int size

它强制发生在**mybuffer 上的任何更改都应该反映在用户空间中,但它似乎不起作用。

所以我在其他地方看到我可以使用copy_to_user(void *dest, void *src, int size) 将数据从内核空间复制到用户空间。

在用户空间中,我有一个称为缓冲区的结构,该结构在系统调用中也出现相同的情况。

typedef struct buffer {
int n;
}buffer;

    int main(void)
   {
     buffer **buf = malloc(sizeof(buffer *));
     int i = 0
for(;i<8;i++)
buf[i] = malloc(sizeof(buffer));
    long int sys = systemcall(801,buf,8)
//print out buf 
   return 0;
   }

在系统调用中我有

asmlinkage long sys_something(buffer **buf,int size)
{
//allocate buffer same as it appears in int main
//fill buf with some data
for(i = 0; i<size,i++)
copy_to_user(buf[i],buf[i],sizeof(buffer));

我很确定我做错了什么。实际上如何将数据从内核空间复制到用户空间?

附:我正在使用 linux 内核 3.16.0

【问题讨论】:

  • destsrc 等于buf[i] 肯定是错误的。您要复制什么内核的数据?指向这些数据的指针应用作copy_to_user 的第二个参数。还要注意,因为第一个系统调用的参数实际上是一个指针数组,您需要使用copy_from_user 读取这些指向内核(临时)内存的指针,然后在@ 中使用来自该内核内存的指针987654332@电话。

标签: c linux linux-kernel system-calls


【解决方案1】:

函数copy_to_user用于将数据从内核地址空间复制到用户程序的地址空间。例如,将已分配kmalloc的缓冲区复制到用户提供的缓冲区中。

编辑:您的示例有点复杂,因为您将一组指针传递给系统调用。访问这些指针 您必须先使用copy_from_user 将数组buf 复制到内核空间。

因此,您的内核代码应如下所示:

asmlinkage long sys_something(buffer **buf, int size)
{
    /* Allocate buffers_in_kernel on stack just for demonstration.
     * These buffers would normally allocated by kmalloc.
     */
    buffer buffers_in_kernel[size];
    buffer *user_pointers[size]; 
    int i;
    unsigned long res;

    /* Fill buffers_in_kernel with some data */
    for (i = 0; i < size; i++)
        buffers_in_kernel[i].n = i;  /* just some example data */

    /* Get user pointers for access in kernel space. 
     * This is a shallow copy, so that, the entries in user_pointers 
     * still point to the user space.
     */
    res = copy_from_user(user_pointers, buf, sizeof(buffer *) * size);
    /* TODO: check result here */

    /* Now copy data to user space. */
    for (i = 0; i < size; i++) {
         res = copy_to_user(user_pointers[i], &buffers_in_kernel[i], sizeof(buffer));
         /* TODO: check result here */
    }
}

最后但并非最不重要的一点是,您的 main 函数中存在错误。在第一次malloc 调用中,它只为 1 个指针分配了足够的空间,而不是 8 个。应该是:

int main(void)
{
  const int size = 8;
  buffer **buf = malloc(sizeof(buffer *) * size);
  for(int i=0; i<size; i++) buf[i] = malloc(sizeof(buffer));
  long int sys = systemcall(801,buf,size)
  //print out buf 
  return 0;
}

【讨论】:

  • 顺便说一句 copy_to_user(void *dst, const void *src, const int size);无论如何谢谢:)你真的做得很好
  • 另外我需要指出我测试了我的系统调用,但没有实现copy_from_user() 宏并将数据复制到用户空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
相关资源
最近更新 更多