Proyekto upang i-port ang mekanismo ng paghihiwalay ng pangako sa Linux

Ang may-akda ng Cosmopolitan standard C library at ang Redbean platform ay inihayag ang pagpapatupad ng pledge() isolation mechanism para sa Linux. Ang Pledge ay orihinal na binuo ng proyekto ng OpenBSD at nagbibigay-daan sa iyo na piliing ipagbawal ang mga application sa pag-access ng mga hindi nagamit na mga tawag sa system (isang uri ng puting listahan ng mga tawag sa system ay nabuo para sa aplikasyon, at ang iba pang mga tawag ay ipinagbabawal). Hindi tulad ng system call restriction mechanisms na available sa Linux, gaya ng seccomp, ang pledge mechanism ay orihinal na idinisenyo upang maging simple hangga't maaari.

Ang nabigong inisyatiba upang ihiwalay ang mga application sa OpenBSD base environment gamit ang mekanismo ng systrace ay nagpakita na ang paghihiwalay sa antas ng mga indibidwal na tawag sa system ay masyadong kumplikado at nakakaubos ng oras. Bilang kahalili, iminungkahi ang isang pangako, na naging posible na lumikha ng mga panuntunan sa paghihiwalay nang hindi naglalagay ng mga detalye at nagmamanipula ng mga nakahanda nang klase sa pag-access. Halimbawa, ang mga klase na inaalok ay stdio (input/output), rpath (read-only na mga file), wpath (magsulat ng mga file), cpath (lumikha ng mga file), tmppath (gumana sa mga pansamantalang file), inet (network socket), unix ( unix sockets), dns (DNS resolution), getpw (read access sa database ng user), ioctl (ioctl call), proc (process management), exec (process launch) at id (access rights management).

Ang mga panuntunan para sa pagtatrabaho sa mga system call ay tinukoy sa anyo ng mga anotasyon, kabilang ang isang listahan ng mga pinapayagang klase ng mga tawag sa system at isang hanay ng mga path ng file kung saan pinapayagan ang pag-access. Pagkatapos buuin at ilunsad ang binagong application, ang kernel ang namamahala sa gawain ng pagsubaybay sa pagsunod sa mga tinukoy na panuntunan.

Ang isang hiwalay na pagpapatupad ng pledge ay binuo para sa FreeBSD, na nakikilala sa pamamagitan ng kakayahang ihiwalay ang mga application nang hindi gumagawa ng mga pagbabago sa kanilang code, habang sa OpenBSD ang pledge call ay naglalayong mahigpit na pagsasama sa base na kapaligiran at pagdaragdag ng mga anotasyon sa code ng bawat isa. aplikasyon.

Ang mga nag-develop ng pledge port para sa Linux ay kumuha ng halimbawa ng FreeBSD at, sa halip na gumawa ng mga pagbabago sa code, naghanda ng isang add-on na utility pledge.com na nagpapahintulot sa iyo na maglapat ng mga paghihigpit nang hindi binabago ang application code. Halimbawa, para patakbuhin ang curl utility na may access lang sa stdio, rpath, inet at threadstdio system call classes, patakbuhin lang ang β€œ./pledge.com -p 'stdio rpath inet thread' curl http://example.com”.

Gumagana ang pledge utility sa lahat ng distribusyon ng Linux simula sa RHEL6 at hindi nangangailangan ng root access. Bukod pa rito, batay sa cosmopolitan library, ang isang API ay ibinibigay para sa pamamahala ng mga paghihigpit sa program code sa wikang C, na nagbibigay-daan, bukod sa iba pang mga bagay, na lumikha ng mga enclave para sa piling paghihigpit sa pag-access na may kaugnayan sa ilang mga function ng application.

Ang pagpapatupad ay hindi nangangailangan ng mga pagbabago sa kernel - ang mga paghihigpit sa pledge ay isinalin sa mga panuntunan ng SECCOMP BPF at pinoproseso gamit ang katutubong Linux system call isolation mechanism. Halimbawa, ang call pledge("stdio rpath", 0) ay iko-convert sa isang 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 - , /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[8])), /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 9, 0 - 12, 10), /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 10, 6 - 12, 11), /*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 11, 17, 0 - 13), /*L11*/ BPF_KPF | SECCOMP_RET_ALLOW), /*L12*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L13*/ /* susunod na filter */ };

Pinagmulan: opennet.ru

Magdagdag ng komento