Issue
I recently wrote a module implementing these functions.
What is the difference between the two? From my understanding, the copy_..._user
functions are more secure. Please correct me if I'm mistaken.
Furthermore, is it a bad idea to mix the two functions in one program? For example, I used simple_read_from_buffer
in my misc dev read
function, and copy_from_user
in my write function.
Edit: I believe I've found the answer to my question from reading fs/libfs.c
(I wasn't aware that this was where the source code was located for these functions); from my understanding the simple_...()
functions are essentially a wrapper around the copy_...()
functions. I think it was appropriate in my case to use copy_from_user
for the misc device write function as I needed to validate that the input matched a specific string before returning it to the user buffer.
I will still leave this question open though in case someone has a better explanation or wants to correct me!
Solution
simple_read_from_buffer
and simple_write_to_buffer
are just convenience wrappers around copy_{to,from}_user
for when all you need to do is service a read
from userspace from a kernel buffer, or service a write
from userspace to a kernel buffer.
From my understanding, the
copy_..._user
functions are more secure.
Neither version is "more secure" than the other. Whether or not one might be more secure depends on the specific use case.
I would say that simple_{read,write}_...
could in general be more secure since they do all the appropriate checks for you before copying. If all you need to do is service a read/write to/from a kernel buffer, then using simple_{read,write}_...
is surely faster and less error-prone than manually checking and calling copy_{from,to}_user
.
Here's a good example where those functions would be useful:
#define SZ 1024
static char kernel_buf[SZ];
static ssize_t dummy_read(struct file *filp, char __user *user_buf, size_t n, loff_t *off)
{
return simple_read_from_buffer(user_buf, n, off, kernel_buf, SZ);
}
static ssize_t dummy_write(struct file *filp, char __user *user_buf, size_t n, loff_t *off)
{
return simple_write_to_buffer(kernel_buf, SZ, off, user_buf, n);
}
It's hard to tell what exactly you need without seeing your module's code, but I would say that you can either:
- Use
copy_{from,to}_user
if you want to control the exact behavior of your function. - Use a
return simple_{read,write}_...
if you don't need such fine-grained control and you are ok with just returning the standard values produced by those wrappers.
Answered By - Marco Bonelli Answer Checked By - Candace Johnson (WPSolving Volunteer)