Autor standardowej biblioteki C Cosmopolitan i platformy Redbean ogłosił wdrożenie mechanizmu izolacji pledge() dla systemu Linux. Początkowo pledge został opracowany przez projekt OpenBSD i pozwala selektywnie zablokować aplikacjom dostęp do nieużywanych wywołań systemowych (dla aplikacji tworzy się coś w rodzaju białej listy wywołań systemowych, podczas gdy inne wywołania są zabronione). W przeciwieństwie do dostępnych w systemie Linux mechanizmów ograniczania dostępu do wywołań systemowych, takich jak seccomp, mechanizm pledge został pierwotnie zaprojektowany z myślą o maksymalnym uproszczeniu zastosowania.
Nieudana inicjatywa izolacji aplikacji podstawowego środowiska OpenBSD z użyciem mechanizmu systrace pokazała, że izolacja na poziomie poszczególnych wywołań systemowych jest zbyt skomplikowana i pracochłonna. W zamian zaproponowano pledge, który pozwalał tworzyć zasady izolacji bez zagłębiania się w szczegóły i manipulując gotowymi klasami dostępu. Na przykład proponowane są klasy stdio (wejście/wyjście), rpath (tylko do odczytu plików), wpath (zapis plików), cpath (tworzenie plików), tmppath (praca z plikami tymczasowymi), inet (gniazda sieciowe), unix (gniazda unixowe), dns (rozwiązywanie DNS), getpw (dostęp do bazy użytkowników w trybie odczytu), ioctl (wywołanie ioctl), proc (zarządzanie procesami), exec (uruchamianie procesów) i id (zarządzanie uprawnieniami).
Reguły pracy z wywołaniami systemowymi określane są w formie adnotacji, które zawierają listę dozwolonych klas wywołań systemowych oraz tablicę ścieżek do plików, do których zezwolony jest dostęp. Po skonstruowaniu i uruchomieniu zmodyfikowanej aplikacji, jądro przejmuje kontrolę nad przestrzeganiem ustalonych zasad.
Osobno rozwijana jest implementacja pledge dla FreeBSD, która różni się możliwością izolacji aplikacji bez wprowadzania zmian w ich kodzie, podczas gdy w OpenBSD wywołanie pledge jest ukierunkowane na ścisłą integrację z podstawowym środowiskiem i dodawanie adnotacji do kodu każdej aplikacji.
Programiści portu pledge dla systemu Linux wzorowali się na przykładzie FreeBSD i zamiast wprowadzać zmiany w kodzie, przygotowali narzędzie-rozszerzenie pledge.com, które umożliwia nałożenie ograniczeń bez modyfikacji 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 wykonać „./pledge.com -p ‘stdio rpath inet thread’ curl http://example.com”.
Narzędzie pledge działa we wszystkich dystrybucjach Linuxa, zaczynając od RHEL6, i nie wymaga dostępu root. Dodatkowo, na podstawie biblioteki cosmopolitan, dostępne jest API do zarządzania ograniczeniami w kodzie programów w języku C, co pozwala na tworzenie enklaw do selektywnego ograniczania dostępu związane z określonymi funkcjami aplikacji.
Implementacja nie wymaga zmian w jądrze — ograniczenia pledge są tłumaczone na zasady SECCOMP BPF i przetwarzane za pomocą natywnego mechanizmu izolacji wywołań systemowych w Linuxie. Na przykład, wywołanie pledge("stdio rpath", 0) zostanie przekształcone w 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(args[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
