我正在使用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有关。
谢谢!
答案 0 :(得分:0)
您正在遇到签名问题。因为0xF82DF038
设置了最高位,所以它被认为是负数,当它从32位值升级到64位值时,重复该最高位以填充新空间,所以最后你得到0xfffffffff82df038
。
为避免这种情况,请使用无符号数据类型。
考虑container->ptr
和data->ptr
的类型。