Der Autor der Standard-C-Bibliothek Cosmopolitan und der Plattform Redbean hat die Implementierung des Isolationsmechanismus pledge() fĂŒr Linux bekannt gegeben. UrsprĂŒnglich wurde pledge vom OpenBSD-Projekt entwickelt und ermöglicht es, Anwendungen selektiv den Zugriff auf nicht benötigte Systemaufrufe zu verweigern (es wird eine Art Whitelist fĂŒr Systemaufrufe erstellt, wĂ€hrend andere Aufrufe blockiert werden). Im Gegensatz zu den in Linux verfĂŒgbaren Mechanismen zur BeschrĂ€nkung des Zugriffs auf Systemaufrufe, wie seccomp, wurde der pledge-Mechanismus von Anfang an mit dem Ziel entwickelt, die Anwendung zu vereinfachen.
Die fehlgeschlagene Initiative zur Isolierung von Anwendungen in der Basisumgebung von OpenBSD unter Verwendung des Systrace-Mechanismus hat gezeigt, dass die Isolierung auf der Ebene einzelner Systemaufrufe zu komplex und zeitaufwendig ist. Als Alternative wurde pledge vorgeschlagen, mit dem Regeln zur Isolierung erstellt werden können, ohne sich in Details vertiefen und mit vordefinierten Zugriffsklassen manipulieren zu mĂŒssen. Beispielsweise werden die Klassen stdio (Ein-/Ausgabe), rpath (nur Lesezugriff auf Dateien), wpath (Schreibzugriff auf Dateien), cpath (Dateierstellung), tmppath (Umgang mit temporĂ€ren Dateien), inet (Netzwerksockets), unix (Unix-Sockets), dns (DNS-Resolution), getpw (Lesezugriff auf die Benutzerdatenbank), ioctl (ioctl-Aufruf), proc (Prozessverwaltung), exec (Prozessstart) und id (Zugriffsrechteverwaltung) angeboten.
Die Regeln fĂŒr den Umgang mit Systemaufrufen werden in Form von Annotationen festgelegt, die eine Liste der erlaubten Klassen von Systemaufrufen und ein Array von Dateipfaden enthalten, zu denen der Zugriff erlaubt ist. Nach der Erstellung und dem Start der modifizierten Anwendung ĂŒbernimmt der Kernel die Kontrolle ĂŒber die Einhaltung der festgelegten Regeln.
Die Implementierung von pledge fĂŒr FreeBSD entwickelt sich unabhĂ€ngig weiter. Diese ermöglicht die Isolierung von Anwendungen, ohne deren Code zu Ă€ndern, wĂ€hrend der Aufruf von pledge in OpenBSD eine enge Integration mit der Basisumgebung anstrebt und Anmerkungen im Code jeder Anwendung hinzufĂŒgt.
Die Entwickler des pledge-Ports fĂŒr Linux haben sich ein Beispiel an FreeBSD genommen und statt Ănderungen am Code die Overlay-Utility pledge.com erstellt. Diese ermöglicht die Anwendung von EinschrĂ€nkungen, ohne den Anwendungs-Code zu verĂ€ndern. Zum Beispiel genĂŒgt es, um die curl-Utility mit Zugang nur zu den Klassen der Systemaufrufe stdio, rpath, inet und threadstdio auszufĂŒhren, â./pledge.com -p 'stdio rpath inet thread' curl http://example.comâ einzugeben.
Die Utility pledge funktioniert in allen Linux-Distributionen, beginnend mit RHEL6, und benötigt keinen Root-Zugriff. ZusÀtzlich wird auf Basis der Bibliothek cosmopolitan eine API bereitgestellt, um EinschrÀnkungen im C-Code zu verwalten, die unter anderem die Erstellung von Enklaven ermöglichen, um den Zugang zu bestimmten Funktionen der Anwendung selektiv einzuschrÀnken.
Die Implementierung erfordert keine Ănderungen am Kernel â die Pledge-EinschrĂ€nkungen werden in die SECCOMP BPF-Regeln ĂŒberfĂŒhrt und mit dem nativen Linux-Mechanismus zur Isolation von Systemaufrufen verarbeitet. Zum Beispiel wird der Aufruf pledge("stdio rpath", 0) in den BPF-Filter umgewandelt 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 */ };
Quelle: opennet.ru
