I'm trying to define a system call that modifies the character buffer passed to it. Specifically, something like this:
...
asmlinkage int sys_mycall( char __user *buff, int len )
{
char tmp[1000];
copy_from_user(tmp, buff, len);
/* change tmp here */
copy_to_user( buff, &tmp, len );
}
Here, copy_to_user returns -1, and the buffer from the calling program is unchanged. What's happening?
The copy_from_user function copies a block of data from user space into a kernel buffer. it accepts a destination buffer (in kernel space), a source buffer (from user space), and a length defined in bytes.
You can use the copy_from_user() and copy_to_user() functions to move data between kernel space and user space.
Returns number of bytes that could not be copied. On success, this will be zero. If some data could not be copied, this function will pad the copied data to the requested size using zero bytes.
__user is used to mark a pointer as userspace, as in, to indicate that the pointer exists in userspace and that it should not be dereferenced.
Remeber that tmp is already a pointer! Correct way to do it:
copy_to_user( buff, tmp, len );
That looks OK. It's possible that the buffer that userspace passed is mapped read-only - for example if it's in the text segment (eg. a string literal). By the way, this is probably what you want:
return copy_to_user(buff, &tmp, len) ? -EFAULT : 0;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With