Home Dokumentacje Wprowadzenie do Prelink w Gentoo
10 | 12 | 2019
Wprowadzenie do Prelink w Gentoo
Wpisany przez Gentoo   

Wprowadzenie do Prelink w Gentoo

Spis treści:

1. Wprowadzenie

Co to jest Prelink i do czego służy?

Większość aplikacji korzysta ze współdzielonych bibliotek, które muszą zostać załadowane do pamięci w czasie pracy programu, co za każdym razem wiąże się z koniecznością dynamicznego połączenia programu z potrzebnymi mu bibliotekami. W przypadku większości małych programów proces ten trwa bardzo krótko. Jednak w przypadku programów napisanych w języku C++ lub posiadających wiele zależności symbolicznych, proces dynamicznego łączenia może zająć sporo czasu.

W przeciętnym systemie biblioteki rzadko ulegają modyfikacjom, więc kiedy program jest uruchamiany, czynności wykonywane podczas dynamicznego łączenia są zawsze jednakowe. Prelink wykorzystuje ten fakt i dokonuje dynamicznego łączenia tylko raz, po czym zapisuje wyniki na stałe w pliku wykonywalnym programu.

Prelinkowanie może skrócić czas uruchamiania programów. Przykładowo, czas potrzebny do uruchomienia typowego programu dla środowiska KDE może zostać skrócony nawet o 50%. Jedynym obowiązkiem użytkownika jest ponowne uruchomienie polecenia prelink po każdej aktualizacji biblioteki używanej przez prelinkowany program.

Ostrzeżenie: Prelinkowanie nie działa na Hardened Gentoo. Dzieje się tak dlatego, że oba projekty próbują zmienić adresowanie bibliotek współdzielonych. Jednak prelinkowanie z opcją -R przydziela przypadkowe adresy współdzielonym bibliotekom, co w pewnym stopniu zapewnia odpowiedni poziom bezpieczeństwa.

Podsumowanie

  • Prelinkowania dokonuje się przy użyciu programu o nazwie prelink, który modyfikuje plik wykonywalny tak, aby ten uruchamiał się szybciej.
  • Jeżeli jedna z bibliotek wykorzystywanych przez prelinkowany program ulegnie modyfikacji, konieczne jest ponowne prelinkowanie programu. W przeciwnym wypadku zostanie utracony efekt przyśpieszonego uruchamiania. W skrócie, za każdym razem, kiedy poprzez portage aktualizowany jest pakiet, który aktualizuje jakieś biblioteki, wszystkie programy, które z nich korzystają muszą zostać ponownie prelinkowane.
  • Modyfikacje dokonane poleceniem prelink są w pełni odwracalne. Polecenie to posiada funkcję undo.
  • Aktualne wersje Portage potrafią rozpoznać zmiany w sumach MD5 i znacznikach czasowych plików wykonywalnych, dokonane w wyniku użycia prelink.
  • Nie ma potrzeby dopisywania FEATURES="prelink" do pliku make.conf. Portage automatycznie użyje prelinkowania, jeżeli znajdzie w systemie zainstalowany program prelink.

2. Instalacja programu Prelink

Instalacja

Aby rozpocząć, należy zainstalować program prelink. Podczas jego instalacji wykonywana jest seria testów, mających na celu określenie, czy korzystanie z prelinkowania w danym systemie będzie w pełni bezpieczne.

Listing 2.1: Instalacja polecenia Prelink

# emerge prelink

U części użytkowników instalowanie programu prelink kończy się błędem z powodu niepowodzenia podczas testowania systemu. Testy te zostały wprowadzone ze względów bezpieczeństwa. Można je pominąć, jednak w takim przypadku zachowanie polecenia prelink może być nieobliczalne. Przyczyną niepowodzenia testów jest zwykle nieprawidłowa instalacja podstawowych pakietów systemowych, takich jak binutils, gcc i glibc. Instalacja tych pakietów w podanej kolejności może wpłynąć na poprawę sytuacji i tym samym możliwość instalacji programu prelink bez pomijania testów.

Uwaga: Wskazówka: W przypadku pojawienia się błędu istnieje możliwość ręcznej instalacji programu prelink (./configure ; make ; make check). Jeżeli wystąpił błąd, zawsze można przejrzeć pliki *.log w katalogu zawierającym programy testujące. Z zawartości tych plików można wyłowić przydatne wskazówki, pomocne przy usuwaniu błędu.

Jeżeli istnieje określona sekwencja kroków, w wyniku której w innym systemie również pojawia się identyczny błąd, należy wysłać ich opis na Bugzillę Gentoo.

