Разработка ядра Linux | страница 83
>/*
>* Системный вызов silly copy — крайне бесполезная функция,
>* которая копирует len байтов из области памяти,
>* на которую указывает параметр src, в область памяти,
>* на которую указывает параметр dst, с использованием ядра
>* безо всякой на то причины. Но это хороший пример!
>*/
>asmlinkage long sys_silly_copy(unsigned long *src,
> unsigned long *dst, unsigned long len) {
> unsigned long buf;
> /* возвращаем ошибку, если размер машинного слова в ядре
> не совпадает с размером данных, переданных пользователем */
> if (len != sizeof(buf))
> return -EINVAL;
> /* копируем из src, который является адресом в пространстве
> пользователя, в buf */
> if (copy_from_user(&buf, src, len))
> return -EFAULT;
> /* копируем из buf в dst, который тоже является адресом
> в пространстве пользователя */
> if (copy_to_user(dst, &buf, len))
> return -EFAULT;
> /* возвращаем количество скопированных данных */
> return len;
>}
Следует заметить, что обе функции, >copy_from_user()
и >copy_to_user()
, могут блокироваться. Это возникает, например, если страница памяти, содержащая данные пользователя, не находится в физической памяти, а в данный момент вытеснена на диск. В таком случае процесс будет находиться в приостановленном состоянии до тек пор, пока обработчик прерываний из-за отсутствия страниц (page fault handler) не возвратит страницу памяти в оперативную память из файла подкачки на диске.
Последняя проверка — это проверка на соответствие правам доступа. В старых версиях ядра Linux стандартом было использование функции >suser()
для системных вызовов, которые требуют прав пользователя root. Эта функция просто проверяла, запущен ли процесс от пользователя root. Сейчас эту функцию убрали и заменили более мелко структурированным набором системных "возможностей использования" (capabilities). В новых системах предоставляется возможность проверять специфические права доступа к специфическим ресурсам. Функция >capable()
с допустимым значением флага, определяющего тип прав, возвращает ненулевое значение, если пользователь обладает указанным правом, и нуль— в противном случае. Например, вызов >capable
(>CAP_SYS_NICE
) проверяет, имеет ли вызывающий процесс возможность модифицировать значение параметра nice других процессов. По умолчанию суперпользователь владеет всеми правами, а пользователь, не являющийся пользователем root, не имеет никаких дополнительных прав. Следующий пример системного вызова, который демонстрирует использование возможностей использования, тоже является практически бесполезным.