2012-08-17 13 views
5

Piszę moduł jądra, który ma dostęp do pamięci określonego procesu. Zrobiłem anonimowego odwzorowania na niektóre pamięci przestrzeni użytkownika z do_mmap():Zmiana flag ochrony pamięci użytkownika z modułu jądra

#define MAP_FLAGS (MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS) 

prot = PROT_WRITE; 
retval = do_mmap(NULL, vaddr, vsize, prot, MAP_FLAGS, 0); 

vaddr i vsize są ustawione wcześniej, a połączenie się powiedzie. Po napisaniu do tego bloku pamięci z modułu jądra (przez copy_to_user), chcę usunąć na nim uprawnienie PROT_WRITE (tak jak z mprotect w normalnej przestrzeni użytkownika). Nie mogę znaleźć funkcji, która na to pozwoli.

Podjęto próbę usunięcia mapy regionu i ponownego jej przypisania z odpowiednimi zabezpieczeniami, ale to zeruje blok pamięci, usuwając wszystkie zapisane przeze mnie dane; Ustawienie MAP_UNINITIALIZED może naprawić, ale ze strony człowieka:

MAP_UNINITIALIZED (od wersji Linuksa 2.6.33)

Nie jasne anonimowych stron. Ta flaga ma na celu zwiększenie wydajności wbudowanych urządzeń . Ta flaga jest honorowana tylko wtedy, gdy jądro zostało skonfigurowane z opcją CONFIG_MMAP_ALLOW_UNINITIALIZED. Z powodu implikacji związanych z bezpieczeństwem ta opcja jest zwykle włączona tylko w urządzeniach wbudowanych (tj. Urządzeniach, w których jedna ma pełną kontrolę nad zawartością pamięci użytkownika).

więc, chociaż może to zrobić, co chcę, to nie byłoby bardzo przenośne. Czy istnieje standardowy sposób osiągnięcia tego, co zasugerowałem?

+0

Dlaczego oh, dlaczego robisz to wszystko w swoim module jądra? Dzięki zdrowo zdefiniowanemu API nie ma powodu, którego nie mógłby zrobić sam proces przestrzeni użytkownika. – mpe

+0

@mpe Powodem, dla którego nie mogę tego zrobić w przestrzeni użytkownika, jest to, że moduł, który piszę, to program ładujący proces; Nie mam żadnego wpływu na kod przestrzeni użytkownika. – nosuchthingasstars

+0

Co masz na myśli przez program ładujący proces? Masz na myśli handler binfmt? – mpe

Odpowiedz

1

Po kilku dalszych badań, znalazłem funkcji o nazwie get_user_pages() (najlepiej dokumentacji znalazłem jest here), która zwraca listę stron z przestrzeni użytkownika w danym adresem, które mogą być przypisane do jądra przestrzeń kmap() i pisemnych do sposób (w moim przypadku, używając kernel_read()). Może to być użyte jako zamiennik dla copy_to_user(), ponieważ pozwala wymuszać uprawnienia do zapisu na pobranych stronach. Jedyną wadą jest to, że musisz pisać strona po stronie, zamiast wszystkiego za jednym razem, ale rozwiązuje to problem opisany w moim pytaniu.

0

W przestrzeni użytkownika istnieje wywołanie systemowe mprotect, które może modyfikować flagi ochrony w istniejącym odwzorowaniu. Najprawdopodobniej będziesz musiał wykonać implementację tej funkcji systemowej, lub po prostu wywołać ją bezpośrednio z Twojego kodu. Zobacz mm/protect.c.

Powiązane problemy