Projekt przeniesienia mechanizmu izolacji zobowiązań do systemu Linux

Autor standardowej biblioteki C Cosmopolitan i platformy Redbean zapowiedział wdrożenie mechanizmu izolacji zastaw() dla systemu Linux. Pledge został pierwotnie opracowany w ramach projektu OpenBSD i umożliwia selektywne blokowanie aplikacjom dostępu do nieużywanych wywołań systemowych (dla aplikacji tworzony jest rodzaj białej listy wywołań systemowych, a inne wywołania są zabronione). W przeciwieństwie do mechanizmów ograniczających wywołania systemowe dostępnych w Linuksie, takich jak seccomp, mechanizm zastawu został pierwotnie zaprojektowany tak, aby był tak prosty, jak to tylko możliwe.

Nieudana inicjatywa izolowania aplikacji w środowisku bazowym OpenBSD za pomocą mechanizmu systrace pokazała, że ​​izolacja na poziomie poszczególnych wywołań systemowych była zbyt złożona i czasochłonna. Alternatywnie zaproponowano zastaw, który umożliwił stworzenie reguł izolacji bez wchodzenia w szczegóły i manipulacji gotowymi klasami dostępu. Na przykład oferowane klasy to stdio (wejścia/wyjścia), rpath (pliki tylko do odczytu), wpath (zapis plików), cpath (tworzenie plików), tmppath (praca z plikami tymczasowymi), inet (gniazda sieciowe), unix ( gniazda unix), dns (rozpoznawanie DNS), getpw (dostęp do odczytu bazy danych użytkowników), ioctl (wywołanie ioctl), proc (zarządzanie procesami), exec (uruchamianie procesu) i id (zarządzanie prawami dostępu).

Zasady pracy z wywołaniami systemowymi są określone w formie adnotacji, zawierających listę dozwolonych klas wywołań systemowych oraz tablicę ścieżek plików, do których dozwolony jest dostęp. Po zbudowaniu i uruchomieniu zmodyfikowanej aplikacji jądro przejmuje pracę monitorowania zgodności z określonymi regułami.

Dla FreeBSD rozwijana jest osobna implementacja zastawu, która wyróżnia się możliwością izolowania aplikacji bez dokonywania zmian w ich kodzie, natomiast w OpenBSD wywołanie zastawu ma na celu ścisłą integrację ze środowiskiem bazowym i dodanie adnotacji do kodu każdego aplikacja.

Twórcy portu zastawu dla Linuksa wzięli przykład z FreeBSD i zamiast wprowadzać zmiany w kodzie, przygotowali dodatek do narzędzia zastaw.com, który pozwala na nakładanie ograniczeń bez zmiany kodu aplikacji. Na przykład, aby uruchomić narzędzie curl z dostępem tylko do klas wywołań systemowych stdio, rpath, inet i threadstdio, wystarczy uruchomić „./pledge.com -p 'stdio rpath inet thread' curl http://example.com”.

Narzędzie zastawu działa na wszystkich dystrybucjach Linuksa, począwszy od RHEL6 i nie wymaga dostępu do konta root. Dodatkowo w oparciu o bibliotekę kosmopolityczną udostępniono API umożliwiające zarządzanie ograniczeniami w kodzie programu w języku C, które pozwala m.in. na tworzenie enklaw służących do selektywnego ograniczania dostępu w odniesieniu do określonych funkcji aplikacji.

Implementacja nie wymaga zmian w jądrze - ograniczenia zastawów są tłumaczone na reguły SECCOMP BPF i przetwarzane przy użyciu natywnego mechanizmu izolacji wywołań systemowych Linuksa. Na przykład wywołanie zastaw("stdio rpath", 0) zostanie skonwertowane na filtr BPF static const struct sock_filter kFilter[] = { /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall, 0, 14 - 1 ), / * L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])), /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0), /* L3* / BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4), /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(argumenty[1])), /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800), /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0), /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8) , /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0), /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 12 - 11, 0), /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 - 11), /*L12*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* następny filtr */ };

Źródło: opennet.ru

Dodaj komentarz