1 poin oleh GN⁺ 2024-04-28 | 1 komentar | Bagikan ke WhatsApp

Gambaran umum IPC Hubris

  • Hubris menggunakan kernel kecil yang tidak bergantung pada aplikasi, dan sebagian besar kode (driver, logika aplikasi, stack jaringan, dll.) berada dalam task terisolasi yang dikompilasi secara terpisah
  • Task-task ini dapat saling berkomunikasi menggunakan sistem perpesanan lintas-task (IPC)
  • IPC Hubris terdiri dari 3 operasi inti yang diimplementasikan di kernel (RECV, SEND, REPLY)
    • RECV: mengambil pesan masuk dengan prioritas tertinggi, atau memblokir sampai ada pesan yang tiba
    • SEND: mengirim pesan dan kontrol ke task penerima lalu menghentikan pemanggil. Pemanggil berpindah ke status menunggu sampai menerima respons
    • REPLY: menyampaikan respons ke task yang sebelumnya menggunakan SEND agar dapat melanjutkan eksekusi

Mode kegagalan baru yang menarik

  • Karena IPC melintasi batas task dan task Hubris adalah program yang dikompilasi terpisah, perlu berhati-hati saat membuat asumsi pada IPC yang setara dengan asumsi compiler saat melakukan pemanggilan fungsi
  • Di Hubris, semua task yang berperan sebagai server IPC harus menangani potensi kesalahan berikut:
    • menerima pesan dengan antarmuka dan kode operasi yang tidak sesuai
    • menerima kumpulan byte yang tidak bisa ditafsirkan alih-alih tipe pesan yang diharapkan, atau menerima pesan yang terlalu pendek maupun terlalu panjang
    • tidak menerima memori yang diperlukan (seperti memori yang dapat ditulisi)

Dalam program normal dan benar, situasi ini tidak terjadi

  • Dalam program Hubris yang normal, situasi yang disebutkan di atas tidak terjadi
  • Task saling terhubung melalui konfigurasi sistem build sehingga sulit tertukar satu sama lain
  • Klien dan server menggunakan kode Rust yang dihasilkan, sehingga dapat diasumsikan sistem tipe bekerja melintasi batas task

Kernel tidak mengizinkan situasi yang tidak masuk akal

  • Di Unix, jika prasyarat system call dilanggar maka kernel mengembalikan kode error kepada pemanggil, tetapi di Hubris task langsung dihancurkan
  • Kernel Hubris menyampaikan error ke task yang melanggar aturan kernel melalui konsep yang disebut Synthetic Fault
  • Di Hubris, ketika terjadi fault perangkat keras atau synthetic fault, task langsung dihentikan dan tidak dapat dipulihkan

Server juga tidak mengizinkan situasi yang tidak masuk akal

  • Melalui system call ke-13 dan yang paling tidak biasa, REPLY_FAULT, server dapat menyampaikan error ke klien
  • REPLY_FAULT mirip dengan REPLY, tetapi alih-alih menyampaikan pesan dan membuat task kembali dapat dijalankan, ia menyampaikan error dan menghentikan task tersebut
  • Dengan REPLY_FAULT, penanganan error IPC yang tidak perlu bisa dihindari. Program normal dapat berjalan seolah-olah masalah semacam itu tidak mungkin terjadi, dan program yang tidak normal bahkan tidak mendapat kesempatan untuk menangani error
  • REPLY_FAULT juga menyediakan cara baru untuk mendefinisikan dan mengimplementasikan error khusus aplikasi, seperti aturan kontrol akses

