为什么在ioctl命令中从用户空间复制结构失败?

为什么在ioctl命令中从用户空间复制结构失败?,c,linux-kernel,kernel,kernel-module,ioctl,C,Linux Kernel,Kernel,Kernel Module,Ioctl,我正在开发一个设备驱动程序,需要使用IOCTL。不幸的是,我无法从用户空间复制结构。以下是简化的代码,删除了错误处理: 结构 应用 内核模块 致以最良好的祝愿, Oliver Hanappi您的用户呼叫复制错误。它不返回复制的字节数,而是返回未复制的字节数。你想要的是 if (copy_from_user(...) != 0) return -EFAULT; 您可以跳过代码段中ret的赋值。copy\u from\u user返回无法复制的字节数。因此,您应该期望0成功,而不是

我正在开发一个设备驱动程序,需要使用IOCTL。不幸的是,我无法从用户空间复制结构。以下是简化的代码,删除了错误处理:

结构

应用

内核模块

致以最良好的祝愿, Oliver Hanappi

您的用户呼叫复制错误。它不返回复制的字节数,而是返回未复制的字节数。你想要的是

if (copy_from_user(...) != 0)
        return -EFAULT;

您可以跳过代码段中ret的赋值。

copy\u from\u user返回无法复制的字节数。因此,您应该期望0成功,而不是sizeofstruct secvault\u createoptions。

您应该将语句修改为

  if (copy_from_user(&creationOptions, (void*)arg, sizeof(struct secvault_createoptions)) != 0)
            {
                /* Always this branch gets executed */
                printk(KERN_ALERT "Copying secure vault creation options from user space failed.\n");
                returnCode = -EFAULT;
                break;
            }
因为从用户复制用户在成功完成后总是返回0


有关详细信息,请参阅。

通常的习惯用法是如果从用户处复制。。。返回-默认值;
int control_device_ioctl(struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg)
{
    struct secvault_createoptions creationOptions;
    int returnCode;

    switch (cmd)
    {
        case SECVAULT_IOCTL_CREATE:
            if (copy_from_user(&creationOptions, (void*)arg, sizeof(struct secvault_createoptions)) != sizeof(struct secvault_createoptions))
            {
                /* Always this branch gets executed */
                printk(KERN_ALERT "Copying secure vault creation options from user space failed.\n");
                returnCode = -EFAULT;
                break;
            }
            printk(KERN_ALERT "2 IOCTL create request on control device received: secvaultId = %d, dataSize = %ld.\n",
                creationOptions.secvaultId, creationOptions.dataSize);

            returnCode = createDataDevice(&creationOptions);
            break;
    }
    return returnCode;
}
if (copy_from_user(...) != 0)
        return -EFAULT;
  if (copy_from_user(&creationOptions, (void*)arg, sizeof(struct secvault_createoptions)) != 0)
            {
                /* Always this branch gets executed */
                printk(KERN_ALERT "Copying secure vault creation options from user space failed.\n");
                returnCode = -EFAULT;
                break;
            }