2

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!

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
62626368616e
  • 321
  • 3
  • 9

1 Answers1

3

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.
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128