A Szi könyvtár Cosmopolitan és a Redbean platform szerzője bejelentette a pledge() izolációs mechanizmus Linuxra való megvalósítását. Eredetileg a pledge az OpenBSD projekt keretében készült, és lehetővé teszi, hogy az alkalmazások számára szelektíven tiltva legyenek a nem használt rendszerhívások (az alkalmazás számára olyan fehérlistás jellegű rendszerhívások készülnek, amelyek a többi hívást blokkolják). A Linuxban elérhető rendszerhívás-korlátozási mechanizmusokkal, mint például a seccomp, ellentétben a pledge mechanizmust eredetileg a lehető legegyszerűbb alkalmazásra tervezték.
A systrace mechanizmus használatával végződött sikertelen OpenBSD alapú környezeti alkalmazásizolációs kezdeményezés megmutatta, hogy a különböző rendszerhívások szintjén történő izoláció túl bonyolult és időigényes. Alternatívaként a pledge jött létre, amely lehetővé tette az izolációs szabályok létrehozását anélkül, hogy a részletekbe belemennénk, és kész hozzáférési osztályokkal manipulálunk. Például a következő osztályokat javasolják: stdio (bemenet/kimenet), rpath (csak fájlok olvasása), wpath (fájlok írása), cpath (fájlok létrehozása), tmppath (ideiglenes fájlok kezelése), inet (hálózati socketek), unix (unix-socketek), dns (DNS feloldás), getpw (hozzáférés a felhasználói adatbázishoz), ioctl (ioctl hívás), proc (folyamatkezelés), exec (folyamatok indítása) és id (hozzáférési jogok kezelése).
A rendszerhívásokkal kapcsolatos szabályokat annotációk formájában határozzák meg, amelyek tartalmazzák a megengedett rendszerhívásosztályok listáját és a fájlok elérési útvonalait, ahová hozzáférést kapnak. A módosított alkalmazás összeállítása és futtatása után a kernel átveszi a megadott szabályok betartásának ellenőrzését.
Különösen a pledge FreeBSD-re való megvalósítása fejlődik, amely lehetővé teszi az alkalmazások izolációját anélkül, hogy a kódjukba változtatásokat kellene eszközölni, míg az OpenBSD-ben a pledge hívás a szoros integrációra összpontosít az alap környezettel, és megköveteli a kód annotálását minden alkalmazásnál.
A Linuxra való pledge port fejlesztői a FreeBSD példájára alapozva nem a kódban történő módosításokkal, hanem egy pledge.com nevű kiegészítő eszközzel készítették el, amely lehetővé teszi a korlátozások alkalmazását anélkül, hogy a kódot módosítani kellene. Például a curl segédprogram futtatásához, amely csak a stdio, rpath, inet és threadstdio hívás szolgáltatásokhoz biztosít hozzáférést, elegendő a parancs végrehajtása: './pledge.com -p 'stdio rpath inet thread' curl http://example.com'.
A pledge utility works on all Linux distributions starting from RHEL6 and does not require root access. Additionally, based on the cosmopolitan library, it provides an API for controlling constraints in C code, allowing for the creation of enclaves to selectively limit access tied to specific application functions.
The implementation does not require changes to the kernel — pledge constraints are translated into SECCOMP BPF rules and processed using the native Linux system call isolation mechanism. For example, the call pledge("stdio rpath", 0) will be converted into a BPF filter 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*/ /* next filter */ };
Forrás: opennet.ru
