Sebuah layanan dapat memberikan instance io_uring kepada kode yang hanya perlu menjalankan kelas operasi asinkron yang sempit. Ring itu sendiri mendukung banyak opcode submission dan perintah registration. Jika pembatasan hanya bergantung pada kode aplikasi agar tidak memakai operasi tertentu, permukaan yang diizinkan tetap berupa konvensi, bukan properti yang ditegakkan kernel.

Linux menyediakan mekanisme yang lebih ketat melalui IORING_REGISTER_RESTRICTIONS. Ring yang dibuat dengan IORING_SETUP_R_DISABLED dapat menerima sekumpulan pembatasan sebelum dapat dipakai untuk submission. Proses kemudian mengaktifkan ring dengan IORING_REGISTER_ENABLE_RINGS. Sejak titik itu, kernel mengevaluasi operasi terhadap pembatasan yang telah didaftarkan.

Properti keamanannya bersifat temporal sekaligus fungsional: kebijakan dipasang ketika ring belum dapat mengirim pekerjaan, lalu ring berpindah ke keadaan aktif dengan kebijakan yang sudah tetap.

Pembatasan bekerja pada antarmuka ring

API pembatasan tidak mendeskripsikan path filesystem, tujuan jaringan, identitas proses, atau isi data. Mekanisme ini membatasi bagian tertentu dari antarmuka io_uring. Sebuah entri pembatasan dapat mengizinkan opcode submission tertentu, opcode registration tertentu, atau flag submission queue entry tertentu.

Jenis pembatasan yang relevan mencakup IORING_RESTRICTION_SQE_OP, IORING_RESTRICTION_REGISTER_OP, IORING_RESTRICTION_SQE_FLAGS_ALLOWED, dan IORING_RESTRICTION_SQE_FLAGS_REQUIRED. Efeknya adalah menetapkan kelas request yang diterima ring setelah aktivasi.

Karakteristik tersebut membuat mekanisme ini cocok untuk mengurangi permukaan antarmuka. Sebagai contoh, komponen yang memerlukan pembacaan asinkron dapat menerima ring dengan opcode SQE yang lebih sempit daripada seluruh set yang didukung kernel aktif. Request di luar set yang diizinkan ditolak, bukan sekadar dihindari oleh library pembungkus.

Batas ini berbeda dari otorisasi pada resource tujuan. Mengizinkan opcode pembacaan tidak memberikan akses ke sebuah file. Pemeriksaan kredensial, descriptor, filesystem, dan pemeriksaan kernel lain tetap berlaku pada operasi tersebut. Sebaliknya, proses yang sudah memiliki otoritas resource luas tidak kehilangan otoritas itu hanya karena satu ring memiliki set opcode terbatas; jalur system call lain masih dapat tersedia kecuali dibatasi secara terpisah.

Keadaan nonaktif menutup race saat pemasangan kebijakan

IORING_SETUP_R_DISABLED membuat ring dalam keadaan yang belum menerima submission. Hal ini penting ketika ring dirancang untuk melintasi batas kepercayaan.

Tanpa fase setup nonaktif, rancangan yang lebih dulu membuat ring dapat digunakan lalu mencoba mempersempitnya akan memiliki interval ketika antarmuka yang lebih luas sudah aktif. Thread lain yang berbagi akses ke ring berpotensi mengirim pekerjaan pada interval tersebut. Batas keamanan yang baru muncul setelah aktivasi lebih lemah daripada batas yang sudah ada saat transisi menuju keadaan aktif.

Alur pembatasan membalik urutan tersebut:

io_uring_setup(..., IORING_SETUP_R_DISABLED)
        |
        v
IORING_REGISTER_RESTRICTIONS
        |
        v
IORING_REGISTER_ENABLE_RINGS
        |
        v
ring terbatas menerima submission

Pembatasan harus didaftarkan sebelum ring diaktifkan. Setelah ring aktif, set pembatasannya tidak dapat diganti dengan kebijakan baru melalui urutan setup yang sama. Transisi satu arah ini berguna ketika komponen setup berprivilege menyiapkan ring lalu memberikan akses kepada komponen dengan tingkat kepercayaan lebih rendah.

Komponen setup tetap harus melindungi proses serah terima itu sendiri. Jika komponen yang kurang dipercaya juga mempertahankan ring tanpa pembatasan, dapat membuat ring lain, atau dapat menjalankan operasi setara melalui system call biasa, ring terbatas bukan sandbox lengkap.

Allowlist ditentukan oleh entri eksplisit

Set pembatasan paling berguna ketika diperlakukan sebagai allowlist untuk fitur antarmuka yang benar-benar diperlukan konsumen. Mengizinkan opcode SQE menyatakan bahwa ring boleh menerima kelas operasi tersebut. Mengizinkan opcode registration mengontrol perintah registration yang tetap tersedia pada ring. Pembatasan flag dapat mempersempit perilaku SQE lebih lanjut.

