Sebuah proses sandbox dapat memerlukan operasi yang tidak aman jika direpresentasikan sebagai aturan allow seccomp permanen. Operasi tersebut dapat bergantung pada kebijakan runtime, keadaan eksternal, atau resource yang seharusnya hanya diperiksa oleh komponen dengan privilese lebih tinggi. Mengizinkan system call tanpa syarat memperluas sandbox, sedangkan menolaknya menghilangkan fungsi yang dibutuhkan.

Linux menyediakan titik mediasi untuk kondisi ini melalui notifikasi pengguna seccomp. Filter seccomp dapat mengembalikan SECCOMP_RET_USER_NOTIF untuk call tertentu. Kernel kemudian memblokir task pemicu dan mengirim notifikasi melalui file descriptor listener. Supervisor membaca notifikasi itu dan mengirim respons yang menentukan disposisi langsung dari call yang dicegat.

Mekanisme ini memindahkan lokasi pengambilan keputusan, tetapi tidak menjadikan supervisor sebagai reference monitor kernel yang transparan. Notifikasi membawa snapshot metadata syscall, sementara memori proses dan keadaan descriptor dapat tetap berubah. Keamanan karena itu bergantung pada kebijakan seccomp sekaligus cara supervisor menangani keadaan yang dapat berubah antara pemeriksaan dan tindakan.

Descriptor listener adalah batas otoritas

Filter yang dipasang dengan SECCOMP_FILTER_FLAG_NEW_LISTENER dapat mengembalikan file descriptor listener kepada proses pemasang. Notifikasi yang dihasilkan oleh SECCOMP_RET_USER_NOTIF diterima melalui descriptor ini memakai ioctl notifikasi seccomp.

Descriptor tersebut bukan sekadar aliran event. Proses yang dapat mengoperasikan listener bisa memengaruhi apakah call yang dicegat gagal, mengembalikan nilai yang disediakan, atau dilanjutkan melalui kernel ketika continuation diminta dan didukung oleh flag respons. Kontrol atas listener karena itu merupakan bagian dari model otoritas sistem.

Arsitektur yang umum memisahkan task terbatas dari supervisor yang mempertahankan listener. Task terbatas berjalan di bawah filter; supervisor memegang data kebijakan dan menerima record notifikasi. Transfer descriptor, lifetime proses, dan privilese supervisor menjadi bagian dari batas keamanan, bukan detail implementasi sampingan.

Kernel tidak menyimpulkan kebijakan aplikasi. Kernel melaporkan nomor syscall yang dicegat, argumen, informasi identitas task, dan identifier notifikasi. Supervisor memberikan interpretasi kebijakan.

Identifier notifikasi melindungi keadaan task yang bergerak

Sebuah notifikasi memiliki identifier yang dapat divalidasi supervisor dengan SECCOMP_IOCTL_NOTIF_ID_VALID. Hal ini penting karena task target dapat keluar atau sebuah notifikasi dapat berhenti menjadi request aktif ketika supervisor sedang bekerja.

Validasi identifier menyediakan cara untuk memeriksa bahwa notifikasi masih merujuk pada request tertunda yang hidup sebelum supervisor melakukan efek samping eksternal. Validasi ini tidak membekukan seluruh keadaan userspace yang terkait dengan request. Pointer yang diteruskan sebagai argumen syscall tetap menunjuk ke memori yang dikendalikan sesuai model berbagi memori milik proses target.

Perbedaan itu penting untuk pathname, struktur alamat socket, dan argumen lain berbasis pointer. Membaca memori target sekali lalu bertindak berdasarkan salinan interpretasi dapat menimbulkan celah time-of-check to time-of-use jika operasi berikutnya membaca memori target lagi. Supervisor tidak boleh memperlakukan memori pengguna yang mutable sebagai capability immutable.

Identifier notifikasi menyelesaikan ambiguitas lifetime notifikasi. Identifier tersebut tidak menyelesaikan race arbitrer di memori aplikasi.

Continuation mempertahankan semantik kernel sekaligus race

Supervisor dapat merespons dengan SECCOMP_USER_NOTIF_FLAG_CONTINUE pada kernel yang mendukung perilaku ini. Kernel kemudian melanjutkan eksekusi system call yang dicegat alih-alih mengembalikan hasil yang disediakan supervisor.

Continuation berguna ketika kebijakan perlu menyetujui operasi sementara implementasi syscall aktual tetap dijalankan kernel. Mekanisme ini juga memiliki limit yang jelas: pemeriksaan supervisor dan pemakaian argumen syscall oleh kernel terjadi pada dua waktu berbeda. Jika argumen merujuk pada memori mutable, nilai yang diperiksa supervisor dapat berbeda dari nilai yang dikonsumsi setelah continuation.

Karena itu, continuation tidak setara dengan persetujuan atomik atas objek persis yang diperiksa supervisor. Kebijakan berbasis string atau struktur yang dirujuk pointer memerlukan desain yang memperhitungkan mutasi. Pemeriksaan yang membandingkan string pathname lalu melanjutkan openat() dapat tidak aman jika thread lain dapat mengubah string sebelum kernel menyalinnya.

Dokumentasi seccomp memperlakukan continuation sebagai operasi yang memerlukan kehati-hatian. Fitur ini berguna, tetapi properti keamanannya lebih sempit daripada primitive check-and-execute atomik.

Injeksi descriptor dapat menggantikan pemutaran ulang pathname

Untuk desain akses file tertentu, SECCOMP_IOCTL_NOTIF_ADDFD menawarkan pola yang lebih kuat daripada menyetujui pathname lalu melanjutkan operasi open semula. Supervisor dapat membuka resource di bawah kebijakan resolusi yang dikendalikannya sendiri, lalu memasang file descriptor ke proses target dalam kaitannya dengan notifikasi tertunda.

Hal ini mengubah objek yang melewati batas. Alih-alih bergantung pada pathname mutable untuk mengidentifikasi objek yang sama dua kali, supervisor dapat me-resolve resource sekali dan mentransfer referensi file kernel. Supervisor kemudian dapat mengembalikan nomor descriptor yang sesuai sebagai hasil call yang dicegat ketika desainnya cocok dengan kontrak syscall yang diemulasi.

Injeksi descriptor tetap memerlukan kebijakan yang cermat. Namespace filesystem, kredensial, directory descriptor, dan aturan resolusi path milik supervisor menentukan resource yang dapat dibukanya. Memberikan descriptor kepada target juga memberikan operasi yang diizinkan oleh descriptor tersebut dan pemeriksaan kernel berikutnya. Mekanisme ini menghapus satu kelas race pemutaran ulang pathname; kebijakan resource tetap harus ditetapkan secara terpisah.

SECCOMP_IOCTL_NOTIF_ADDFD juga bergantung pada versi kernel. Deployment harus memverifikasi dukungan dan tidak menganggap ioctl tersebut tersedia pada seluruh implementasi notifikasi pengguna seccomp.

Emulasi harus sesuai dengan kontrak ABI yang dicegat

Supervisor dapat mengirim respons berisi error atau return value. Fasilitas ini memungkinkan emulasi syscall, tetapi kebenarannya bergantung pada ABI persis yang diharapkan program yang dicegat.

Mengembalikan nilai yang tampak sukses dapat melanggar asumsi aplikasi jika syscall normalnya membuat keadaan kernel. Nomor descriptor rekaan, misalnya, tidak setara dengan pemasangan descriptor nyata. Call yang membuat handle, mengubah keadaan proses, atau membentuk objek kernel memerlukan perubahan keadaan terkait jika akan diemulasi alih-alih dilanjutkan.

Ini merupakan persoalan keamanan sekaligus kompatibilitas. Emulasi yang tidak lengkap dapat memindahkan alur kontrol aplikasi ke keadaan yang tidak diperhitungkan desain sekitarnya. Kasus penggunaan yang paling andal adalah kondisi ketika supervisor dapat menghasilkan objek kernel yang diperlukan atau ketika kebijakan kegagalan sudah memadai.

Arsitektur karena itu perlu membedakan tiga tindakan: menolak call, mengemulasi hasilnya beserta seluruh keadaan yang diperlukan, atau mengizinkan eksekusi kernel melalui continuation. Ketiganya memiliki properti race dan kebutuhan otoritas yang berbeda.

Notifikasi pengguna bukan primitive eskalasi privilese

Notifikasi pengguna seccomp tidak secara inheren memberikan privilese supervisor kepada task target. Target tetap tunduk pada kredensial, namespace, kebijakan LSM, dan kontrol kernel lain ketika syscall yang dilanjutkan dieksekusi. Namun, supervisor yang menjalankan operasi sendiri bertindak dengan otoritas supervisor kecuali operasi tersebut sengaja dibatasi.

Kondisi ini menciptakan persoalan deputy. Jika supervisor berprivilese menerima argumen yang dikendalikan penyerang dan menjalankan akses resource tanpa kebijakan ketat, lapisan mediasi dapat mengekspos otoritas yang sebelumnya tidak dimiliki task sandbox. Filter dapat sempit sementara implementasi supervisor terlalu luas.

Desain yang kuat karena itu memperlakukan supervisor sebagai endpoint protokol berprivilese. Input dianggap tidak tepercaya, operasi yang diizinkan dinyatakan eksplisit, argumen mutable ditangani dengan pola yang memperhitungkan race, dan descriptor yang ditransfer hanya membawa otoritas yang diperlukan untuk operasi terkait.

Batas keamanan mencakup filter, listener, dan supervisor

Notifikasi pengguna seccomp paling kuat ketika cakupannya dinyatakan secara presisi. Filter memilih call untuk dimediasi. Descriptor listener membawa otoritas keputusan. Identifier notifikasi melacak request kernel yang tertunda. Supervisor menerapkan kebijakan deployment, dan continuation atau emulasi menentukan lokasi operasi akhir.

Tidak satu pun elemen tersebut sendirian membentuk sandbox lengkap. Filter yang mendelegasikan terlalu luas dapat mengekspos antarmuka supervisor yang besar. Filter yang benar tetapi dipasangkan dengan supervisor berprivilese berlebihan dapat menciptakan jalur confused deputy. Supervisor yang cermat tetap dapat mengambil keputusan keliru jika mengasumsikan argumen pointer stabil melewati batas continuation.

Mekanisme ini karena itu paling tepat diperlakukan sebagai kanal delegasi terkontrol untuk keputusan syscall terpilih. Nilainya berasal dari jeda yang ditegakkan kernel sebelum operasi tertentu, sementara mesin kebijakan tetap berada di luar proses terbatas. Limitnya juga konkret: jeda tersebut tidak membekukan setiap objek yang memengaruhi request, sehingga arsitektur sekitarnya perlu mengikat keputusan ke objek kernel yang stabil ketika keadaan userspace mutable membuat persetujuan menjadi ambigu.