2009-11-08 13 views
9

Zaimplementowałam urządzenie znakowe i potrzebuję pomocy z funkcją copy_ from_user.Kernel systemu Linux: copy_from_user - struct ze wskazówkami

Mam strukturę:

struct my_struct{ 

int a; 

int *b; 
}; 

zainicjować go w przestrzeni użytkownika i przekazać wskaźnik do my_struct do mojego urządzenia char za pomocą funkcji „Zapisz”. W funkcji "write" funkcji urządzenia Kernel Space rzutuję ją z * char na tego typu strukturę. Przydzielam trochę pamięci dla struct za pomocą komendy kmalloc i do copy_from_user.

Jest w porządku dla prostego "int a", ale kopiuje tylko wskaźnik (adres) wartości b, nie wartość wskazywaną przez b, więc jestem teraz w Przestrzeni jądra i pracuję ze wskaźnikiem, który wskazuje pamięć przestrzeni użytkownika. Czy jest to niepoprawne i nie powinienem mieć bezpośredniego dostępu do wskaźnika przestrzeni użytkownika i muszę do copy_from_user każdego wskaźnika w mojej strukturze, a następnie skopiować każdy wskaźnik w funkcji "odczyt" przy użyciu funkcji copy_to_user?

Odpowiedz

6

Masz rację w swoim podejściu. Jeśli potrzebujesz dostępu do wartości *b, musisz użyć copy_from_user (i copy_to_user, aby zaktualizować ją ponownie w procesie użytkownika).

+2

Chciałbym również zwrócić uwagę, że nie mogę myśleć o żadnych systemach i ioctls, które pobierają struktury ze wskaźnikami w nich. Nawet ci, którzy mają łańcuchy, będą mieli zamiast tablicy tablicę znaków. Fakt, że napisanie kodu dla każdego elementu wskaźnika jest bardzo denerwujące, może mieć z tym coś wspólnego. :-) – asveikau

+0

@asveikau: 'readv()' i 'writev()'? – caf

13

Musisz zawsze używać copy_from_user i podobnego, aby uzyskać dostęp do pamięci miejsca użytkownika z przestrzeni jądra, niezależnie od tego, jak uzyskałeś wskaźnik. Ponieważ b jest wskaźnikiem do pamięci przestrzeni użytkownika, należy użyć copy_from_user, aby uzyskać do niego dostęp.

Te funkcje zrobić dwie ważne dodatkowe zadania:

  1. One upewnić się punkty kursora do przestrzeni użytkownika, a nie jądra przestrzeń. Bez tego sprawdzenia programy przestrzeni użytkownika mogą być w stanie odczytać lub zapisać w pamięci jądra, omijając normalne zabezpieczenia.
  2. Poprawnie obsługują błędy strony. Zwykle błąd strony w trybie jądra spowoduje OOPS lub panikę - rodzina funkcji copy_*_user ma specjalne nadpisanie, które mówi obsługującemu PF, że wszystko jest w porządku, a usterka powinna być obsługiwana normalnie; oraz w przypadku, gdy błąd nie może zostać spełniony przez IO (tj. co zwykle powoduje, że SIGSEGV lub SIGBUS), zwraca zamiast tego kod błędu, aby jego rozmówca mógł wykonać niezbędne czyszczenie przed powrotem do przestrzeni użytkownika z -EFAULT.
Powiązane problemy