将32位指针转换为64位指针? (导致copy_from_user失败)

时间:2014-02-25 23:27:00

标签: c linux pointers casting linux-kernel

我正在使用linux内核,我有一个尝试将ioctl发送到内核的usermode程序。我觉得ioctl很好,但是我的copy_from_user失败了,大概是因为指针错了。

用户模式程序编译为32位,而内核以64位运行。

用户模式:

user_test_input *input_test = (user_test_input*)malloc(sizeof(user_test_input));
// container->ptr is defined as uint64_t, even though this is 32-bit user mode
container->ptr = (uint64_t)input_test;
printf("ptr: 0x%016X", container->ptr);

//send ioctl(fd, COMMAND, container);

输出: 0x00000000F82DF038

内核模式:

test_input *kernel_input_data = (test_input *)kmalloc(sizeof(test_input), GFP_KERNEL);
copy_from_user(kernel_input_data, (void __user*)data->ptr, sizeof(test_input));

我看到的数据 - > ptr的值是: 0xfffffffff82df038

我做错了吗?我的copy_from_user失败了。我当时认为它与0x00000000XXXXXXXX vs 0xFFFFFFFFXXXXXXXX有关。

谢谢!

1 个答案:

答案 0 :(得分:0)

您正在遇到签名问题。因为0xF82DF038设置了最高位,所以它被认为是负数,当它从32位值升级到64位值时,重复该最高位以填充新空间,所以最后你得到0xfffffffff82df038

为避免这种情况,请使用无符号数据类型。

考虑container->ptrdata->ptr的类型。