Sebuah proses dapat membentuk mapping memori dengan alamat, ukuran, dan protection bit tertentu, lalu mengubah mapping itu melalui operasi seperti munmap(), mprotect(), atau mremap(). Linux mseal() menambahkan transisi state satu arah: virtual memory area terpilih dapat disegel sehingga sejumlah perubahan mapping berikutnya ditolak oleh kernel.
Mekanisme ini melindungi struktur mapping, bukan byte yang tersimpan di dalamnya. Mapping writable yang disegel tetap dapat ditulis melalui store biasa. Sealing membatasi operasi yang dapat menghapus mapping, memindahkannya, menggantinya, atau mengubah atribut yang tercakup oleh aturan sealing.
Seal melekat pada virtual memory area
mseal() menerima alamat, panjang, dan argumen flags. Alamat awal harus page-aligned, sedangkan kedua ujung interval yang diminta harus berada di memori virtual yang sudah dialokasikan. Gap di dalam interval tidak diterima. Kernel membulatkan panjang ke batas page sesuai kontrak interface.
Pemanggilan yang berhasil menandai mapping yang tercakup sebagai sealed. Operasi yang sama pada memori yang sudah sealed tidak menimbulkan masalah. Interface ini sengaja tidak menyediakan operasi kebalikan untuk melepas seal.
Sifat irreversible tersebut merupakan bagian inti mekanisme. Kode dapat menyusun state address space saat inisialisasi, lalu mengurangi kumpulan transformasi yang tersedia selama sisa masa hidup proses.
Operasi yang mengubah tata letak dibatasi
Seal memblokir operasi yang dapat membongkar atau membentuk ulang mapping terlindungi. munmap() tidak dapat menghapus region yang sealed. mremap() tidak dapat digunakan untuk memindahkan atau mengubah ukurannya, sedangkan mmap() tidak dapat mengganti mapping sealed dengan mapping baru pada alamat yang sama.
Batas ini juga mencakup perubahan permission. mprotect() dan pkey_mprotect() ditolak ketika mencoba perubahan terlarang yang melibatkan mapping sealed. Jalur kode berikutnya tidak dapat memakai interface tersebut untuk menulis ulang protection state yang telah ditetapkan sebelum sealing.
Efeknya berbeda dari sekadar menyimpan metadata mapping yang diharapkan di state aplikasi. Pembatasan diterapkan pada jalur memory management kernel, sehingga kode yang berjalan di proses yang sama tidak dapat mengabaikan flag tingkat aplikasi lalu menjalankan operasi mapping yang diblokir.
Sealing tidak membuat data writable menjadi immutable
Nama mekanisme ini dapat memberi kesan semantik data yang lebih kuat daripada kontrak syscall sebenarnya. mseal() tidak mengubah page writable menjadi storage read-only. Jika sebuah mapping memiliki PROT_WRITE, write biasa tetap mengikuti permission tersebut setelah sealing.
Untuk data yang harus menjadi read-only, proses dapat lebih dulu menetapkan protection yang diinginkan melalui mprotect(), kemudian menyegel mapping hasilnya. Urutannya penting: setelah mapping disegel, transformasi memory management yang diblokir tidak dapat dipakai sebagai jalur rekonfigurasi rutin.
Pemisahan ini menghasilkan dua properti berbeda. Page permission mengatur akses memori seperti read, write, dan instruction fetch. Seal mengatur percobaan berikutnya untuk mengubah properti tertentu dari mapping itu sendiri.
Advice destruktif juga termasuk dalam batas
Sejumlah perilaku madvise() dapat membuang atau mengubah isi mapping secara material tanpa mengubah rentang alamat yang terlihat. Karena itu, Linux memblokir operasi advice destruktif tertentu pada mapping sealed, termasuk perilaku discard dan fork terkait yang tercantum dalam kontrak interface.
Pembatasan tersebut menutup celah yang muncul jika sealing hanya menjaga mmap(), munmap(), dan perubahan protection. Tanpa batas itu, mapping dapat mempertahankan alamat virtual dan permission bit yang sama saat operasi lain membuang backing content-nya.
Tidak semua perintah madvise() memiliki semantik setara, dan sealing bukan larangan menyeluruh terhadap seluruh advice. Software yang bergantung pada operasi advice tertentu perlu memakai daftar operasi terblokir yang terdokumentasi sebagai kontrak syscall, bukan menyimpulkan perilakunya hanya dari nama mekanisme.
Kegagalan pada beberapa mapping perlu diperlakukan secara spesifik
System call memory management dapat mencakup lebih dari satu VMA. Untuk sebagian operasi yang diblokir, kegagalan akibat VMA sealed tidak berarti seluruh bagian sebelumnya dari permintaan multi-VMA tetap tidak berubah. Dokumentasi kernel membedakan operasi yang bersifat atomic dari kasus yang dapat mengalami partial update sebelum EPERM dikembalikan.
munmap() didokumentasikan atomic terhadap pemeriksaan sealing ini: jika VMA sealed ditemukan dalam rentang yang diberikan, VMA dalam permintaan tersebut tidak di-unmap. Operasi lain, termasuk sebagian perubahan protection dan advice, dapat memiliki perilaku partial update yang berbeda.
Kode yang menganggap error return sebagai sinyal rollback universal dapat memiliki model address space yang keliru setelah kegagalan. Semantik kegagalan syscall terkait tetap penting meski sealing sudah diterapkan.
Batas berlaku pada state memori proses
Mapping sealed tetap menjadi bagian dari address space proses sampai proses berakhir, kecuali terdapat jalur kernel yang diizinkan dengan semantik di luar kumpulan transformasi yang diblokir. Mekanisme ini tidak membuat seal persisten pada file backing dan tidak mengubah mapping independen milik proses lain terhadap file yang sama.
Karakteristik tersebut membedakan mseal() dari file seal pada objek seperti file memfd. File sealing membatasi operasi pada objek file menurut aturannya sendiri. Memory sealing membatasi transformasi VMA tertentu dalam satu address space proses.
Perbedaan ini penting ketika file yang sama dipetakan ke beberapa proses. Menyegel mapping pada satu proses tidak mengubah shared backing file menjadi resource immutable bagi semua proses yang memakainya.
Dukungan arsitektur merupakan batas deployment
Interface Linux saat ini dibangun untuk kernel 64-bit. Pada kernel yang tidak mendukungnya, syscall tidak tersedia dan mengembalikan hasil not-implemented yang sesuai. Software yang memakai sealing sebagai batas keamanan memerlukan kebijakan eksplisit untuk kernel yang tidak menyediakannya.
Melanjutkan eksekusi secara diam-diam tanpa seal dapat mengubah invariant wajib menjadi preferensi best-effort. Program dapat memilih untuk gagal saat startup, menonaktifkan fitur yang bergantung pada invariant tersebut, atau memakai mekanisme isolasi lain sesuai threat model.
mseal() paling tepat ditempatkan setelah proses selesai menyusun region memori yang tata letak dan permission-nya tidak boleh dikonfigurasi ulang. State yang sudah ditetapkan kemudian menjadi batas satu arah yang dipaksakan kernel, sementara akses memori biasa tetap mengikuti permission yang telah melekat pada setiap mapping.