Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

copy_to_user() and copy_from_user() for basic data type

I'm writing a linux kernel driver and for every function that sends data up to userspace or reads data from userspace, I am using copy_to_user() and copy_from_user(). My question is: do I need to use these calls if I am just copying a basic data type such as a u32 or an int?

like image 567
user1747719 Avatar asked Apr 01 '15 17:04

user1747719


2 Answers

If the function receives a pointer to user-space data, you have to use copy_from_user() to copy the pointed-to data from user space into kernel space (and vice versa).

Note that the pointer value itself is passed by value (like all C parameters), so you don't have to do a copy_from_user() to obtain the pointer value before you can copy_from_user() the data it points to.

Numeric arguments work the same way as pointer arguments; in C terms, they're both scalars. You don't have to use copy_from_user() to copy the value of the parameter; that's already been copied. You only have to use it to copy data that's pointed to by a passed pointer.

So if you have a parameter of type int, you can use it directly. If your parameter points to an int, then the int object will be in user space, and you need to use copy_to_user to copy the value of that object into kernel space.

like image 189
Keith Thompson Avatar answered Nov 10 '22 00:11

Keith Thompson


When a user passes data to kernel space, this data can be split on several pages, and these pages can be even in swapped out memory. In these cases, you'll have to wait for the kernel to swap in the page and get access to the page where the data is in. In the case of elementary data types (like int or pointers) it is also true that some architectures (notably x86 intel) don't force the user to align the data so even an integer can be split around a page border. You can have access to the first part of you integer, but to wait for the second to get swapped in by the memory manager before the whole thing is accessed.

You can save some roundtrips by putting all user data in a structure whose pointer is passed to the kernel. You can copy_from_user it as a block and save accesses (and running into the risk of being blocked several times)

So, and as a conclusion, use the functions even for basic types, as there are plenty of them. Don't assume anything about where the user data can be when running in kernel mode. You have access to it, but the kernel virtual addresses of user data have nothing to do with the virtual addresses seen in user mode.

like image 28
Luis Colorado Avatar answered Nov 10 '22 00:11

Luis Colorado