SCM_RIGHTS Memindahkan Otoritas File Descriptor Melalui Unix Socket
Sebuah layanan berprivilege dapat membuka file yang tidak dapat dibuka proses lain melalui pathname, lalu mengirim akses tersebut melalui Unix-domain socket. Proses penerima memperoleh file descriptor baru yang merujuk ke state open-file kernel yang sama. Tidak diperlukan lookup pathname kedua, dan kemampuan penerima untuk membuka path tersebut tidak dievaluasi ulang sebagai bagian dari transfer.
Properti itu membuat SCM_RIGHTS lebih dari sekadar fasilitas IPC. Mekanisme ini memindahkan capability kernel yang sudah terbentuk melewati batas proses. Keamanan bergantung pada kedua sisi pertukaran: pengirim harus membatasi descriptor yang boleh keluar dari domain otoritasnya, sedangkan penerima harus memperlakukan descriptor masuk sebagai objek berprivilege yang propertinya perlu divalidasi.
Transfer membawa referensi terbuka, bukan pathname
Di Linux, ancillary data yang dikirim dengan sendmsg() dapat memakai SOL_SOCKET dan SCM_RIGHTS untuk membawa file descriptor melalui Unix-domain socket. Penerima mendapatkannya melalui control message recvmsg().
Kernel tidak menserialisasi nomor descriptor itu sendiri sebagai identitas permanen. Nomor descriptor adalah indeks tabel yang lokal bagi proses. Operasi ini mengirim referensi ke open file description yang mendasarinya, lalu penerima memperoleh nomor descriptor yang dialokasikan pada tabel descriptornya sendiri.
Perbedaan ini memiliki konsekuensi keamanan langsung. Membuka /srv/private/report secara normal melibatkan resolusi pathname dan pemeriksaan izin yang relevan bagi proses pembuka. Menerima descriptor untuk file yang sudah terbuka tidak mengulangi operasi open tersebut. Otoritas yang diwujudkan oleh referensi terbuka sudah terbentuk sebelumnya.
Pola yang sama berlaku di luar regular file. File descriptor dapat merepresentasikan socket, pipe, objek event, direktori, device node, dan objek kernel lain yang didukung interface descriptor. Broker yang mengirim descriptor berarti mendelegasikan akses ke objek kernel, bukan sekadar membagikan nama file.
State open-file bersama dapat melewati batas proses
Descriptor yang diterima melalui SCM_RIGHTS merujuk ke open file description yang sama dengan descriptor yang diberikan pengirim. Untuk regular file, hal ini dapat mencakup file offset bersama dan file status flag yang terkait dengan open file description.
Kondisi tersebut berbeda dari dua proses yang masing-masing membuka pathname yang sama. Open independen biasanya membuat open file description terpisah meskipun pada akhirnya merujuk inode yang sama. Pengiriman descriptor mempertahankan relasi open-file yang sudah ada.
Penerima yang menganggap dirinya memiliki offset independen dapat mengganggu pengguna lain dari open file description yang sama. Demikian pula, perubahan file status flag melalui satu descriptor dapat memengaruhi operasi melalui descriptor lain yang terikat pada description tersebut. Descriptor flag seperti close-on-exec merupakan properti per-descriptor yang terpisah.
Batas keamanan dengan demikian juga menyangkut aliasing state. Delegasi dapat memberikan akses ke objek yang state open-file mutablenya juga terlihat di tempat lain.
Kontrol akses socket menentukan pihak yang dapat meminta delegasi
Broker descriptor biasanya mengekspos Unix-domain socket dan menentukan objek yang akan dibuka atas nama client. Endpoint socket menjadi batas otorisasi karena koneksi yang berhasil dapat menghasilkan otoritas yang tidak dapat diperoleh client secara langsung.
Permission filesystem pada pathname Unix socket dapat membatasi akses koneksi di Linux, tetapi otorisasi sering memerlukan pengikatan identitas yang lebih kuat daripada sekadar kemampuan menjangkau socket. Linux mendukung mekanisme credential peer untuk Unix socket, termasuk SO_PEERCRED bagi peer yang terhubung dan credential ancillary data ketika dikonfigurasi untuk tujuan tersebut.
Credential tersebut mengidentifikasi peer sesuai semantik kernel yang terdokumentasi; credential tidak otomatis menetapkan hak pada level aplikasi. Broker tetap memerlukan kebijakan yang memetakan identitas proses atau identitas layanan terautentikasi ke descriptor spesifik yang diminta.
Mengirim descriptor hanya setelah memeriksa bahwa client dapat terhubung dapat mereduksi kebijakan resource yang terperinci menjadi kebijakan akses socket yang kasar. Hal itu mungkin disengaja untuk kelompok layanan yang dikonfin secara ketat, tetapi tetap merupakan keputusan deployment, bukan properti yang diberikan SCM_RIGHTS.
Penerima juga memerlukan kebijakan penerimaan descriptor
Sisi penerima memiliki persoalan trust tersendiri. Descriptor masuk bukan data aplikasi yang mendeskripsikan dirinya sendiri. Nilai integer descriptor tidak menyatakan tipe objek, mode akses, asal, atau kesesuaiannya untuk operasi yang akan dilakukan penerima.
Protokol yang mengharapkan regular file dapat memeriksa metadata descriptor sebelum digunakan dan menolak tipe objek di luar kontrak tersebut. Aplikasi juga mungkin perlu memverifikasi mode akses, properti filesystem yang diharapkan, atau invariant lain yang relevan bagi operasi. Pemeriksaan tepatnya bergantung pada kelas objek dan threat model.
Hal ini penting ketika proses dengan trust lebih rendah dapat mengirim descriptor ke layanan dengan privilege lebih tinggi. Menerima direktori, device, socket, atau objek lain yang tidak diharapkan dapat mengarahkan operasi berikutnya ke interface kernel yang tidak dimaksudkan layanan untuk diekspos melalui jalur IPC tersebut.
Validasi sebaiknya berfokus pada properti objek yang diterima, bukan membangun kembali trust dari pathname yang diklaim dan dikirim bersamanya. Pathname dalam pesan hanyalah data yang dikontrol peer dan belum tentu mengidentifikasi objek yang dirujuk descriptor.
Close-on-exec menjadi bagian dari containment
Descriptor yang diterima dapat bertahan setelah transaksi IPC dan juga dapat melewati execve() berikutnya kecuali close-on-exec diaktifkan. Linux menyediakan MSG_CMSG_CLOEXEC untuk recvmsg(), yang menerapkan flag close-on-exec pada file descriptor yang diterima melalui SCM_RIGHTS.
Penerapan flag secara atomik saat penerimaan menghindari jendela pada program multithreaded ketika thread lain dapat menjalankan program baru di antara penerimaan descriptor dan pemanggilan fcntl() terpisah yang menetapkan FD_CLOEXEC.
Flag ini tidak mengurangi otoritas penerima saat ini atas descriptor. Fungsinya membatasi propagasi yang tidak disengaja ke program yang kemudian dieksekusi. Layanan yang menerima descriptor terdelegasi perlu menetapkan kebijakan inheritance secara eksplisit, bukan mengandalkan tahap cleanup berikutnya.
Parsing ancillary data termasuk bagian dari batas keamanan
SCM_RIGHTS tiba di area control data milik recvmsg(). Penerima menyediakan buffer terbatas untuk ancillary data, sehingga kode yang tangguh perlu menangani truncation dan struktur pesan alih-alih menganggap control message yang diharapkan selalu tiba utuh.
Di Linux, file descriptor berlebih dapat ditutup oleh kernel ketika ancillary data terpotong karena buffer penerima terlalu kecil. Meski ada perilaku tersebut, logika aplikasi tetap perlu menolak state protokol yang malformed atau tidak lengkap, bukan melanjutkan pemrosesan dengan kumpulan descriptor parsial.
Protokol perlu mendefinisikan jumlah descriptor yang diharapkan serta relasi antara descriptor dan payload pesan biasa. Ambiguitas di sini dapat mengubah detail transport menjadi kesalahan otorisasi: layanan dapat memvalidasi satu objek sementara kode berikutnya memakai objek lain jika urutan atau jumlah descriptor tidak menjadi bagian kontrak pesan.
Batas resource juga relevan. Linux membatasi jumlah file descriptor yang dapat dibawa dalam satu control message SCM_RIGHTS, dan batas descriptor proses membatasi penerimaan. Aplikasi perlu memperlakukan kegagalan transfer sebagai kondisi operasional normal, bukan menganggap delegasi selalu berhasil setelah otorisasi.
Delegasi mempersempit paparan pathname tetapi memperluas otoritas IPC
Pengiriman descriptor dapat memperkuat arsitektur ketika broker kecil memegang akses pathname dan worker dengan privilege lebih rendah hanya menerima objek yang diperlukan untuk suatu tugas. Worker tidak memerlukan permission direktori luas atau credential hanya untuk membuka ulang resource yang sudah dipilih broker.
Desain yang sama juga memusatkan otoritas pada broker dan kebijakan IPC-nya. Cacat confused deputy dalam pemilihan resource dapat menyerahkan descriptor valid kepada peer yang salah, melewati pemeriksaan filesystem yang semestinya memblokir open langsung. Kernel tetap menerapkan semantik descriptor secara benar; kegagalannya berada pada delegasi otoritas yang sudah terbentuk kepada pihak yang salah.
Desain yang kuat karena itu memperlakukan SCM_RIGHTS sebagai transfer capability. Pengirim mengotorisasi objek dan penerima secara spesifik, penerima memvalidasi kelas objek serta invariant protokol, ancillary data diparsing secara defensif, dan inheritance descriptor dibatasi. Dalam kondisi tersebut, pengiriman descriptor melalui Unix-domain socket dapat mengurangi akses filesystem ambient tanpa menganggap otoritas yang didelegasikan telah hilang.