Dimensi tersebut penting secara terpisah. Set opcode SQE yang sempit tidak otomatis berarti permukaan registration juga sempit. Rancangan yang mendelegasikan ring perlu memperhitungkan operasi registration yang dapat mengubah resource atau perilaku eksekusi ring, bukan hanya request I/O yang terlihat di submission queue.

Kebijakan flag juga memerlukan ketepatan. IORING_RESTRICTION_SQE_FLAGS_ALLOWED mendeskripsikan flag yang boleh muncul, sedangkan IORING_RESTRICTION_SQE_FLAGS_REQUIRED mendeskripsikan flag yang wajib muncul. Kebijakan dengan demikian dapat menolak opcode yang sebenarnya diizinkan ketika flag SQE tidak memenuhi kondisi terdaftar.

Ini adalah kontrak antarmuka yang ditegakkan saat request diterima. Mekanisme tersebut bukan validator semantik untuk seluruh operasi. IORING_OP_READ yang diizinkan tetap membawa file descriptor, offset, buffer, dan length yang validitas serta otorisasinya dievaluasi oleh jalur operasi normal.

Versi kernel dan ketersediaan opcode tetap menjadi persoalan terpisah

Entri pembatasan menyebut operasi io_uring atau perintah registration, tetapi dukungan terhadap fitur itu tetap bergantung pada kernel yang sedang berjalan. Kebijakan pembatasan tidak dapat membuat opcode yang tidak didukung menjadi tersedia. Aplikasi yang berjalan pada beberapa versi kernel perlu memperlakukan deteksi kapabilitas dan definisi kebijakan sebagai dua pekerjaan terpisah.

Pembedaan sebaliknya juga penting. Kernel yang lebih baru dapat mendukung opcode io_uring tambahan, tetapi allowlist pembatasan yang sudah ditetapkan tidak otomatis meluas hanya karena kernel memperoleh fitur baru. Ini merupakan properti yang berguna untuk ring terdelegasi: pertumbuhan fitur kernel tidak harus berarti pertumbuhan permukaan operasi yang diterima ring.

Pembuatan kebijakan tetap perlu dikaitkan dengan operasi tepat yang akan dijalankan aplikasi. Konfigurasi yang disalin dari runtime lain dapat gagal secara tertutup dengan menolak operasi yang dibutuhkan, atau terlalu luas jika mengizinkan fitur yang tidak pernah dipakai komponen saat ini.

Pembatasan ring tidak menggantikan confinement proses

Interpretasi terkuat atas mekanisme ini juga merupakan interpretasi yang paling sempit. Pembatasan io_uring mengatur operasi yang diterima ring tertentu. Mekanisme ini secara umum tidak mencegah proses menjalankan system call biasa, membuka descriptor lain, memakai ring lain, atau berkomunikasi melalui kanal IPC lain.

Rancangan confinement pada tingkat proses dapat menggabungkan pembatasan ring dengan kontrol seperti seccomp, Landlock, namespace, pengurangan capability, atau arsitektur pemisahan privilege. Setiap mekanisme mencakup batas yang berbeda. Pembatasan ring bernilai ketika ring itu sendiri didelegasikan atau dibagikan dan permukaan operasi asinkronnya harus tetap lebih sempit daripada seluruh set fitur io_uring milik kernel.

Pemisahan ini mencegah kekeliruan arsitektural: menyamakan antarmuka submission yang dibatasi dengan proses yang dibatasi. Yang pertama dapat menjadi komponen dari yang kedua, tetapi tidak membentuk confinement proses dengan sendirinya.

Delegasi membuat permukaan tetap bernilai secara operasional

Mekanisme ini menjadi sangat relevan ketika satu komponen melakukan setup berprivilege dan komponen lain menjalankan I/O berkelanjutan. Sisi setup dapat membuat ring nonaktif, mendaftarkan hanya operasi antarmuka yang diperlukan, mengaktifkannya, lalu mentransfer akses sesuai model IPC dan descriptor aplikasi.

Pada titik tersebut, komponen penerima tidak dapat memperluas ring hanya dengan meminta opcode SQE yang tidak tercantum dalam set pembatasan. Kernel menolak request pada batas ring. Hal ini mengurangi ketergantungan pada kepatuhan komponen penerima terhadap library pembungkus tingkat tinggi.

Hasil keamanan tetap bergantung pada grafik otoritas di sekitarnya. File descriptor, system call, kredensial, namespace, dan relasi IPC lain milik penerima dapat menyediakan kapabilitas di luar ring. Rancangan yang presisi karena itu menyebut ring terbatas sebagai salah satu batas operasi yang ditegakkan di antara beberapa batas lain, bukan sebagai batas privilege umum bagi proses.

Transisi tetap dari setup nonaktif menuju aktivasi terbatas merupakan properti utamanya. Sistem dapat menetapkan kosakata operasi yang diterima ring sebelum submission apa pun berhasil, lalu mempertahankan kosakata tersebut selama pemakaian berikutnya. Untuk I/O asinkron yang didelegasikan, mekanisme ini memberikan batas konkret yang ditegakkan kernel dengan cakupan yang dapat dinyatakan dan diaudit.