Shared memory efisien karena dua proses dapat mengamati storage yang sama tanpa menyalin data. Properti itu menjadi masalah keamanan ketika satu pihak memvalidasi byte lalu mengonsumsinya sementara pihak lain masih memiliki kewenangan untuk mengubah objek yang sama. Sealing pada memfd Linux dapat mempersempit race tersebut dengan membuat mutasi tertentu gagal di kernel sebelum file descriptor melewati batas kepercayaan.
memfd_create() membuat file anonim dan mengembalikan file descriptor biasa. Objek tersebut dapat diatur ukurannya, ditulis, dipetakan, dan ditransfer melalui UNIX domain socket. Dengan MFD_ALLOW_SEALING, inode dimulai dengan set seal kosong sehingga produsen dapat menambahkan pembatasan yang tidak dapat dibatalkan setelah payload diisi.
Seal melekat pada inode, bukan pada satu descriptor
F_ADD_SEALS menambahkan pembatasan ke inode yang dirujuk oleh file descriptor writable. Seal dibagikan oleh setiap descriptor yang merujuk inode tersebut, termasuk descriptor yang diduplikasi secara lokal atau ditransfer ke proses lain. Setelah sebuah seal ditambahkan, seal itu tidak dapat dihapus.
Properti ini mengubah model kepercayaan transfer descriptor. Konsumen tidak perlu bergantung pada janji bahwa produsen akan menahan diri dari mutasi terlarang setelah handoff. Mutasi yang relevan ditolak berdasarkan state inode bersama.
F_GET_SEALS menampilkan bit mask seal saat ini. Proses penerima dapat mensyaratkan set seal tertentu sebelum memperlakukan payload sebagai stabil. Pemeriksaan itu berguna hanya jika seal yang diwajibkan benar-benar mencakup mutasi yang penting bagi parser atau protokol.
Seal ukuran menghapus truncation dan extension sebagai jalur mutasi
F_SEAL_SHRINK mencegah ukuran file diperkecil. Hal ini penting untuk data bersama yang dipetakan karena truncation dapat menghapus page di bawah mapping yang sudah ada dan akses berikutnya dapat menghasilkan SIGBUS.
F_SEAL_GROW memblokir operasi yang memperbesar ukuran file. Bersama-sama, kedua seal menetapkan panjang objek, tetapi tidak membuat byte di dalam panjang tersebut immutable. Produsen yang berhenti pada sealing ukuran masih dapat membuat konsumen terpapar perubahan isi melalui jalur penulisan yang tetap diizinkan.
Perbedaan ini penting bagi payload terstruktur. Panjang tetap dapat menstabilkan offset dan batas, sementara field pada offset tersebut masih dapat berubah. Integritas ukuran dan integritas isi merupakan properti yang terpisah.
F_SEAL_WRITE mensyaratkan writable shared mapping sudah tidak ada
F_SEAL_WRITE mencegah modifikasi isi file melalui operasi bergaya write dan mencegah writable shared mapping baru. Kernel tidak akan menambahkan seal ini selama writable shared mapping yang sudah ada untuk file tersebut masih aktif. Produsen yang mengisi objek melalui mapping semacam itu harus lebih dulu menghapus mapping tersebut atau menghilangkan state writable mapping yang berkonflik.
Persyaratan itu menutup bypass langsung. Jika kernel mengizinkan full write seal sementara writable shared mapping yang sudah ada tetap hidup, pemegang mapping tersebut dapat terus mengubah page meskipun objek tampak berada dalam state immutable.
Handoff tipikal karena itu memiliki transisi state: buat memfd, tetapkan ukurannya, isi payload, hapus writable shared mapping, tambahkan seal yang diperlukan, periksa set seal yang dihasilkan, lalu transfer descriptor. Properti keamanan berasal dari penyelesaian transisi tersebut sebelum pihak yang kurang dipercaya bergantung pada byte di dalamnya.
F_SEAL_FUTURE_WRITE memiliki batas yang sengaja lebih lemah
F_SEAL_FUTURE_WRITE memblokir operasi write di masa depan dan writable shared mapping baru, tetapi writable shared mapping yang sudah ada tetap dapat memodifikasi file. Hal ini memungkinkan produsen mempertahankan mapping yang sudah terbentuk sambil mencegah kewenangan tulis baru diperoleh melalui file descriptor.
Perilaku tersebut berguna untuk protokol yang sengaja mempertahankan writer yang sudah ada, tetapi tidak setara dengan isi immutable. Konsumen yang mensyaratkan byte tetap konstan setelah validasi tidak dapat menyimpulkan properti itu hanya dari F_SEAL_FUTURE_WRITE selama writable mapping yang dibuat sebelumnya mungkin masih hidup.
Perbedaan antara kedua write seal tersebut merupakan keputusan batas kepercayaan, bukan sekadar detail API. F_SEAL_WRITE menargetkan state tanpa writable shared mapping yang masih bertahan; F_SEAL_FUTURE_WRITE dapat hidup berdampingan dengannya.
F_SEAL_SEAL membekukan policy, bukan payload
F_SEAL_SEAL mencegah penambahan seal berikutnya. Seal ini sendiri tidak melarang penulisan isi, pertumbuhan, atau penyusutan. Penerapannya terlalu dini dapat secara permanen mencegah inode menerima pembatasan yang kemudian diwajibkan protokol handoff.
Produsen yang memerlukan policy immutable final biasanya menambahkan seal mutasi terlebih dahulu dan menyertakan F_SEAL_SEAL hanya ketika tidak ada pembatasan tambahan yang boleh ditambahkan. Karena seal bersifat monotonik, set final menjadi policy pada tingkat inode yang tidak dapat dilonggarkan oleh kedua pihak.
Ada pula default penting saat pembuatan. Jika memfd_create() dipanggil tanpa MFD_ALLOW_SEALING, file baru dimulai dengan F_SEAL_SEAL. Dalam state tersebut, sealing biasa tidak dapat kemudian menambahkan pembatasan write atau ukuran. Kemampuan sealing karena itu harus menjadi bagian keputusan saat pembuatan, bukan tambahan setelah handoff akan dilakukan.
Transfer descriptor tidak mentransfer kewenangan mutasi tanpa batas
Memfd dapat dikirim ke proses lain dengan SCM_RIGHTS melalui UNIX domain socket. Descriptor penerima merujuk file dasar yang sama sehingga aksesnya tunduk pada seal yang sudah melekat pada inode.
Hal ini membuat sealed memfd sesuai untuk desain IPC ketika satu proses membangun payload dan proses lain melakukan parsing atau mapping tanpa menerima kewenangan mutasi berkelanjutan dari produsen. Penerima dapat memvalidasi seal yang diharapkan lalu bekerja langsung pada objek bersama alih-alih menyalin data semata-mata untuk memperoleh snapshot stabil.
Seal tidak mengautentikasi produsen, menetapkan otorisasi socket, atau membuktikan bahwa byte awal aman. Identitas peer, framing pesan, validasi payload, dan provenance descriptor tetap merupakan kontrol terpisah. Sealing hanya membatasi mutasi setelahnya yang dicakup oleh set seal terpasang.
Permission eksekusi merupakan batas memfd yang terpisah
Content sealing dan status executable merupakan dua hal berbeda. Linux saat ini menyediakan MFD_NOEXEC_SEAL untuk membuat memfd non-executable dengan bit executable disegel agar tidak dapat ditambahkan kemudian. Linux juga menyediakan MFD_EXEC untuk memfd executable, dengan tetap tunduk pada policy kernel.
Pengaturan vm.memfd_noexec yang memiliki lingkup PID namespace dapat mengubah atau menegakkan default bagi pemanggilan yang tidak menyertakan flag eksekusi eksplisit. Policy ini bersifat hierarkis pada PID namespace, dengan pengaturan paling restriktif yang berlaku saat pembuatan.
Desain yang memakai memfd hanya sebagai transport data karena itu dapat membatasi eksekusi secara terpisah dari mutasi isi. Write seal sendiri tidak menyatakan policy non-eksekusi, sedangkan memfd non-executable sendiri tidak membuat payload immutable.
Immutability paling kuat ketika state handoff dibuat eksplisit
Batas keamanan yang berguna bukan sekadar keberadaan descriptor memfd, melainkan state inode ketika komponen lain mulai mempercayai isinya. Ukuran tetap, write yang diblokir, policy seal yang dibekukan, dan status non-executable masing-masing mencakup jalur mutasi atau penggunaan yang berbeda.
Untuk handoff data immutable, penerima dapat memperlakukan mask seal yang diwajibkan sebagai metadata protokol dan menolak objek yang tidak memenuhinya. Dengan demikian invariant terikat pada state yang terlihat oleh kernel, bukan pada konvensi proses. Batasannya juga tetap presisi: seal dapat menghapus kewenangan mutasi tertentu dari file bersama, tetapi tidak menggantikan autentikasi, validasi payload, otorisasi IPC, atau confinement proses yang saling bertukar data.