Descriptor dari memfd_create() merujuk ke file anonim dengan penyimpanan pada infrastruktur filesystem berbasis memori. Handoff descriptor saja tidak membekukan objek tersebut: proses yang masih memiliki akses yang sesuai dapat menulis byte, melakukan truncate, atau memperbesar file. File seal Linux menambahkan pembatasan yang ditegakkan kernel sehingga mutasi tertentu gagal setelah producer menyatakan objek selesai dibuat.

Mekanisme ini mengubah handoff shared memory dari sekadar konvensi menjadi transisi state yang ditegakkan pada objek file.

Seal melekat pada file, bukan pada satu descriptor

Memfd dapat dibuat dengan MFD_ALLOW_SEALING:

int fd = memfd_create("payload", MFD_CLOEXEC | MFD_ALLOW_SEALING);

Tanpa MFD_ALLOW_SEALING, set seal awal mencakup F_SEAL_SEAL, sehingga penambahan seal berikutnya tidak diizinkan. Jika sealing diaktifkan, fcntl() dapat menambahkan pembatasan:

int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_WRITE | F_SEAL_SEAL;

if (fcntl(fd, F_ADD_SEALS, seals) == -1) {
    perror("F_ADD_SEALS");
}

F_GET_SEALS melaporkan set yang aktif. Seal merupakan properti inode yang mendasari file, sehingga duplikasi descriptor atau pengiriman melalui UNIX domain socket tidak menghasilkan salinan tanpa seal.

F_SEAL_SEAL menutup set seal itu sendiri: setelah dipasang, seal tambahan tidak dapat dimasukkan. Seal yang sudah ada juga tidak dapat dihapus.

Seal ukuran dan seal penulisan melindungi mutasi yang berbeda

F_SEAL_SHRINK menolak operasi yang mengurangi ukuran file. F_SEAL_GROW menolak operasi yang memperbesar ukuran. Keduanya terpisah dari perubahan byte di dalam extent yang sudah ada.

F_SEAL_WRITE memblokir penulisan dan juga mencegah pembuatan writable shared mapping. Penambahannya dapat gagal dengan EBUSY selama writable shared mapping masih ada. Producer karena itu perlu memperhitungkan masa hidup mapping sebelum menjalankan transisi tersebut.

Urutan umum untuk payload immutable adalah:

buat memfd
    |
    v
tetapkan ukuran dan isi byte
    |
    v
hapus writable shared mapping
    |
    v
tambahkan seal GROW + SHRINK + WRITE
    |
    v
opsional: tambahkan SEAL
    |
    v
kirim descriptor ke consumer

Urutannya penting. Seal tidak membuat mapping writable yang tidak kompatibel menghilang secara retroaktif.

F_SEAL_FUTURE_WRITE membiarkan mapping writable lama tetap aktif

Linux juga menyediakan F_SEAL_FUTURE_WRITE. Seal ini mencegah penulisan berikutnya melalui write(2) dan mencegah writable shared mapping baru, tetapi writable shared mapping yang sudah ada saat seal ditambahkan masih dapat mengubah file.

Perbedaan tersebut membentuk batas handoff yang lain. Producer dapat mempertahankan mapping writable yang sudah dibuat sambil mencegah penerima memperoleh jalur writable baru melalui descriptor. Kondisi ini tidak setara dengan objek immutable selama mapping lama masih aktif.

F_SEAL_WRITE merupakan transisi yang lebih kuat ketika tidak ada writable shared mapping yang boleh bertahan.

Permission descriptor bukan batas yang sama

Mengirim descriptor sebagai read-only tidak selalu cukup sebagai model integritas objek. Access mode descriptor menggambarkan operasi yang tersedia melalui open file description tertentu, sedangkan seal membatasi objek file yang mendasarinya terhadap kelas mutasi tertentu.

Perbedaan ini penting ketika beberapa descriptor atau mapping sudah ada. Consumer yang memeriksa seal dapat menilai state pada tingkat objek, bukan hanya mengandalkan klaim mengenai descriptor yang dipakai sebagai transport.

Contohnya:

int seals = fcntl(fd, F_GET_SEALS);
if (seals == -1) {
    perror("F_GET_SEALS");
    return -1;
}

int required = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_WRITE;
if ((seals & required) != required) {
    fprintf(stderr, "payload is still mutable\n");
    return -1;
}

Pemeriksaan ini dapat menjadi bagian dari kontrak IPC: receiver menerima objek hanya setelah pembatasan yang diwajibkan terlihat pada file itu sendiri.

Sealing tidak mengautentikasi payload

Seal membatasi mutasi; seal tidak menetapkan asal, otorisasi, atau validitas semantik. Producer berbahaya dapat menyegel byte yang salah semudah menyegel byte yang benar. Receiver yang memerlukan autentisitas tetap membutuhkan mekanisme kepercayaan yang sesuai, misalnya signature terverifikasi, channel terautentikasi, atau identitas peer tepercaya.

Seal juga tidak menggantikan bounds check. Receiver tetap perlu memvalidasi ukuran file, offset, panjang internal, dan format data sebelum melakukan mapping atau parsing terhadap konten yang tidak tepercaya.

Properti keamanan yang diberikan lebih sempit: setelah seal yang diwajibkan aktif, operasi berikutnya yang tercakup oleh seal tersebut tidak dapat mengubah state objek yang sudah diterima melalui jalur mutasi file biasa.

Objek memfd tersegel cocok untuk batas handoff zero-copy

Memfd dapat diisi sekali, dipetakan proses lain tanpa penyalinan, lalu ditransfer dengan SCM_RIGHTS. Sealing memungkinkan producer membatasi objek sebelum transfer, sementara consumer dapat memverifikasi pembatasan melalui F_GET_SEALS.

Pola ini memisahkan transport dari mutabilitas. Descriptor membawa akses ke objek kernel yang sama; set seal mencatat mutasi berikutnya yang wajib ditolak kernel. Untuk shared buffer, artefak hasil generasi, dan payload IPC, pemisahan tersebut memberikan batas yang presisi antara tahap konstruksi dan konsumsi.