File yang dibuat dengan memfd_create() dapat bermula sebagai penyimpanan mutable lalu memperoleh pembatasan yang dipaksakan kernel dan berlaku pada file dasarnya, bukan hanya pada satu descriptor. Dengan MFD_ALLOW_SEALING, proses dapat menambahkan seal melalui fcntl(F_ADD_SEALS) sehingga mutasi tertentu tidak lagi tersedia bagi semua pemegang file tersebut.
Mekanisme ini membentuk transisi state yang tidak dapat dinyatakan oleh permission descriptor biasa. Produsen dapat mengisi byte, menetapkan ukuran file, lalu memublikasikan descriptor dengan pembatasan yang tetap melekat meskipun descriptor melintasi batas proses.
Seal melekat pada file, bukan pada descriptor
memfd_create() mengembalikan file descriptor untuk file anonim. File tersebut berperilaku seperti file biasa untuk operasi seperti read(), write(), mmap(), ftruncate(), dan duplikasi descriptor, sesuai flag serta permission yang berlaku pada tiap operasi.
Saat sealing diaktifkan ketika file dibuat, F_ADD_SEALS menambahkan pembatasan pada file. F_GET_SEALS melaporkan kumpulan seal saat ini. Duplikasi descriptor atau transfer melalui SCM_RIGHTS tidak membuat kumpulan seal privat bagi penerima. Semua descriptor yang merujuk file tersebut mengamati state sealing yang sama.
Cakupan ini menjadi bagian penting dari kontrak. Flag seperti FD_CLOEXEC berlaku per descriptor, sedangkan seal memfd membatasi operasi pada objek file yang dipakai bersama.
Seal ukuran memisahkan layout dari mutabilitas byte
F_SEAL_GROW mencegah operasi yang menambah ukuran file. F_SEAL_SHRINK mencegah operasi yang menguranginya. Keduanya dapat dipasang secara independen, sehingga file dapat melarang pemotongan ukuran sambil tetap mengizinkan penambahan, atau sebaliknya.
Produsen yang memerlukan rentang byte tetap dapat memasang keduanya setelah menetapkan panjang yang dituju. Pemanggilan ftruncate() berikutnya yang bertentangan dengan seal tersebut akan gagal. Penulisan yang memperbesar file juga ditolak ketika pertumbuhan telah disegel.
Kedua seal ukuran tersebut tidak membuat byte yang sudah ada menjadi immutable. Penulisan yang seluruhnya berada di dalam rentang file saat ini masih dapat mengubah data kecuali seal terkait penulisan memblokirnya. Ukuran tetap dan isi tetap merupakan dua properti berbeda.
F_SEAL_WRITE memiliki prasyarat mapping
F_SEAL_WRITE memblokir penulisan ke file dan mencegah shared writable mapping baru. Linux juga menolak penambahan seal ini selama masih ada shared writable mapping. Kernel tidak dapat menjamin state tanpa penulisan ketika MAP_SHARED writable yang sudah ada masih menyediakan jalur untuk mengubah isi file.
Kondisi tersebut membuat urutan sealing dapat diamati. Produsen yang hendak memublikasikan byte immutable harus memperhitungkan shared writable mapping sebelum meminta F_SEAL_WRITE. Menutup descriptor yang dipakai untuk membuat mapping saja tidak menghapus mapping; mapping memiliki lifetime sendiri.
F_SEAL_FUTURE_WRITE menyatakan batas yang berbeda pada versi Linux yang mendukungnya. Seal ini memblokir akses bergaya penulisan di masa depan sambil tetap mengizinkan penulisan melalui shared writable mapping yang sudah ada ketika seal dipasang. Karena itu, semantiknya tidak dapat dipertukarkan dengan F_SEAL_WRITE.
F_SEAL_SEAL menutup kebijakan sealing
Seal bersifat aditif. Setelah dipasang, seal tidak dapat dihapus. F_SEAL_SEAL menambahkan transisi lain: setelah seal ini ada, seal tambahan tidak dapat dipasang.
Akibatnya, urutan operasi menjadi bagian dari interface. Memasang F_SEAL_SEAL terlalu awal dapat secara permanen mencegah file mencapai state yang lebih ketat. Urutan publikasi dapat memasang pembatasan isi terlebih dahulu dan menambahkan F_SEAL_SEAL hanya ketika kumpulan seal itu sendiri harus dibuat final.
Kernel memaksakan model monotonik ini. Efektivitas seal yang sudah terpasang tidak bergantung pada kerja sama antar pemegang descriptor.
Publikasi dapat mentransfer data dan kebijakan mutasi bersama-sama
Sebuah proses dapat membuat memfd, menetapkan ukurannya, mengisi data, menambahkan seal yang diperlukan, lalu mengirim descriptor ke proses lain. Penerima memperoleh akses ke objek file yang sama dengan state seal yang sudah melekat.
Hal ini berbeda secara material dari mengirim pathname disertai kesepakatan agar penerima membuka file secara read-only. Pathname memicu lookup lain, sedangkan descriptor read-only membatasi mode akses descriptor tersebut. memfd yang telah disegel membawa pembatasan pada objek file itu sendiri.
Penerima tetap perlu memeriksa kontrak yang menjadi dasar operasinya. F_GET_SEALS dapat memverifikasi kumpulan seal saat ini, sedangkan metadata tingkat aplikasi tetap memerlukan validasi tersendiri. Sealing membatasi mutasi file yang ditentukan; mekanisme ini tidak mengautentikasi produsen atau memvalidasi format byte.
Sealing bukan primitive sinkronisasi umum
Seal yang berhasil dipasang mengubah operasi berikutnya yang diterima kernel, tetapi tidak mengubah akses memori terdahulu yang tidak tersinkronisasi menjadi protokol concurrency yang valid. Thread atau proses yang memakai mapping tetap memerlukan sinkronisasi sesuai bahasa, runtime, dan desain shared memory yang digunakan.
Seal juga tidak membuat snapshot state eksternal. Seal mengatur objek memfd dan kelas mutasi yang didefinisikan oleh tiap seal. Mekanisme ini tidak membekukan struktur data di tempat lain, menetapkan urutan pesan, atau menyediakan kesepakatan versi pada tingkat aplikasi.
Batas desain yang tepat adalah kontrak state file yang monotonik. memfd dapat berpindah dari penyimpanan yang luas mutabilitasnya menuju objek publikasi yang dibatasi, dan kernel dapat memaksakan transisi itu pada setiap descriptor yang mencapai file yang sama.