casting and the copy_to_user macro

自闭症网瘾萝莉.ら 提交于 2019-12-12 00:35:30

问题


I need to copy curr_task->pid, a pid_t in kernel space, to a structure's field in user space that has space for a long. Since this is a widening conversion, I'm not expecting any issues.

However, I'm getting an annoying compiler warning (copy_long_to_user is for all intents and purposes the same as copy_to_user):

cs300/process_ancestors.c:31:3: warning: passing argument 2 of ‘copy_long_to_user’ from incompatible pointer type [enabled by default]
   if(copy_long_to_user(&info_array[num_filled_kernel].pid, &curr_task->pid)) {    
   ^
cs300/process_ancestors.c:9:5: note: expected ‘long int *’ but argument is of type ‘pid_t *’

Is this warning something I can safely ignore (will the compiler do the cast for me)? If I need to cast curr_task->pid to a long explicitly, how can I do that in the context of using copy_to_user? My guess would be that it's something like:(copy_long_to_user(&info_array[num_filled_kernel].pid, &((long)curr_task->pid)))


回答1:


In Linux kernel, the type of pid_t is equals to int, so the compiler warns you that int* cannot cast to long int*. I don't know how do you realize your copy_long_to_user function, if you write like this, you may get a wrong result. copy_long_to_user(long int* dest, long int* src){ copy_to_user(dest, src, sizeof(long int)); ...... } because sizeof(long) >= sizeof(int), if sizeof(long) > sizeof(int), support that sizeof(long) == 8, and sizeof(int) always 4, you will get a wrong result, because current_task->pid just occupy the 4 byte of dest, but copy_to_user(dest, src, sizeof(long int)) must copy 8 byte to dest, so the 4 bytes follow the current->pid are copied to dest, so dest can not equal to current->pid. so you'd better write a function named copy_pid_to_user and it codes like that: copy_pid_to_user(long int* dest, void* src){ copy_to_user(dest, src, sizeof(curent->pid)) ......




回答2:


You need a helper variable to do this correctly.

long curr_pid = curr_task->pid;
copy_long_to_user(&info_array[num_filled_kernel].pid, &curr_pid);

Taking the address of a helper variable is legal, address of a temporary (produced by the cast) isn't.



来源:https://stackoverflow.com/questions/36658773/casting-and-the-copy-to-user-macro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!