Przygotowanie systemu

Należy również zwrócić uwagę, żeby wśród flag w zmiennych CFLAGS/CXXFLAGS nie znajdowała się opcja -fPIC. W przeciwnym wypadku konieczne będzie jej usunięcie i ponowne przebudowanie całego systemu.

Konfiguracja

Wywołanie env-update spowoduje wygenerowanie pliku /etc/prelink.conf, w którym zawarta jest lista plików przeznaczonych do prelinkowania.

Listing 2.2: Wywoływanie env-update

# env-update

Niestety nie jest możliwe prelinkowanie programów skompilowanych przy użyciu starych wersji binutils. Większość z tych programów pochodzi z pakietów aplikacji rozpowszechnianych wyłącznie w postaci binarnej, które instalowane są zwykle w katalogu /opt. Utworzenie następującego pliku spowoduje, że wspomniane programy zostaną pominięte podczas prelinkowania.

Listing 2.3: /etc/env.d/60prelink

PRELINK_PATH_MASK="/opt"

Uwaga: Można określić więcej katalogów do pominięcia poprzez oddzielenie ich nazw dwukropkami.

3. Prelinkowanie

Użycie polecenia Prelink

Do prelinkowania wszystkich programów w katalogach wymienionych w pliku /etc/prelink.conf można użyć polecenia:

Listing 3.1: Prelinkowanie wyszczególnionych programów

# prelink -amR

Ostrzeżenie: Jeżeli w systemie jest mało miejsca na dysku, prelinkowanie całego może się skończyć obcięciem i tym samym zniszczeniem niektórych plików wykonywalnych, czego efektem będzie pad systemu. Należy wtedy użyć polecenia file albo readelf, aby szybko sprawdzić stan podejrzanego pliku. Najlepiej jednak, przed prelinkowaniem, sprawdzić ilość wolnego miejsca na dysku wywołując df -h.

Opis użytych parametrów:
-a "All": prelinkuje wszystkie programy.
-m Oszczędzaj pamięć wirtualną. Przydatne w przypadku prelinkowania większej ilości bibliotek.
-R Tryb losowy - przyporządkowuje przypadkowe adresy, co skutkuje wzrostem poziomu bezpieczeństwa poprzez zwiększenie odporności na ataki z wykorzystaniem przepełnienia bufora (buffer overflow).

Uwaga: Więcej parametrów i szczegółów dotyczących użycia powyższych można odnaleźć na stronie manuala: man prelink.

Prelinkowanie w cronie

Pakiet sys-devel/prelink-20060213 ,i późniejsze, instaluje zadania do wykonania przez cron w pliku /etc/cron.daily/prelink. Aby je uaktywnić należy edytować plik /etc/conf.d/prelink. Dzięki temu prelinkowanie będzie uruchamiane codziennie, zaoszczędzając nam ręcznego wpisywania poleceń.

Przyspieszanie uruchamiania KDE po prelinkowaniu

Czas uruchamiania KDE może zostać znacznie zredukowany w wyniku prelinkowania. Aby dodatkowo skrócić czas uruchamiania KDE, można je skonfigurować tak, aby przestało korzystać z programu kdeinit, który po prelinkowaniu nie jest już potrzebny.

