Project om het belofte-isolatiemechanisme over te zetten naar Linux

De auteur van de Cosmopolitan standaard C-bibliotheek en het Redbean-platform heeft de implementatie aangekondigd van het belofte() isolatiemechanisme voor Linux. Pledge werd oorspronkelijk ontwikkeld door het OpenBSD-project en stelt u in staat selectief te verbieden dat applicaties toegang krijgen tot ongebruikte systeemaanroepen (er wordt een soort witte lijst met systeemaanroepen gevormd voor de applicatie, en andere oproepen zijn verboden). In tegenstelling tot de systeemoproepbeperkingsmechanismen die beschikbaar zijn in Linux, zoals seccomp, was het beloftemechanisme oorspronkelijk ontworpen om zo eenvoudig mogelijk te zijn.

Het mislukte initiatief om applicaties in de OpenBSD-basisomgeving te isoleren met behulp van het systrace-mechanisme toonde aan dat isolatie op het niveau van individuele systeemaanroepen te complex en tijdrovend was. Als alternatief werd een belofte voorgesteld, die het mogelijk maakte om isolatieregels te creëren zonder in details te treden en kant-en-klare toegangsklassen te manipuleren. De aangeboden klassen zijn bijvoorbeeld stdio (invoer/uitvoer), rpath (alleen-lezen bestanden), wpath (bestanden schrijven), cpath (bestanden maken), tmppath (werken met tijdelijke bestanden), inet (netwerksockets), unix ( unix sockets), dns (DNS-resolutie), getpw (leestoegang tot de gebruikersdatabase), ioctl (ioctl-aanroep), proc (procesbeheer), exec (proceslancering) en id (beheer van toegangsrechten).

Regels voor het werken met systeemaanroepen worden gespecificeerd in de vorm van annotaties, inclusief een lijst met toegestane klassen van systeemaanroepen en een reeks bestandspaden waar toegang is toegestaan. Na het bouwen en starten van de gewijzigde applicatie neemt de kernel het werk van het controleren van de naleving van de gespecificeerde regels over.

Voor FreeBSD wordt een afzonderlijke implementatie van belofte ontwikkeld, die zich onderscheidt door de mogelijkheid om applicaties te isoleren zonder wijzigingen in hun code aan te brengen, terwijl in OpenBSD de belofte-oproep gericht is op nauwe integratie met de basisomgeving en het toevoegen van annotaties aan de code van elke toepassing. sollicitatie.

De ontwikkelaars van de belofte-poort voor Linux namen het voorbeeld van FreeBSD en maakten, in plaats van wijzigingen in de code aan te brengen, een add-on-hulpprogramma belofte.com waarmee u beperkingen kunt toepassen zonder de applicatiecode te wijzigen. Om bijvoorbeeld het curl-hulpprogramma uit te voeren met alleen toegang tot de stdio-, rpath-, inet- en threadstdio-systeemaanroepklassen, voert u gewoon "./pledge.com -p 'stdio rpath inet thread' curl http://example.com" uit.

Het beloftehulpprogramma werkt op alle Linux-distributies beginnend met RHEL6 en vereist geen root-toegang. Bovendien is er, gebaseerd op de kosmopolitische bibliotheek, een API beschikbaar voor het beheren van beperkingen in programmacode in de C-taal, waarmee onder andere enclaves kunnen worden gemaakt voor het selectief beperken van de toegang met betrekking tot bepaalde applicatiefuncties.

De implementatie vereist geen wijzigingen aan de kernel - beloftebeperkingen worden vertaald in SECCOMP BPF-regels en verwerkt met behulp van het native Linux-systeemoproepisolatiemechanisme. De call belofte("stdio rpath", 0) wordt bijvoorbeeld geconverteerd naar een 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, UIT(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, UIT(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, UIT(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*/ /* volgend filter */ };

Bron: opennet.ru

Voeg een reactie