Jakie są różnice w korzystaniu z Xorg w Gentoo Hardened?
PaX jest łatą na linuksowy kernel i stanowi główną część projektu Gentoo Hardened. Dostarcza różnych funkcjonalności, takich jak ASLR lub pamięć z atrybutem NX ([przyp. tłum.] NX = non-executable, kod w takim obszarze pamięci nie jest wykonywany). Więcej informacji znajduje się na stronie Krótkie wprowadzenie do PaX w Gentoo Hardened. Na potrzeby tego dokumentu zakładamy, że czytelnicy znają podstawy działania PaX, a także ideę PIE (Position Independent Executable) - kodu relokowalnego.
Szczególnie interesującą cechą PaX, z punktu widzenia tego artykułu, jest MPROTECT, który chroni przed wykonaniem kodu z przestrzeni adresowej programu. Jedną z głównych cech Gentoo Hardened jest możliwość wydajnego działania w oparciu o ET_DYN/PIE. Końcowy cel jaki chcemy osiągnąć z Xorg, to uzyskanie binariów ET_DYN/PIE, które nie zawierają relokacji sekcji "text" oraz mają losowy adres bazowy, a wszystko to bez narzutu wydajnościowego, jaki generuje EX_EXEC.
W tym momencie, kompilacja Xorg z opcją PIC wydaje się oczywistym i logicznym wyborem. Gentoo Hardened w tym celu oferuje gcc w wersji hardened, które umożliwia przezroczystą kompilację z PIE/SSP. I tu zaczynają pojawiać się problemy. Xorg obecnie używa elfloadera, by obsłużyć ładowanie potrzebnych modułów. Elfloader nie jest w stanie rozwiązać pewnych typów relokowalnych symboli, które są zawsze generowane przez kod PIC. Co więcej, elfloader nie oferuje wsparcia dla typu symboli Globalnej Tablicy Przesunięć (GOF - Global Offset Table) lub Tablicy Linkowania Procedur (PLT - Procedure Linkage Table). Obydwa rodzaje wymienionych symboli są istotne dla bibliotek współdzielonych.
Jeśli nie elfloader, to co zadziała? Na szczęście istnieje w pełni sprawny, dobrze przetestowany i dojrzały dynamiczny program ładujący, który jest zainstalowany w naszym systemie. Jest to ld-linux.so, który dostarczany jest wraz z glibc. W tym momencie nasuwa się oczywisty pomysł, że byłoby bardzo dobrze gdyby istniał interfejs programistyczny dla programu ładującego glibc, dzięki czemu program ładujący X mógłby zostać zmodyfikowany tak, aby korzystać z tego interfejsu, zamiast z własnego programu ładującego. Okazuje się, że taki interfejs istnieje - dlopen(3) et. al. - i jest dokładnie tym, czego używa dlloader.
Uwaga: Począwszy od Xorg 7.0, dlloader jest domyślną aplikacją ładującą moduły dla X. |
Opcja 'CONFIG_PAX_KERNEXEC' jest odpowiednikiem PAGEEXEC oraz MPROTECT w jądrze. Poprzez udostępnienie tej opcji stanie się trudniejszym używanie "obcego" kodu w pamięci jądra. Ta opcja może również dać nam dziwne doświadczenia związane z ustawieniami Xorg hardened (kursor myszy zatrzymany w lewej części ekranu). Zaleca się zatem wyłączenie tej opcji poprzez odznaczenie jej w konfiguracji.
Aktywacja tej opcji spowoduje, że wszystkie odwołania do ioperm(2) oraz iopl(2) będą zwracały błędy. ioperm(2) i iopl(2) mozna użyć przy wprowadzaniu zmian w obecnie wykorzystywanym jądrze. Jeżeli chcemy uruchomic serwer Xorg przy jądrze hardened (głównie GRsecurity) należy wyłączyć tę opcję, aby serwer X zaczął działać.
Ponieważ Xorg 7.0 (i wyższe) używa domyślnie dlloader zamiast elfloader, nie ma potrzeby wykonywać jakichkolwiek kroków aby Xorg został skompilowany oraz uruchomiony na profilu hardened.
Xorg można skonfigurować w oparciu o opis procesu konfiguracji serwera X, znajdujący się pod adresem http://www.gentoo.org/doc/pl/xorg-config.xml
Gentoo Hardened posiada domyślną strategię linkowania, która polega na rozwiązywania wszystkich symboli w czasie ładowania i wymusza takie zachowanie na wszystkich bibliotekach współdzielonych, które są budowane. Zazwyczaj program ładujący używa "leniwego" rozwiązywania symboli, tzn. symbole są rozwiązywane wtedy, gdy są potrzebne. Niestety niektóre z modułów Xorg posiadają wzajemne zależności i inne utrudnienia, które sprawiają, że moduły nie mogą zostać załadowane, chyba że włączone jest "leniwe" rozwiązywanie symboli. Obecnie ten problem w Gentoo został rozwiązany poprzez kompilację modłów Xorg oraz serwera, z ustawioną flagą -nonow dla gcc. Pozwala to na pozbycie się błędów "dlopen: undefined symbol". Tak więc, metody ręcznego wykrywania i ładowania modułów nie są już potrzebne.
Ważne: Wszelkie problemy prosimy zgłaszać na bugzilli, która znajduje się pod adresem http://bugs.gentoo.org załączając logi i pliki konfiguracyjne. |
Sterowniki binarne nie są obecnie wspierane przez profil hardened i zachęca się do używania sterowników z otwartym kodem źródłowym.
Flaga -M (MPROTECT), z PaX, nie wydaje się działać z Xorg, powoduje znaczne opóźnienie. Flagi PaX -P (PAGEEXEC), -S (SEGMEXEC), -M (MPROTECT) jak i -R (RANDMMAP) teraz działają z Xorg.