simple_read_from_buffer / simple_write_to_buffer против copy_to_user / copy_from_user - PullRequest
0 голосов
/ 19 июня 2020

Недавно я написал модуль, реализующий эти функции.

В чем разница между ними? Насколько я понимаю, функции copy_..._user более безопасны. Пожалуйста, поправьте меня, если я ошибаюсь.

Кроме того, не стоит ли смешивать две функции в одной программе? Например, я использовал simple_read_from_buffer в моей функции mis c dev read и copy_from_user в моей функции записи.

Edit: Я считаю, что нашел ответ на свой вопрос, прочитав fs/libfs.c (я не знал, что именно здесь находится исходный код этих функций); Насколько я понимаю, функции simple_...() по сути являются оболочкой для функций copy_...(). Я думаю, что в моем случае было уместно использовать copy_from_user для функции записи устройства mis c, так как мне нужно было проверить, соответствует ли ввод заданной строке c, прежде чем возвращать его в пользовательский буфер.

Я все равно оставлю этот вопрос открытым, если у кого-то есть лучшее объяснение или кто-то хочет меня поправить!

1 Ответ

1 голос
/ 20 июня 2020

simple_read_from_buffer и simple_write_to_buffer - это просто удобные оболочки вокруг copy_{to,from}_user, когда все, что вам нужно сделать, это обслужить read из пользовательского пространства из буфера ядра или обслужить write из пользовательского пространства в буфер ядра. .

Насколько я понимаю, функции copy_..._user более безопасны.

Ни одна из версий не является «более безопасной», чем другая. Может ли один быть более безопасным, чем другой, зависит от конкретного варианта использования c.

Я бы сказал, что simple_{read,write}_... в целом может быть более безопасным, поскольку они все соответствующие чеки перед копированием. Если все, что вам нужно сделать, это обслужить чтение / запись в / из буфера ядра, тогда использование simple_{read,write}_..., безусловно, быстрее и менее подвержено ошибкам, чем ручная проверка и вызов copy_{from,to}_user.

Хороший пример где simple_read_from_buffer полезно:

#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, kernel_buf + off, kernel_buf, SZ - off);
}

Трудно сказать, что именно вам нужно, не видя кода вашего модуля, но я бы сказал, что вы можете либо:

  1. Используйте copy_{from,to}_user, если вы хотите контролировать точное поведение вашей функции .
  2. Используйте return simple_{read,write}_..., если вам не нужен такой мелкозернистый элемент управления, и вы можете просто вернуть стандартные значения, созданные этими оболочками.
...