Opini GN⁺

  • REPLY_FAULT adalah mekanisme kuat yang memungkinkan server memicu panic! lintas-proses pada klien tanpa kerja sama dari sisi klien. Ini membuat Hubris menjadi sistem yang sangat memusuhi program berbahaya
  • Kekurangan REPLY_FAULT adalah pengujian fuzz menjadi sangat sulit. Task chaos engineering yang menghasilkan IPC atau system call acak akan langsung di-reset pada hampir semua perilaku
  • Namun, karena task Hubris yang normal tidak membuat pesan IPC secara dinamis, task tersebut dapat beroperasi tanpa pernah menyadari keberadaan REPLY_FAULT
  • Melalui REPLY_FAULT, server dapat secara acak memicu fault pada klien, tetapi penilaian terhadap hal ini masih belum sepenuhnya dilakukan
  • Penanganan error Hubris yang agresif membantu menemukan bug lebih awal dalam pengembangan, dan tidak seperti kode error, fault tidak bisa diabaikan
  • Menggunakan metode umum untuk menangani error IPC dapat menimbulkan overhead yang tidak perlu bahkan pada program normal. REPLY_FAULT tampak sebagai solusi elegan yang menghindari hal ini sekaligus merespons program yang tidak normal dengan tegas

1 komentar

 
GN⁺ 2024-04-28
Opini Hacker News

Ringkasannya sebagai berikut:

  • Muncul kekhawatiran apakah REPLY_FAULT menyebar secara berantai dan kerentanan yang ditimbulkannya

    • Dalam situasi A menunggu B, dan B menunggu C, perlu dipastikan apakah ketika C melakukan REPLY_FAULT, A juga ikut dihentikan
    • Jika ya, seluruh sistem bisa menjadi rentan
    • Jika SEND membentuk struktur siklik, sistem juga bisa tanpa sengaja menghentikan dirinya sendiri
  • REPLY_FAULT menyediakan cara untuk mendefinisikan dan mengimplementasikan error yang spesifik aplikasi, seperti kontrol akses

    • Ini berguna ketika sistemnya kecil, rapat, dan sebagian besar aplikasi ditulis oleh perancang sistem
    • Namun, saat diintegrasikan dengan kode pihak ketiga, ada kekhawatiran karena pihak lain bisa langsung menghentikan proses kapan saja
    • Di dunia ini ada banyak driver dan proses latar belakang berkualitas buruk yang ditulis oleh pengembang yang terus ditekan administrator
  • Dalam sistem tempat satu tim menulis seluruh kode, menyingkirkan klien yang mencurigakan bisa mempercepat iterasi

  • Hubris dapat dipandang sebagai kernel yang memungkinkan server melakukan efek yang tidak dapat ditangani klien

    • Ini membuat penggunaan ulang kode dan komposisi menjadi lebih sulit, tetapi menyederhanakan model eksekusi
    • Dalam sistem embedded statis, ini bisa menjadi kompromi yang tepat
  • Hubris dan Humility adalah teknologi yang ingin didalami, tetapi sulit karena keterbatasan waktu dan kewajiban

  • Dalam RFC April Mop tentang HTTP, diusulkan kode status HTTP 499 yang berarti "Anda seharusnya merasa malu"

    • Ini cocok dengan konteks seperti "hah... tapi sebenarnya masuk akal juga"
  • Mengutip pepatah Einstein, "Sesederhana mungkin, tetapi jangan terlalu sederhana," dan menunjukkan bahwa desain Hubris melanggar bagian yang kedua

    • Tidak tertarik pada lingkungan operasi yang sama sekali tidak mengizinkan kekacauan dunia nyata
  • Humility adalah nama yang sangat bagus untuk sebuah debugger

    • Banyak programmer menolak memakai debugger karena menganggap kode yang "baik" tidak perlu di-debug
  • Di Linux, Anda memang tidak bisa langsung mematikan program lain hanya dengan socket, tetapi dengan hak root Anda bisa menghentikan proses lain atau bahkan me-reboot sistem

    • Di container, hak root itu umum sehingga risiko seperti ini memang ada
  • Ini agak bertentangan dengan kebijaksanaan lama sistem jaringan: "bersikaplah longgar saat menerima dan ketat saat mengirim"

    • Namun, saat mengubah API sambil mempertahankan kompatibilitas program lama, mau tidak mau kita harus longgar saat menerima