Aby tego dokonać, wystarczy umieścić wiersz KDE_IS_PRELINKED="true" w pliku /etc/env.d/*kdepaths*.

Usuwanie prelinka

Jeżeli w przyszłości prelink przestanie być porządany w systemie, należy najpierw usunąć zadanie cron z katalogu /etc/cron.daily i pliku /etc/conf.d/prelink. Następnie należy usunąć prelink ze wszystkich plików binarnych:

Listing 3.2: Usuwanie prelinka z plików binarnych

# prelink -au

Na koniec należy usunąć pakiet prelink:

Listing 3.3: Usuwanie prelinka

# emerge -aC prelink

4. Znane problemy i ich rozwiązania

"Cannot prelink against non-PIC shared library" (Nie można prelinkować z biblioteką, skompilowaną bez opcji PIC)

Przyczyną tego problemu jest niewłaściwie skompilowana biblioteka, podczas kompilacji której nie podano parametru -fPIC.

Oto lista bibliotek, które nie zostały poprawione lub których poprawienie nie jest możliwe:

  • Biblioteki w pakiecie wine i pochodnych (w tym winex). Prelinkowanie w tym wypadku i tak nie spowodowałoby przyśpieszenia programów napisanych dla systemu MS Windows.
  • Biblioteka /usr/lib/liblavfile-1.6.so.0 z pakietu media-video/mjpegtools.
  • Bliblioteki OpenGL Nvidia, /usr/lib/opengl/nvidia/lib/libGL.so.*. Z powodu problemów z wydajnością zostały one skompilowane bez wsparcia dla PIC.

Jeżeli sprawcą problemu jest biblioteka nie ujęta na tej liście, najlepiej zgłosić ten fakt, wraz z łatą (jeśli to możliwe), dodającą we właściwych miejscach flagę -fPIC do CFLAGS.

Po prelinkowaniu systemu niektóre statyczne programy przestają działać.

W systemie opartym na glibc tak naprawdę nie istnieje coś takiego, jak w 100% statyczny program. Skompilowanie programu statycznie w stosunku do glibc nie oznacza, że program nie będzie posiadał innych zależności, w stosunku do innych plików systemowych. Oto, jak problem wyjaśnił Dick Howell:

"Pomysł ze statycznie skompilowanymi programami ma na celu uniezależnienie ich od zainstalowanych w systemie bibliotek. Niestety w Linuksie oraz, jak sądzę, w innych systemach opartych o GLIBC, nie jest to do końca możliwe. Jest np. sprawa biblioteki "libnss" (Name Service Switch, przez niektórych nie wiedzieć czemu, nazywana Network Security System), która udostępnia interfejs dostępu do różnych baz danych uwierzytelniania, informacji sieciowych i wielu innych rzeczy. Ma to na celu uniezależnienie aplikacji od konfiguracji sieciowej konkretnego systemu. Pomysł jest niezły, jednak zmiany w GLIBC mogą powodować problemy z jej załadowaniem. Nie można statycznie włączyć biblioteki "libnss", ponieważ dla każdego systemu jest ona inaczej skonfigurowana. Problem wydaje się leżeć w statycznym linkowaniu innych bibliotek składowych GLIBC, np. "libpthread", "libm" oraz "libc", w wyniku czego powstają niekompatybilne odwołania do funkcji biblioteki "libnss"."

Prelink kończy z błędem "prelink: dso.c:306: fdopen_dso: Assertion `j == k' failed."

Jest to znany problem, przystępnie opisany tutaj. Prelink nie radzi sobie z plikami wykonywalnymi, skompresowanymi programem UPX. Począwszy od prelinka w wersji 20021213 jedynym sposobem ominięcia problemu jest nakazanie poleceniu prelink pominięcie takich programów. W rozdziale Konfiguracja opisano prosty sposób, w jaki można tego dokonać.

Używam grsecurity i mam wrażenie, że prelinkowanie nie działa.

Aby prelinkować programy w systemie używającym grsecurity, z opcją losowego generowania adresów bazowych w funkcji mmap(), konieczne jest WYŁĄCZENIE tej funkcji dla pliku /lib/ld-2.3.*.so. Można tego dokonać przy użyciu polecenia chpax, jednak plik nie może być danym momencie używany przez żaden program (najlepiej zrobić to uruchamiając system z płyty CD).

Prelink kończy pracę z błędem "prelink: Can't walk directory tree XXXX: Too many levels of symbolic links".

Błąd ten może oznaczać nadmierny poziom skomplikowania dowiązań symbolicznych. Występuje na przykład, gdy dwa dowiązania wskazują wzajemnie na siebie. Częstym powodem takiego problemu jest na przykład /usr/lib/lib -> lib. Aby naprawić dowiązania, można je zmienić ręcznie lub posłużyć się programem dostarczanym razem z pakietem symlinks:

Listing 4.1: Naprawianie dowiązań

# emerge symlinks
# symlinks -drv /

Więcej informacji na temat tego błędu można znaleźć w Bugzilli oraz na forum Gentoo.

5. Podsumowanie

Prelinkowanie może drastycznie przyspieszyć uruchamianie wielu dużych aplikacji. W dodatku jest ono wspierane przez Portage. Prelinkowanie jest również bezpieczne, ponieważ zawsze można odwrócić ten proces dla dowolnego pliku wykonywalnego, jeżeli sprawia on kłopoty. Wystarczy pamiętać, aby po aktualizacji glibc lub innych bibliotek zawsze ponownie uruchomić prelink w celu uaktualnienia wszystkich programów.

 

 
Linki sponsorowane

W celu realizacji usług i funkcji na witrynach internetowych ZUI "ELPRO" stosujemy pliki cookies. Korzystanie z witryny bez zmiany ustawień dotyczących plików cookies oznacza, że będą one zapisywane w urządzeniu wyświetlającym stronę internetową. Więcej szczegółów w Polityce plików cookies.

Akceptuję pliki cookies z tej witryny.