Sebuah memfd Linux dapat bermula sebagai file anonim yang writable, lalu memperoleh pembatasan yang tidak dapat dihapus. Pembatasan tersebut melekat pada inode, sehingga transfer atau duplikasi descriptor tidak menghasilkan tampilan yang lebih longgar. Setelah sebuah seal berhasil ditambahkan, setiap descriptor yang merujuk inode itu tunduk pada seal tersebut.
Sifat ini berbeda dari access mode pada descriptor. Descriptor dapat membawa flag lokal, sedangkan seal mengubah batas mutasi pada objek file bersama itu sendiri.
Sealing harus diaktifkan saat pembuatan
memfd_create() mengembalikan descriptor untuk file anonim. Dengan MFD_ALLOW_SEALING, kumpulan seal awal kosong dan F_ADD_SEALS dapat menambahkan pembatasan setelahnya.
Tanpa MFD_ALLOW_SEALING, file dimulai dengan F_SEAL_SEAL. Seal tersebut memblokir penambahan berikutnya, sehingga ketiadaan flag saat pembuatan bukan kondisi yang sama dengan kebijakan sealing kosong tanpa pembatasan.
Kumpulan seal dapat diperiksa melalui F_GET_SEALS. Penambahan seal memerlukan descriptor writable, tetapi enforcement melekat pada inode, bukan hanya pada descriptor yang dipakai untuk F_ADD_SEALS.
Kumpulan seal hanya bergerak menuju pembatasan yang lebih ketat
F_ADD_SEALS melakukan transisi aditif:
S_next = S_current | S_requestedTidak ada operasi untuk menghapus seal. Menambahkan kembali seal yang sudah ada merupakan no-op selama F_SEAL_SEAL belum menutup kumpulan seal terhadap pemanggilan F_ADD_SEALS berikutnya.
Sifat monotonik ini penting ketika memfd melintasi batas proses. Proses penerima dapat memeriksa kumpulan saat ini, tetapi tidak dapat mengandalkan transisi berikutnya menuju keadaan yang lebih mutable. Jika F_SEAL_SEAL belum ada, proses yang memegang descriptor writable masih dapat menambahkan pembatasan lain.
Seal ukuran membatasi arah yang berbeda
F_SEAL_SHRINK mencegah operasi yang mengurangi ukuran file. File masih dapat diperbesar.
F_SEAL_GROW mencegah operasi yang menambah ukuran file. File masih dapat diperkecil.
Memasang keduanya membuat ukuran tetap terhadap pertumbuhan dan penyusutan, tetapi tidak dengan sendirinya membuat byte yang sudah ada menjadi immutable. Stabilitas ukuran dan stabilitas isi adalah properti terpisah.
Perbedaan ini penting pada shared mapping. Peer yang tidak dapat melakukan truncate tidak lagi dapat membuat backing file lebih pendek melalui operasi perubahan ukuran biasa, tetapi byte dalam rentang yang dipertahankan masih dapat writable jika tidak ada seal terkait write.
F_SEAL_WRITE mensyaratkan shared writer yang ada sudah hilang
F_SEAL_WRITE memblokir write dan shared writable mapping baru. Linux juga menolak penambahan seal ini dengan EBUSY selama masih ada writable shared mapping.
Urutan batasnya bersifat eksplisit:
isi data
|
hapus shared writable mapping
|
tambah F_SEAL_WRITE
|
bagikan atau map read-onlyKernel tidak mencabut shared writable mapping yang aktif secara retroaktif agar F_SEAL_WRITE berhasil. Mapping tersebut harus dihapus lebih dulu.
Batas ini mencegah file dinyatakan sepenuhnya write-sealed ketika mapping lama masih menyediakan jalur write.
F_SEAL_FUTURE_WRITE mempertahankan shared mapping terdahulu
F_SEAL_FUTURE_WRITE memiliki batas berbeda. Setelah seal ini dipasang, write() dan shared writable mmap() baru gagal, tetapi shared writable mapping yang dibuat sebelum seal tetap dapat memodifikasi file.
Properti tersebut mendukung producer yang mempertahankan mapping yang sudah terbentuk sambil mencegah peer baru memperoleh jalur write baru. Kondisi ini tidak setara dengan isi immutable karena mapping lama tetap menjadi kanal mutasi yang sah.
Perbedaan kedua write seal bersifat temporal. F_SEAL_WRITE mensyaratkan kumpulan writable shared mapping kosong saat sealing; F_SEAL_FUTURE_WRITE membentuk batas antara mapping yang dibuat sebelum dan sesudah transisi.
F_SEAL_SEAL membekukan kebijakan, bukan data file
F_SEAL_SEAL mencegah operasi F_ADD_SEALS berikutnya. Seal ini tidak otomatis menyiratkan F_SEAL_WRITE, F_SEAL_GROW, atau F_SEAL_SHRINK.
File yang hanya memiliki F_SEAL_SEAL dapat tetap writable dan resizable sesuai state lainnya, sementara kebijakan sealing tidak dapat diperketat lagi. Urutan menjadi penting saat membentuk kebijakan akhir: pembatasan yang diperlukan pada objek akhir harus ditambahkan sebelum kumpulan seal ditutup.
State data immutable yang umum dapat dinyatakan sebagai:
F_SEAL_WRITE | F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEALKumpulan yang tepat perlu mengikuti batas mutasi yang dituju, bukan memperlakukan F_SEAL_SEAL sebagai singkatan untuk immutability.
Transfer descriptor mempertahankan objek sealed yang sama
Mengirim memfd melalui UNIX domain socket dengan SCM_RIGHTS, mewariskannya lewat fork(), atau membuka referensi /proc/PID/fd/FD yang sesuai dapat menghasilkan descriptor lain untuk file dasar yang sama. Kumpulan seal tetap terkait dengan file tersebut.
Sifat ini memberi sealing properti IPC yang spesifik: producer dapat menetapkan pembatasan yang ditegakkan kernel sebelum menyerahkan objek ke proses lain. Consumer tidak menerima snapshot privat; consumer memperoleh akses ke inode yang sama di bawah pembatasan yang telah melekat.
Batasnya sempit tetapi kuat. Seal membatasi mutasi file tertentu. Seal tidak mengautentikasi producer, memvalidasi byte, menetapkan makna aplikasi pada data, atau menggantikan pemeriksaan pada level protokol. Perannya adalah membuat kapabilitas mutasi tertentu hilang secara monotonik dari objek file bersama.