init_module(2) System Calls Manual init_module(2) NAZWA init_module, finit_module - laduje modul jadra BIBLIOTEKA Standardowa biblioteka C (libc, -lc) SKLADNIA #include /* Definicja stalych MODULE_* */ #include /* Definicja stalych SYS_* */ #include int syscall(SYS_init_module, void module_image[.len], unsigned long len, const char *param_values); int syscall(SYS_finit_module, int fd, const char *param_values, int flags); Uwaga: glibc nie udostepnia opakowania dla tych wywolan systemowych, co wymusza uzycie syscall(2). OPIS init_module() laduje obraz ELF do przestrzeni jadra, przeprowadzajac wszelkie niezbedne przesuniecia symboli, inicjuje parametry modulu zgodnie z wartosciami przekazanymi przez wywolujacego, a nastepnie uruchamia funkcje init modulu. To wywolanie systemowe wymaga uprzywilejowania. Argument module_image wskazuje na bufor zawierajacy obraz binarny, ktory ma byc zaladowany; len okresla rozmiar tego bufora. Obraz modulu powinien byc prawidlowym obrazem ELF, zbudowanym do aktualnie dzialajacego jadra. Argument param_values jest lancuchem zawierajacym wartosci parametrow modulu (zdefiniowanych wewnatrz modulu za pomoca module_param() i module_param_array()), rozdzielone spacja. Jadra analizuje ten lancuch i inicjuje podane parametry. Okreslenie kazdego z parametrow ma postac: nazwa[ =wartosc [,wartosc...]] Parametr nazwa jest jednym ze zdefiniowanych wewnatrz modulu za pomoca module_param() (zob. plik zrodel jadra Linux include/linux/moduleparam.h). Parametr wartosc jest opcjonalny w przypadku parametrow bool i invbool. Wartosci parametrow tablicy sa podawane w liscie rozdzielonej przecinkami. finit_module() Wywolanie systemowe finit_module() jest podobne do init_module(), lecz odczytuje modul, ktory ma byc zaladowany, z deskryptora pliku fd. Ma to zastosowanie, gdy autentycznosc modulu jadra mozna okreslic na podstawie jego polozenia w systemie plikow; w przypadku gdy jest to mozliwe, mozna w ten sposob uniknac narzutu wynikajacego z uzywania modulow podpisanych kryptograficznie. Argument param_values jest taki sam jak do init_module(). Argument flags modyfikuje dzialanie finit_module(). Jest maska bitowa wartosci, utworzona przez zsumowanie (OR) zera lub wiecej ponizszych znacznikow: MODULE_INIT_IGNORE_MODVERSIONS Ignoruje skroty wersji symboli. MODULE_INIT_IGNORE_VERMAGIC Ignoruje magie wersji jadra. MODULE_INIT_COMPRESSED_FILE (od Linuksa 5.17) Uzywa modulu dekompresji w jadrze. W module sa wbudowane pewne mechanizmy bezpieczenstwa zapewniajace, ze bedzie on pasowal do jadra, do ktorego jest zaladowywany. Sa one zapisywane przy budowaniu modulu i weryfikowane przy jego ladowaniu. Po pierwsze, modul zapisuje lancuch ,,vermagic" zawierajacy lancuch z numerem wersji jadra i glownymi cechami (takimi jak typ procesora). Po drugie, jesli modul zbudowano z wlaczona opcja konfiguracyjna CONFIG_MODVERSIONS, to zapisywany jest skrot (hash) wersji kazdego symbolu, ktorego uzywa modul. Skrot ten zalezy od typow argumentow i zwracanej przez funkcje, nazwana przez symbol, wartosci. W niniejszym przypadku, numer wersji jadra w ,,vermagic" jest ignorowany przyjmujac, ze skroty wersji symboli sa wystarczajaco wiarygodne. Uzycie znacznika MODULE_INIT_IGNORE_VERMAGIC wskazuje, ze lancuch ,,vermagic" ma byc zignorowany, natomiast znacznik MODULE_INIT_IGNORE_MODVERSIONS wskazuje, ze skroty wersji symboli maja byc zignorowane. Jesli jadro zbudowano w sposob umozliwiajacy wymuszone ladowanie modulow (tj. skonfigurowano je z opcja CONFIG_MODULE_FORCE_LOAD), to ladowanie bedzie kontynuowane, w przeciwnym przypadku zawiedzie z bledem ENOEXEC, jak jest to spodziewane wobec nieprawidlowych modulow. Jesli jadro zbudowano z opcja CONFIG_MODULE_DECOMPRESS, mozna skorzystac z funkcji dekompresji w jadrze. Kod w przestrzeni uzytkownika moze sprawdzic, czy jadro obsluguje dekompresje odczytujac atrybut /sys/module/compression. Jesli jadro obsluguje dekompresje, skompresowany plik mozna podac bezposrednio do finit_module() za pomoca znacznika MODULE_INIT_COMPRESSED_FILE. Modul dekompresji w jadrze obsluguje nastepujace algorytmy kompresji: o gzip (od Linuksa 5.17) o xz (od Linuksa 5.17) o zstd (od Linuksa 6.2) Jadro implementuje jedynie pojedyncza metode dekompresji. Wybiera sie ja przy generowaniu modulu, zgodnie z metoda kompresji uzyta w konfiguracji jadra. WARTOSC ZWRACANA W przypadku powodzenia, te wywolania zwracaja 0. W razie wystapienia bledu zwracane jest -1 i ustawiane errno wskazujac blad. BLEDY EBADMSG (od Linuksa 3.7) Podpis modulu jest nieprawidlowo sformatowany. EBUSY Nastapilo przeterminowanie, przy probie rozwiazania referencji symbolu przez ten modul. EFAULT Argument adresu odnosi sie do polozenia, znajdujacego sie poza dostepna przestrzenia adresowa procesu. ENOKEY (od Linuksa 3.7) Podpis modulu jest nieprawidlowy albo jadro nie ma klucza do tego modulu. Blad jest zwracany tylko, jesli jadro skonfigurowano z opcja CONFIG_MODULE_SIG_FORCE; w przeciwnym wypadku nieprawidlowy lub niepodpisany modul jedynie zatruwa (taint) jadro. ENOMEM Brak pamieci. EPERM Wywolujacy nie byl uprzywilejowany (nie posiadal przywileju (ang. capability) CAP_SYS_MODULE) lub ladowanie modulow jest wylaczone (zob. /proc/sys/kernel/modules_disabled w proc(5)). Moga wystapic nastepujace dodatkowe bledy dla init_module(): EEXIST Zaladowano juz modul o takiej nazwie. EINVAL param_values jest nieprawidlowe albo pewne fragmenty obrazu module_image sa niespojne. ENOEXEC Obraz binarny podany w module_image nie jest obrazem ELF albo jest nieprawidlowym lub przeznaczonym do innej architektury obrazem ELF. Moga wystapic nastepujace dodatkowe bledy dla finit_module(): EBADF Plik, do ktorego odnosi sie fd , nie jest otwarty do odczytu. EFBIG Plik, do ktorego odnosi sie fd, jest zbyt duzy. EINVAL Znaczniki flags sa nieprawidlowe. EINVAL Przy ladowaniu spakowanego modulu ze znacznikiem MODULE_INIT_COMPRESSED_FILE, zawiodlo sprawdzanie poprawnosci przeprowadzone przez dekompresor. ENOEXEC fd nie odnosi sie do otwartego pliku. EOPNOTSUPP (od Linuksa 5.17) Ustawiono znacznik MODULE_INIT_COMPRESSED_FILE w celu zaladowania spakowanego modulu, lecz jadro zbudowano bez CONFIG_MODULE_DECOMPRESS. ETXTBSY (od Linuksa 4.7) Plik, do ktorego odnosi sie fd, jest otwarty do odczytu i zapisu. Oprocz powyzszych bledow, jesli wykonana funkcja init modulu zwroci blad, to init_module() lub finit_module() zawioda, a errno zostanie ustawione na wartosc zwrocona przez funkcje init. STANDARDY Linux. HISTORIA finit_module() Linux 3.8. Wywolanie systemowe init_module() nie jest obslugiwane przez glibc. W naglowkach glibc nie ma jego deklaracji, ale z powodow pewnych zaszlosci historycznych wersje glibc przed glibc 2.23 eksportowaly ABI dla tego wywolania systemowego. Z tego powodu, aby go uzyc wystarczy (przed glibc 2.23) manualnie zadeklarowac interfejs w swoim kodzie; alternatywnie mozna wywolac to wywolanie systemowe za pomoca syscall(2). Linux 2.4 i wczesniejsze W Linuksie 2.4 i wczesniejszych wywolanie systemowe init_module() bylo wyraznie odmienne: #include int init_module(const char *name, struct module *image); (Aplikacje w przestrzeni uzytkownika moga wykryc dostepna wersje init_module() przez wywolanie query_module(); to ostatnie wywolanie zawiedzie z bledem ENOSYS w Linuksie 2.6 i pozniejszych). Starsza wersja tego wywolania systemowego ladowala przesuniety obraz jadra, na ktory wskazywalo image do przestrzeni jadra i uruchamialo funkcje init modulu. To wywolujacy byl odpowiedzialny za udostepnienie przesunietego obrazu (od Linuksa 2.6, to wywolanie systemowe init_module() dokonuje przesuniecia). Obraz modulu rozpoczyna sie od struktury modulu, po ktorej nastepuja, odpowiednio, kod i dane. Od Linuksa 2.2 struktura modulu jest zdefiniowana nastepujaco: struct module { unsigned long size_of_struct; struct module *next; const char *name; unsigned long size; long usecount; unsigned long flags; unsigned int nsyms; unsigned int ndeps; struct module_symbol *syms; struct module_ref *deps; struct module_ref *refs; int (*init)(void); void (*cleanup)(void); const struct exception_table_entry *ex_table_start; const struct exception_table_entry *ex_table_end; #ifdef __alpha__ unsigned long gp; #endif }; Wszystkie pola wskazujace, oprocz next i refs, powinny wskazywac na adresy w ciele modulu i zostac zainicjalizowane odpowiednio dla przestrzeni adresowej jadra, tzn. przesuniete wraz z reszta modulu. UWAGI Informacje o obecnie zaladowanych modulach sa dostepne w /proc/modules oraz w strukturze plikow zawartej w podkatalogach, przypisanych poszczegolnym modulom, w katalogu /sys/module. Wiecej przydatnych informacji ,,od kuchni" znajduje sie w pliku zrodel jadra Linux include/linux/module.h. ZOBACZ TAKZE create_module(2), delete_module(2), query_module(2), lsmod(8), modprobe(8) TLUMACZENIE Autorami polskiego tlumaczenia niniejszej strony podrecznika sa: Andrzej Krzysztofowicz i Michal Kulach Niniejsze tlumaczenie jest wolna dokumentacja. Blizsze informacje o warunkach licencji mozna uzyskac zapoznajac sie z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje sie ZADNEJ ODPOWIEDZIALNOSCI. Bledy w tlumaczeniu strony podrecznika prosimy zglaszac na adres listy dyskusyjnej . Linux man-pages 6.9.1 2 maja 2024 r. init_module(2)