Powrót do strony głównej
exec
Uruchamianie skryptów oraz programów w języku
Java
A. Skrypty: binfmt_script.c : do_load_script(...)
Plik skryptu powinien w pierwszym wierszu zawierać znaki "#!", po których
następuje nazwa interpretatora ("shell"). Kontrola zgodności z formatem
sprowadza się tu zbadania, czy nagłówek pliku, dany przez bprm->buf rozpoczyna
się od w. wym. znaków. Dalej już system próbuje wydzielić z pierwszego
wiersza pliku nazwę interpretatora i uruchomić go z nazwą skryptu jako
ostatnim parametrem. Aby tego dokonać, przerabiamy dostarczoną jako parametr
wywołania strukturę linux_binprm na taką, jaka byłaby stworzona, gdyby
użytkownik wydał wprost polecenie uruchomienia powłoki:
-
Przerabiamy stos zmiennych środowiska i parametrów wywołania (bprm->p).
Parametry te są ułożone w odwrotnej kolejnoci - ostatnim jest argv[0]
- nazwa uruchamianego programu. Wyrzucamy go - "remove_arg0",
a następnie zapisujemy w to miejsce nazwę uruchamianego skryptu (Dlaczego?
Czy to nie powinien być ten sam ciąg znaków? - otóż argv[0] zawiera
nazwę pozbawioną ścieżki dostępu - gdyby tylko tyle podać interpretatorowi,
to mógłby nie znaleźć naszego pliku). Następnie na stos wędruje
parametr wywołania powłoki, dany po znakach "#!" i nazwie interpretatora
- tylko jeden! Teraz dopiero dopisujemy nazwę interpretatora jako
nowe argv[0]. Do manipulacji na stosie parametrów, który jest trzymany
w postaci ciągów znaków oddzielonych wartościami NULL, służy nam
procedura "copy_strings".
-
Podmiana pola bprm->inode - zamykamy i-węzeł skryptu
(iput - wykonane na początku procedury), a na to miejsce
wpisujemy i-węzeł interpretatora zwrócony przez "open_namei".
Pole bprm->dont_iput ustawiane jest na 1 po zwróceniu węzła,
a następnie po przydzieleniu nowego znowu staje się 0. Jest to informacja
dla nadrzędnej procedury, aby w razie gdy "do_load_script"
powróci z błędem po zwolnieniu węzła, ale przed przydzieleniem nowego,
system nie próbował zamknąć go jescze raz w ramach akcji "porządkowych".
-
"prepare_binprm" wypełnia pozostałe
pola (uid,gid itp.) oraz sprawdza, czy program interpretatora może
być uruchomiony - czy ma odp. atrybut, itd.
-
Rekurencyjenie wywołujemy "search_binary_handler",
jako parametr podając przebudowaną strukturę bprm. Aby zapobiec sytuacji
gdy interpretator również okazuje się być skryptem (co w tym złego?
- proszę wyobrazić sobie, co stanie się, gdy interpretatorem dla interpretatora
będzie znowu ten sam skrypt - mamy cykl: nieskończona rekursja, system
zapętli się), ustawiamy na 1 pole binprm->sh_bang.
Jego wartość jest sprawdzana zawsze na początku "do_load_script".
UWAGA! "Projekt Linux" błędnie podaje, że "search_binary_handler"
wykonuje się tylko w razie błedu. Jest przeciwnie - "search_binary_handler"
jest ostatnim krokiem prawidłowego przebiegu procedury.
B. Applety i skrypty w języku Java - ich uruchamianie ma prawie
identyczny przebieg jak w przypadku ogólnych skryptów - kody procedur
"do_load_script" oraz "do_load_applet" z pliku
"binfmt_java.c" pokrywają się z kodem procedury "do_load_script"
z pliku "binfmt_script.c" po usunięciu z tej ostatniej "wyłuskiwania"
z góry znanej nazwy interpretatora, oraz sprawdzania pola bprm->sh_bang.
Ciekawostką jest, że uruchamiany jest tutaj "bash" z nazwą interpretatora
Java jako parametrem - czyżby interpretator ten był skryptem?
Opracowanie oraz komentarze w plikach binfmt_script.c i binfmt_java.c:
Marcin Mędelski-Guz