'simple_read_from_buffer/simple_write_to_buffer vs. copy_to_user/copy_from_user

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 1:[1]

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:

  1. Use copy_{from,to}_user if you want to control the exact behavior of your function.
  2. 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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1