Reputation: 31
Here is the structure I get :
struct my_struct {
int size;
int *buffer;
};
Now, I want to copy a variable from user space to kernel space using copy_from_user
but it does not seem to work.
What I do is this:
In user space I declare a variable struct my_struct data
which I in initialize and pass it onto an ioctl, and in the kernel I call copy_from_user(&mydataInkernel, arg, sizeof(mydataInkernel))
after which I allocate the right memory for the pointer and call again copy_from_user(mydataInkernel.buffer, arg + 4, mydataInkernel.size)
. I don't know what I am doing wrong but it is not working.
Does the first copy also copy all the data pointed to by mydataInkernel.buffer ?
Is there a way to do this simply using copy_from_user
?
UPDATE 1: For the size of a pointer on my architecture, it is indeed 8 bytes (x86_64). To be more clear I'm writing a device driver and this is for the need to get a data from the user space to kernel space using an ioctl. So here is the code I try to do to get the buffer:
ret_val = copy_from_user(dma_info, (ioctl_dma *)arg, sizeof(dma_info));
if (ret_val)
printk(KERN_WARNING "COPY_FROM_USER failed !");
else
ret_val = copy_from_user(dma_info->buffer, (ioctl_dma *)arg->buffer, dma_info->taille);
if (ret_val)
printk(KERN_WARNING "COPY_FROM_USER failed !");
else
{
//Do the treatment
}
And here is the prototype of the ioctl function:
long pci_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
So I don't think my second copy_from_user is correct even after the cast.
Nb: dma_info is of type the struct defined above.
Upvotes: 2
Views: 2259
Reputation:
if you have the initial struct copied in, why can't you just copy_from(arg->buffer, ....) instead of playing games like arg + 4?
since no code was shown it is hard to say for sure, but most likely the problem is in the above. offset of 'buffer' is not 4 bytes. It is 8 due to alignment requirements, assuming x86_64.
to make it clear:
Upvotes: 3