copy_to_user 没有 return 预期的数据
copy_to_user does not return expected data
我的内核驱动程序中有一个 ioctl,它需要 return 读取一些数据。当我在用户空间中读回它时,它没有显示预期的结果。
用户空间片段:
typedef struct abc_T {
int size;
int addr;
int data[32];
} abc_T;
// Read
int abc_read(int addr, int size, int *data) {
abc_T abc = {};
int fd, retval;
abc.size = size;
abc.addr = addr;
fd = open("/dev/"ABC_DEV, O_RDWR);
if (fd >=0) {
retval = ioctl(fd, READ_ABC, &abc);
if (retval == 0)
memcpy(data, abc.data, size);
}
return retval;
}
内核:
static int ABC_ioctl(struct file * file, uint cmd, ulong arg)
{
ABC_T abc;
void __user * arg_ptr;
arg_ptr = (void *)arg;
int retval;
if (!access_ok(VERIFY_READ, arg_ptr, sizeof(ABC_T))) {
return -EACCES;
}
if (copy_from_user(&abc, arg_ptr,
sizeof(ABC_T)) != 0) {
return -EFAULT;
}
switch(cmd) {
case READ_ABC:
retval = read_func(&abc);
if (retval == 0) {
if (copy_to_user((void __user *)arg, &abc,
sizeof(ABC_T) != 0)) {
retval = -EFAULT;
} else {
retval = 0;
}
}
return retval;
}
我已经在 read_func
中打印了结果(即数据数组)并且可以看到读取的是预期值,但是在 copy_to_user 之后,当我在 data
中打印时用户空间,我看到全是零。
这个片段有什么问题吗?
你的 parens 正在拨打 copy_to_user
。我 认为 你的意思是测试 copy_to_user
的响应是否是 != 0
。相反,您将 sizeof(ABC_T) != 0
作为最后一个参数。由于 sizeof(ABC_T)
是 non-zero,您的呼叫最终是 copy_to_user((void __user *)arg, &abc, true)
。
修复您的 parens 并查看是否获得更好的结果:
if (copy_to_user((void __user *)arg, &abc, sizeof(ABC_T)) != 0) {
// ...
}
我的内核驱动程序中有一个 ioctl,它需要 return 读取一些数据。当我在用户空间中读回它时,它没有显示预期的结果。
用户空间片段:
typedef struct abc_T {
int size;
int addr;
int data[32];
} abc_T;
// Read
int abc_read(int addr, int size, int *data) {
abc_T abc = {};
int fd, retval;
abc.size = size;
abc.addr = addr;
fd = open("/dev/"ABC_DEV, O_RDWR);
if (fd >=0) {
retval = ioctl(fd, READ_ABC, &abc);
if (retval == 0)
memcpy(data, abc.data, size);
}
return retval;
}
内核:
static int ABC_ioctl(struct file * file, uint cmd, ulong arg)
{
ABC_T abc;
void __user * arg_ptr;
arg_ptr = (void *)arg;
int retval;
if (!access_ok(VERIFY_READ, arg_ptr, sizeof(ABC_T))) {
return -EACCES;
}
if (copy_from_user(&abc, arg_ptr,
sizeof(ABC_T)) != 0) {
return -EFAULT;
}
switch(cmd) {
case READ_ABC:
retval = read_func(&abc);
if (retval == 0) {
if (copy_to_user((void __user *)arg, &abc,
sizeof(ABC_T) != 0)) {
retval = -EFAULT;
} else {
retval = 0;
}
}
return retval;
}
我已经在 read_func
中打印了结果(即数据数组)并且可以看到读取的是预期值,但是在 copy_to_user 之后,当我在 data
中打印时用户空间,我看到全是零。
这个片段有什么问题吗?
你的 parens 正在拨打 copy_to_user
。我 认为 你的意思是测试 copy_to_user
的响应是否是 != 0
。相反,您将 sizeof(ABC_T) != 0
作为最后一个参数。由于 sizeof(ABC_T)
是 non-zero,您的呼叫最终是 copy_to_user((void __user *)arg, &abc, true)
。
修复您的 parens 并查看是否获得更好的结果:
if (copy_to_user((void __user *)arg, &abc, sizeof(ABC_T)) != 0) {
// ...
}