繁体   English   中英

Linux设备驱动程序:将字符串从内核复制到UserSpace

[英]Linux Device Driver: Copying String from Kernel to UserSpace

我有这样一个结构:

typedef struct
{
    char* BUFFER;
    int Size;
}DataTransfer;

在我的IOCTL函数中,我尝试填充该结构并传递给用户空间:

case CHAR_DRIVER_IOCQREAD:
    printk(KERN_INFO "In CHAR_DRIVER_IOCQREAD");
    dataTransfer.BUFFER = kmalloc(strlen_user("Hello") +1, GFP_KERNEL);
    dataTransfer.Size = strlen_user("Hello") +1;
    error_count = copy_to_user((DataTransfer*) arg, &dataTransfer, sizeof(dataTransfer) );

在用户空间中,我尝试这样接收结构:

DataTransfer dataTransfer;
if(ioctl(fd, CHAR_DRIVER_IOCQREAD, &dataTransfer) < 0)
{
    perror("ERROR in ioctl CHAR_DRIVER_IOCQREAD");
}
else
{
    printf("Kernel returned size %d \n", dataTransfer.Size);
    printf("Kernel returned string %s \n", dataTransfer.BUFFER);
}

正确的做法是什么?

这里有几个问题。 首先,将结构复制到用户空间,但不复制它指向的字符串。 该结构将指向您分配的用户空间无法访问的内核内存。 其次,您正在分配内核内存,但实际上并未在其中放置任何内容。

一种方法是让用户空间为IOCtl分配内存以将字符串写入其中,然后将类似于DataTransfer的结构传递给IOCtl以描述其分配的内存。 内核将使用copy_from_user从用户内存中读取该结构,然后,如果分配的缓冲区足够容纳该字符串,请使用copy_to_user在该结构内部传递给它的地址上将其写入那里。

例如(内核侧,仅草图):

case CHAR_DRIVER_IOCQREAD:
    DataTransfer dataTransfer;
    if (copy_from_user(&dataTransfer, arg, sizeof(dataTransfer)))
        return -EFAULT;
    if (dataTransfer.Size < strlen(myString) + 1)
        return -ENOMEM;
    if (copy_to_user(dataTransfer.BUFFER, myString, strlen(myString) + 1))
        return -EFAULT;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM