Filter seccomp dapat menghentikan sebuah task pada entri syscall dan mengubah kejadian itu menjadi pesan untuk process lain. Dengan SECCOMP_RET_USER_NOTIF, kernel tidak langsung menjalankan syscall yang dipilih. Kernel membuat notifikasi untuk listener, memblokir task pemanggil, lalu menunggu respons yang dapat memberikan nilai balik, menginjeksi file descriptor, atau mengizinkan syscall berlanjut.
Batas ini lebih sempit daripada emulasi syscall umum. Notifikasi membawa metadata syscall dan nilai argumen register, sedangkan memori yang dirujuk argumen pointer tetap berada di process target. Target juga dapat berhenti atau notifikasinya menjadi tidak valid saat supervisor sedang mengambil keputusan. Sifat tersebut menjadikan identitas, kepemilikan memori, dan waktu respons sebagai bagian dari kontrak interface.
Listener terikat pada filter, bukan satu task
Pemasangan filter dengan SECCOMP_FILTER_FLAG_NEW_LISTENER menghasilkan file descriptor notifikasi. Aksi filter SECCOMP_RET_USER_NOTIF mengarahkan percobaan syscall yang cocok ke listener tersebut.
Listener terkait dengan filter. Jika task yang memakai filter membuat turunan yang mewarisinya, notifikasi dari beberapa task dapat tiba melalui descriptor yang sama. Karena itu, supervisor tidak dapat memakai descriptor tersebut sebagai identitas satu pemanggil.
Setiap struct seccomp_notif yang diterima memuat id, identifier task sebagaimana terlihat dari konteks listener, dan struct seccomp_data. Data itu mencakup nomor syscall, nilai arsitektur, instruction pointer, serta enam nilai register argumen syscall.
Field arsitektur merupakan bagian dari interpretasi yang benar. Nomor syscall dan calling convention bergantung pada arsitektur, sehingga filter atau supervisor yang menilai nomor syscall tanpa arsitektur terkait dapat memberi makna yang keliru pada status register.
Nilai register bukan snapshot memori yang ditunjuk
Untuk argumen skalar, nilai di seccomp_data.args adalah nilai yang disajikan pada entri syscall. Argumen pointer berbeda. Notifikasi berisi nilai pointer, bukan salinan byte milik kernel dari alamat tersebut.
Pertimbangkan operasi yang dicegat dengan argumen pathname:
task target supervisor
buffer path = "/a"
syscall(path) ---- notify --> nilai pointer
blocked membaca memori target
mengambil keputusanPembacaan memori target melalui mekanisme inspeksi process yang tersedia merupakan operasi terpisah. Byte tersebut dimiliki address space target, bukan notifikasi seccomp.
Supervisor yang menyalin byte rujukan ke memorinya sendiri dapat mengambil keputusan terhadap salinan itu. Namun, syscall yang kemudian dilanjutkan tidak otomatis memakai salinan yang sama. Jika supervisor membalas dengan SECCOMP_USER_NOTIF_FLAG_CONTINUE, kernel meneruskan syscall asli, yang dapat melakukan dereference terhadap memori target sesuai semantik syscall normal. Memori target dapat berubah antara inspeksi dan pemakaian.
Ini adalah batas time-of-check/time-of-use yang melekat pada continuation. Karena itu, notifikasi pengguna tidak cocok sebagai lapisan otorisasi keamanan mandiri untuk syscall yang dilanjutkan ketika argumen penting bagi keamanan harus dibaca dari memori target yang mutable. Pembatasan lain yang ditegakkan kernel dapat membuat continuation aman untuk desain tertentu, tetapi sifat itu berasal dari pembatasan tambahan tersebut, bukan dari pertukaran notifikasi.
ID notifikasi membatasi race masa hidup task
Target tetap menjadi partisipan hidup saat supervisor memproses notifikasi. Target dapat dihentikan, dan notifikasi pending dapat kehilangan validitas sebelum respons tiba.
Linux memberikan identifier untuk setiap notifikasi. SECCOMP_IOCTL_NOTIF_ID_VALID memungkinkan supervisor menguji apakah sebuah ID masih merujuk pada request pending yang valid. Operasi respons juga menunjuk request melalui ID tersebut.
ID penting karena process identifier numerik bukan transaction handle yang tahan lama. PID dapat digunakan kembali setelah task keluar, sedangkan ID notifikasi menamai interaksi seccomp pending yang terkait dengan listener.
Pemeriksaan validitas ID tetap merupakan observasi pada satu titik waktu. Target dapat berhenti setelah pemeriksaan dan sebelum operasi berikutnya. Karena itu, kode harus menangani kegagalan respons atau injeksi descriptor dan tidak memperlakukan hasil valid sebagai jaminan masa hidup target.
Memberikan nilai balik berbeda dari melanjutkan syscall
Respons notifikasi normal dapat membuat syscall yang diblokir tampak mengembalikan nilai atau error tanpa menjalankan syscall asli. Dalam mode ini, supervisor memasok hasil yang terlihat dari operasi yang dicegat.
Continuation memiliki semantik berbeda. Pengaturan SECCOMP_USER_NOTIF_FLAG_CONTINUE meminta kernel menjalankan syscall setelah fase notifikasi. Supervisor tidak lagi mengemulasikan hasil; supervisor melepaskan operasi asli.
Perbedaan itu mengubah batas kepercayaan. Hasil sintetis dapat didasarkan sepenuhnya pada status yang dimiliki supervisor, sesuai protokol aplikasi di sekitarnya. Continuation memasukkan kembali konsumsi normal oleh kernel terhadap argumen syscall milik target. Keputusan dari data pointer mutable dapat menjadi usang sebelum kernel memakainya.
Kedua mode respons dapat terlihat serupa bagi target karena keduanya akhirnya membuka blokir instruksi syscall. Dependensi datanya tidak serupa.
Injeksi file descriptor memindahkan objek kernel
SECCOMP_IOCTL_NOTIF_ADDFD memberi supervisor opsi lain untuk syscall yang hasil bergunanya berupa file descriptor. Supervisor dapat menempatkan descriptor ke tabel descriptor target dan melaporkan nomor descriptor yang dihasilkan.
Hal ini berbeda secara material dari mengembalikan integer yang sekadar menyerupai nomor descriptor. File descriptor adalah entri tabel lokal process yang merujuk open file description atau objek kernel lain. Injeksi membuat relasi tabel tersebut di target.
Operasi dapat meminta status close-on-exec untuk descriptor baru. Linux juga menyediakan mode yang menggabungkan injeksi descriptor dengan pengiriman respons notifikasi, sehingga tidak ada interval terpisah antara pemasangan descriptor dan penyelesaian panggilan yang dicegat.
Supervisor tetap harus menilai objek yang diinjeksi. Resolusi path, credential, konteks namespace, dan open flags yang dipakai untuk memperoleh descriptor sisi supervisor menentukan objek kernel yang dipindahkan. Injeksi tidak menjalankan syscall target asli dalam konteks lookup target.
Blocking mengubah perilaku signal dan pembatalan
Saat notifikasi pending, task target tidur di dalam interaksi seccomp alih-alih menjalankan syscall terpilih. Signal dapat memengaruhi wait tersebut, dan notifikasi dapat dibatalkan sebelum supervisor merespons.
Linux menyediakan SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV untuk desain yang memerlukan penanganan berbeda setelah supervisor menerima request. Dengan mode tersebut, setelah notifikasi diterima, signal nonfatal tidak menginterupsi wait target terhadap respons supervisor, sedangkan signal fatal tetap dapat menghentikannya.
Perubahan ini menyentuh semantik koordinasi, bukan arti syscall yang dicegat. Supervisor yang dapat menjalankan operasi panjang memerlukan model pembatalan eksplisit karena keluarnya target, kegagalan supervisor, dan invalidasi notifikasi tetap menjadi batas yang mungkin terjadi.
Descriptor listener dapat dipantau dengan poll, sehingga dapat masuk ke event loop. Readiness menyatakan bahwa pekerjaan notifikasi tersedia; status itu tidak menjamin setiap request yang sempat terlihat ready akan tetap valid sampai pemrosesan arbitrer selesai.
Mekanisme ini adalah protokol interposisi
Notifikasi pengguna seccomp menyisipkan protokol antara entri syscall dan hasil sintetis atau eksekusi kernel. Sifat utamanya bukan emulasi transparan, melainkan interposisi terkendali pada batas kernel yang terdefinisi.
Filter memilih entri syscall. Notifikasi menangkap metadata tingkat register. Supervisor memiliki salinan status yang dipakai untuk keputusan. Target mempertahankan address space dan dapat berubah masa hidupnya. Respons dapat mengganti hasil, memindahkan objek kernel melalui injeksi descriptor, atau melepaskan syscall asli agar berlanjut.
Batas tersebut menentukan desain yang tetap koheren. Operasi berdasarkan metadata skalar yang stabil lebih sederhana daripada keputusan yang terikat pada pointer target mutable. Injeksi descriptor dapat memindahkan objek kernel yang sudah terbuka tanpa berpura-pura bahwa integer saja sudah memadai. Continuation tepat hanya ketika eksekusi kernel yang tersisa tetap dapat diterima meski memori milik target berubah setelah inspeksi.
Interface ini dengan demikian memperlihatkan pemisahan yang presisi: entri syscall dapat ditahan dan dimediasi, tetapi notifikasi tidak membekukan process target menjadi request yang immutable.