问题
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