=========================== Zadanie 3: System Soczewka™ =========================== Data ogłoszenia: 09.05.2019 Termin oddania: 13.06.2019 (ostateczny 27.06.2019) Wprowadzenie ============ Dowiedzieliśmy się, że pewne osoby używały sprzętu wydziałowego niezgodnie z regulaminem Laboratorium Komputerowego, uruchamiając na nim niedozwolone i niebezpieczne programy, a także wykorzystując go do niedozwolonych celów, W celu walki z tym procederem postanowiliśmy skompilować listę słów kluczowych powiązanych z podejrzanym użyciem i stworzyć system monitorujący, wykrywający wystąpienia tych słów na maszynie -- system Soczewka™. Zadanie ======= Napisać główny komponent systemu Soczewka™ -- zmodyfikować jądro systemu Linux tak, by wykrywało użycie przez użytkowników podejrzanych słów. Lista podsłuchiwanych słów będzie przekazywana przez administratorów jako parametr w linii poleceń jądra, na przykład tak:: boot vmlinuz root=/dev/sda1 soczewka=tiananmen,bomb,h4x,harddoom,mwk,pzuk Można przyjąć ograniczenie do 64 podejrzanych słów, o długości maksymalnie 64 znaków każde. Aby rozpoznać procesy, które powinny być podsłuchiwane, należy dodać do jądra nową flagę capability: ``CAP_SYS_SOCZEWKA_IMMUNE``. Należy podsłuchiwać wszystkie procesy, które nie mają ustawionej tej flagi. W podsłuchiwanych procesach należy monitorować następujące dane: - wszystkie dane wchodzące do jądra przez ``copy_from_user`` - wszystkie dane wychodzące z jądra przez ``copy_to_user`` - dane w zwalnianych stronach pamięci z flagą ``MAP_ANONYMOUS``, czyli: - strony, na których użytkownik wywoła ``munmap`` - strony zwalniane w wywołaniu ``brk`` - przy kończeniu pracy procesu (przez ``exit``, śmiertelny sygnał, bądź w jakikolwiek inny sposób), wszystkie strony wciąż zmapowane w pamięć procesu W przypadku znalezienia wystąpienia podejrzanego słowa w podsłuchiwanych danych, należy wypisać przez ``printk`` następujące informacje: - pid, uid oraz gid procesu wykonującego podejrzaną aktywność - znalezione podejrzane słowo - bajty znajdujące się w przechwyconych danych w okół podejrzanego słowa: 256 bajtów przed słowem i 256 bajtów za słowem (bądź mniej, jeśli wyjechalibyśmy poza zakres przechwyconych danych lub strony). Żeby zabezpieczyć się przed danymi z poza ASCII, należy te dane wypisać jako hex dump:: $ echo -n "abch4xdef" [491972.475072] soczewka: PID 1337 UID 1000 GID 1000 h4x before [61 62 63] after [64 65 66] Aby uniknąć zaśmiecenia systemowych logów przez procesy, które wykazują dużo podejrzanej aktywności, należy dla każdego procesu przechowywać informację, które podejrzane słowa zostały już w nim wykryte i nie wypisywać komunikatów dla kolejnych wystąpień w tym procesie. Dziecko utworzone przez ``fork`` uważamy tutaj za nowy proces, który powinien mieć pustą listę wystąpień słów. Zasady oceniania ================ Za zadanie można uzyskać do 10 punktów. Na ocenę zadania składają się trzy części: - funkcjonalność rozwiązania: - wykrywanie słów tylko w ``copy_*_user`` (0 punktów) - wykrywanie słów w ``copy_*_user`` i stronach pamięci zwalnianych przez ``brk``/``munmap`` (1 punkt) - wykrywanie słów w ``copy_*_user`` i stronach pamięci zwalnianych przez ``brk``/``munmap`` bądź zakończenie procesu (2 punkty) - wynik testów (od 0 do 8 punktów) - ocena kodu rozwiązania (od 0 do -10 punktów) Punkty ujemne za kod można było dostać za: 1. Możliwość przeplotów przy wypisywaniu komuniktów soczewki dla różnych procesów (-0.2 pkt) 2. Brak nowej linii w printk (-0.1 pkt) 3. Skanowanie niepoprawnego zakresu w ``copy_*_user`` (-0.2 pkt) 4. Wykorzystanie globalnego bufora bez mutexu (-0.2 pkt) 5. Wyciek pamięci (-0.2 pkt) 6. Nieprawidłowa obsługa warunku brzegowego: ``copy_*_user`` kopiujące wyłącznie niedozwolone słowo (-0.1 pkt) 7. Niepoprawna implementacja przeszukiwania - obsługa wyłącznie sytuacji gdy szukane słowo znajduje się na początku przeszukiwanego obszaru (-0.1 pkt) 8. Nieprawidłowe parsowanie cmdline (-0.1 pkt) 9. Brak obsługi mapowań ``MAP_ANONYMOUS | MAP_SHARED`` (-0.1 pkt, tylko rozwiązania na 9/10 pkt) 10. Brak ustawiania początkowej wartości flagi w ``init_task`` (-0.0 pkt) 11. Niestandardowy format logowania, wymagający modyfikacji do uruchomienia testów (-0.2 pkt) 12. Wypisywanie nieprawidłowego UID/GID (-0.2 pkt) 13. Brak obsługi huge pages (-0.1 pkt, tylko rozwiązania na 9/10 pkt) 14. Brak skanowania stron znajdujących się na SWAP-ie (-0.4 pkt, tylko rozwiązania na 9/10 pkt) Testy (dla funkcjonalności na 8pkt): - list_badwords - wypisujemy słowa kluczowe (copy_from_user) (1.5 pkt) - simple_read - czytamy /proc/cmdline (copy_to_user) (1.5 pkt) - multiple_copy - obie akcje powyżej, powtórzone (1.5 pkt) - multiple_copy_cap - jak wyżej, ale program ma ustawione capability `CAP_SYS_SOCZEWKA_IMMUNE` (1.5 pkt) - fork - weryfikacja czy fork ma wyczyszczone flagi (1.5 pkt) - thread - uruchamiamy wiele wątków, każdy wykonuje ekwiwalent `multiple_copy` (0.5 pkt) Forma rozwiązania ================= Jako rozwiązanie należy wysłać paczkę zawierającą: - patcha na jądro w wersji 4.20.8, w jednym z następujących formatów: - patch wygenerowaniy przez diffa z opcjami ``-uprN`` nakładający się przez ``patch -p1`` - ``git format-patch`` - krótki opis rozwiązania Rozwiązania prosimy nadsyłać na adres ``p.zuk@mimuw.edu.pl`` z kopią do ``mwk@mimuw.edu.pl``. Uwagi i wskazówki ================= - w przypadku gdy w systemie jest obecny swap, dopuszczamy rozwiązania w których: - weryfikujemy strony trafiające na swap w momencie zapisu na dysk - w ``munmap`` bądź przy zakończeniu procesu sprawdzamy już tylko strony znajdujące się w pamięci - można założyć, że poszukiwane słowa mieszczą się w obrębie strony