我正在开发设备驱动程序,需要使用IOCTL。不幸的是我无法从用户空间复制结构。这是代码(简化,错误处理已删除):
结构
struct secvault_createoptions {
int secvaultId;
long dataSize;
char key[SECVAULT_KEYSIZE];
};
应用
void createSecvault(int secvaultId)
{
struct secvault_createoptions creationOptions;
/* fill with data */
sendIoctlCommand(SECVAULT_IOCTL_CREATE, &creationOptions);
}
void sendIoctlCommand(int command, void *arg)
{
FILE *stream;
int fd, err;
stream = fopen(SECVAULT_DEV_CONTROL, "r");
fd = fileno(stream);
ioctl(fd, command, arg);
fclose(stream);
}
内核模块
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;
}
最诚挚的问候,
Oliver Hanappi
答案 0 :(得分:4)
您的copy_from_user
电话错误。它不返回复制的字节数,而是返回未复制的字节数。你想要的是
if (copy_from_user(...) != 0)
return -EFAULT;
(您可以跳过代码段中的ret
分配。)
答案 1 :(得分:3)
copy_from_user()
返回不复制的字节数。因此,您应该期望0
取得成功,而不是sizeof(struct secvault_createoptions)
。
答案 2 :(得分:0)
您应该将语句修改为
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;
}
因为copy_from_user
在成功完成后总是返回0。
请参阅to this了解详情。