Proyek untuk mem-porting mekanisme isolasi janji ke Linux

Penulis pustaka C standar Cosmopolitan dan platform Redbean telah mengumumkan penerapan mekanisme isolasi janji() untuk Linux. Pledge awalnya dikembangkan oleh proyek OpenBSD dan memungkinkan Anda untuk secara selektif melarang aplikasi mengakses panggilan sistem yang tidak digunakan (semacam daftar putih panggilan sistem dibentuk untuk aplikasi tersebut, dan panggilan lainnya dilarang). Berbeda dengan mekanisme pembatasan akses panggilan sistem yang tersedia di Linux, seperti seccomp, mekanisme janji pada awalnya dirancang agar mudah digunakan.

Inisiatif yang gagal untuk mengisolasi aplikasi di lingkungan dasar OpenBSD menggunakan mekanisme systrace menunjukkan bahwa isolasi pada tingkat panggilan sistem individual terlalu rumit dan memakan waktu. Sebagai alternatif, sebuah janji diusulkan, yang memungkinkan pembuatan aturan isolasi tanpa merinci dan memanipulasi kelas akses yang sudah jadi. Misalnya, kelas yang ditawarkan adalah stdio (input/output), rpath (file read-only), wpath (menulis file), cpath (membuat file), tmppath (bekerja dengan file sementara), inet (soket jaringan), unix ( soket unix), dns (resolusi DNS), getpw (akses baca ke database pengguna), ioctl (panggilan ioctl), proc (manajemen proses), exec (peluncuran proses) dan id (manajemen hak akses).

Aturan untuk bekerja dengan panggilan sistem ditentukan dalam bentuk anotasi, termasuk daftar kelas panggilan sistem yang diizinkan dan serangkaian jalur file yang aksesnya diizinkan. Setelah membangun dan meluncurkan aplikasi yang dimodifikasi, kernel mengambil alih pekerjaan memantau kepatuhan terhadap aturan yang ditentukan.

Implementasi janji terpisah sedang dikembangkan untuk FreeBSD, yang dibedakan dengan kemampuan untuk mengisolasi aplikasi tanpa membuat perubahan pada kodenya, sedangkan di OpenBSD panggilan janji ditujukan untuk integrasi yang erat dengan lingkungan dasar dan menambahkan anotasi ke kode masing-masing. aplikasi.

Pengembang port janji untuk Linux mengambil contoh FreeBSD dan, alih-alih membuat perubahan pada kode, menyiapkan utilitas tambahan janji.com yang memungkinkan Anda menerapkan pembatasan tanpa mengubah kode aplikasi. Misalnya, untuk menjalankan utilitas curl dengan akses hanya ke kelas panggilan sistem stdio, rpath, inet dan threadtdio, jalankan saja β€œ./pledge.com -p 'stdio rpath inet thread' curl http://example.com”.

Utilitas janji berfungsi di semua distribusi Linux yang dimulai dengan RHEL6 dan tidak memerlukan akses root. Selain itu, berdasarkan perpustakaan kosmopolitan, API disediakan untuk mengelola pembatasan kode program dalam bahasa C, yang memungkinkan, antara lain, membuat enklave untuk membatasi akses secara selektif sehubungan dengan fungsi aplikasi tertentu.

Implementasinya tidak memerlukan perubahan pada kernel - pembatasan janji diterjemahkan ke dalam aturan SECCOMP BPF dan diproses menggunakan mekanisme isolasi panggilan sistem Linux asli. Misalnya, panggilan janji("stdio rpath", 0) akan dikonversi ke filter 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*/ /* filter berikutnya */ };

Sumber: opennet.ru

Tambah komentar