Sebuah proses menyiapkan payload biner di memori, menyerahkan file descriptor ke proses lain, lalu mengharapkan byte tetap stabil setelah validasi. Descriptor biasa tidak menghasilkan jaminan tersebut. Jika masih ada pemegang dengan otoritas tulis, objek dapat berubah setelah diperiksa konsumen, sedangkan izin pathname tidak memberi batas yang berguna ketika objek tidak memiliki nama filesystem biasa.
Linux memfd_create() menyediakan file anonim yang ditopang penyimpanan filesystem menyerupai memori, dan file seal dapat membatasi perubahan berikutnya pada file tersebut. Properti keamanan yang berguna bukan anonimitas semata. Mekanismenya memungkinkan pembuatan objek mutable, penerapan pembatasan yang tidak dapat dibatalkan, lalu penyerahan descriptor dengan backing file yang tidak lagi dapat diubah melalui operasi yang dilarang.
Sealing harus diaktifkan saat memfd dibuat
Pemanggil yang hendak menambahkan seal membuat objek dengan MFD_ALLOW_SEALING. Tanpa flag tersebut, file baru dimulai dengan F_SEAL_SEAL, yang mencegah penambahan seal berikutnya. Perilaku bawaan ini menjadikan kemampuan sealing sebagai pilihan eksplisit saat pembuatan.
Seal dikelola dengan fcntl(). F_ADD_SEALS menambahkan pembatasan, sedangkan F_GET_SEALS melaporkan mask seal saat ini. Seal yang sudah ditambahkan tidak dapat dihapus. Transisinya bersifat monoton: proses dapat mempersempit hak mutasi pada file, tetapi tidak dapat memulihkan operasi terlarang dengan menghapus seal.
F_SEAL_SEAL menutup kebijakan seal itu sendiri. Setelah aktif, seal tambahan tidak dapat dipasang. Produsen yang memerlukan kebijakan immutable final biasanya menambahkan seal mutasi yang diperlukan sebelum F_SEAL_SEAL; memasang seal kebijakan terlalu awal akan membekukan mask yang belum lengkap.
Ukuran dan isi merupakan permukaan mutasi yang berbeda
F_SEAL_GROW mencegah penambahan ukuran file. F_SEAL_SHRINK mencegah pengurangan ukurannya. Kedua pembatasan berdiri sendiri karena perubahan panjang dapat mengubah objek yang terlihat oleh konsumen meski byte pada rentang yang dipertahankan tidak diganti.
F_SEAL_WRITE membatasi mutasi isi dengan lebih kuat. Setelah berhasil diterapkan, operasi tulis yang memodifikasi file ditolak dan shared writable mapping baru tidak dapat dibuat. Kernel tidak akan menambahkan seal ini selama masih ada shared writable mapping untuk file tersebut. Kondisi itu mencegah produsen menyatakan write seal yang kuat ketika mapping lain masih membawa otoritas mutasi langsung.
Pemisahan antara ukuran file dan isi file penting bagi desain protokol. Produsen yang memerlukan rangkaian byte tetap umumnya perlu membatasi penulisan sekaligus perubahan ukuran. Mask seal yang memblokir penulisan tetapi masih mengizinkan truncation tidak menyatakan invariant yang sama.
Mapping yang sudah ada menentukan batas keras F_SEAL_WRITE
Memory mapping membuat batas sealing lebih presisi daripada sekadar operasi “jadikan read-only”. Writable MAP_SHARED mapping dapat memodifikasi backing file tanpa memakai write(). Karena itu, F_SEAL_WRITE tidak dapat dipasang sampai mapping tersebut tidak ada lagi.
Linux juga menyediakan F_SEAL_FUTURE_WRITE. Seal ini memblokir penulisan file berikutnya dan pembuatan shared writable mapping berikutnya, tetapi shared writable mapping yang sudah ada masih dapat memodifikasi file. Seal ini mendukung transisi berbeda: menghentikan distribusi otoritas tulis baru tanpa mencabut otoritas yang sudah direpresentasikan oleh mapping yang ada.
Perbedaan tersebut harus tetap terlihat dalam klaim keamanan. F_SEAL_FUTURE_WRITE tidak dapat dipertukarkan dengan F_SEAL_WRITE ketika konsumen memerlukan byte yang tidak dapat berubah setelah serah terima. Produsen harus memperhitungkan writable mapping yang ada dan memilih seal dengan semantik kernel yang sesuai dengan invariant yang diperlukan.
Transfer descriptor tidak menghapus seal
Seal melekat pada objek file, bukan pada satu nomor descriptor. Menduplikasi descriptor atau mengirimkannya melalui Unix domain socket tidak menghasilkan salinan tanpa seal dari file yang sama. Penerima tetap melihat pembatasan yang melekat pada backing object.
Properti ini membuat sealed memfd berguna pada batas IPC. Produsen dapat mengisi data, memvalidasi representasi finalnya sendiri, menerapkan seal yang diperlukan, lalu mentransfer descriptor. Penerima dapat memeriksa F_GET_SEALS jika protokol mensyaratkan mask tertentu, alih-alih mempercayai pesan yang hanya menyatakan bahwa sealing sudah dilakukan.
Penerima tetap harus menetapkan properti yang diterima. Sebuah descriptor yang berasal dari memfd tidak berarti seal yang berguna pasti aktif, dan mask seal nonzero tidak berarti kombinasi yang diperlukan sudah terpasang. Batas protokol berada pada kumpulan properti objek yang diverifikasi, bukan pada nama API yang dipakai untuk membuat objek.
Seal membatasi mutasi, bukan seluruh properti penggunaan data
File sealing tidak mengautentikasi produsen, memvalidasi byte, mengenkripsi isi, atau menentukan proses mana yang boleh menerima descriptor duplikat. Kontrol tersebut berada pada desain IPC, identitas, dan validasi data di sekelilingnya.
Seal juga tidak mengubah objek menjadi primitive penyimpanan immutable universal. Jaminannya terbatas pada operasi yang didefinisikan kernel untuk setiap seal serta keadaan mapping yang relevan saat seal dipasang. Konsumen yang memerlukan provenance atau persistensi melintasi batas penyimpanan yang lebih luas memerlukan mekanisme terpisah.
Nilai arsitekturalnya lebih sempit dan konkret: sealing memungkinkan proses mengubah file anonim dari objek konstruksi menjadi objek serah terima yang dibatasi. Ketika produsen memastikan tidak ada writable mapping yang bertentangan, memasang write seal dan size seal yang diperlukan, serta penerima memverifikasi mask hasilnya, mutabilitas menjadi properti eksplisit pada protokol transfer descriptor, bukan asumsi mengenai perilaku proses.