如何将包含指针的结构从用户空间复制到内核

时间:2017-08-23 13:12:29

标签: c linux linux-kernel driver

这是我得到的结构:

struct my_struct {
    int size;
    int *buffer;
};

现在,我想使用copy_from_user将变量从用户空间复制到内核空间,但它似乎不起作用。 我这样做是:

在用户空间中,我声明了一个变量struct my_struct data,我将其初始化并将其传递给ioctl,在内核中我调用copy_from_user(&mydataInkernel, arg, sizeof(mydataInkernel))之后我为指针分配正确的内存并再次调用copy_from_user(mydataInkernel.buffer, arg + 4, mydataInkernel.size)。我不知道我做错了什么,但它不起作用。

第一个副本是否也会复制mydataInkernel.buffer指向的所有数据?

有没有办法简单地使用copy_from_user

更新1: 对于我的架构上指针的大小,它确实是8个字节(x86_64)。为了更清楚,我正在编写设备驱动程序,这是因为需要使用ioctl从用户空间获取数据到内核空间。所以这是我尝试获取缓冲区的代码:

     ret_val = copy_from_user(dma_info, (ioctl_dma *)arg, sizeof(dma_info));
     if (ret_val)
           printk(KERN_WARNING "COPY_FROM_USER failed !");
     else
           ret_val = copy_from_user(dma_info->buffer, (ioctl_dma *)arg->buffer, dma_info->taille);

     if (ret_val)
            printk(KERN_WARNING "COPY_FROM_USER failed !");
     else
     {
       //Do the treatment
     }

这是ioctl函数的原型:

long    pci_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);

所以我认为即使在演员表之后我的第二个copy_from_user也是正确的。

Nb:dma_info是上面定义的结构类型。

1 个答案:

答案 0 :(得分:3)

如果您复制了初始结构,为什么不能只使用copy_from(arg-> buffer,....)而不是像arg + 4那样玩游戏?

由于没有显示代码,因此很难确定,但很可能问题出在上面。 'buffer'的偏移量不是 4个字节。由于对齐要求,它是8,假设为x86_64。

说清楚:

  1. 从本地对象复制
  2. 验证缓冲区大小是否合理(例如,当您只需要千字节时,它的大小不是兆字节)
  3. 创建另一个本地对象。为缓冲区分配足够的内存并分配给本地对象
  4. 从第一步制作的副本中取出缓冲区的地址(例如localobj->缓冲区)并从中复制。