Sebuah proses dapat masuk ke mount namespace Linux baru tetapi tetap melihat mount yang kemudian dibuat di tempat lain. Batas namespace tetap ada: proses tersebut memiliki tabel mount sendiri. Mount baru muncul karena sebagian mount di kedua namespace masih terhubung melalui relasi propagasi.
Perbedaan ini penting pada container runtime, sandbox layanan, sistem build, dan helper berprivilege. Membuat mount namespace memisahkan tampilan tabel mount milik namespace, tetapi tindakan itu sendiri tidak membuat setiap event mount berikutnya bersifat lokal. Status shared-subtree menentukan apakah event mount dan unmount dapat melintasi batas tersebut.
Status yang relevan merupakan properti mount, bukan properti global sebuah namespace. Satu namespace dapat memuat mount shared, slave, private, dan unbindable secara bersamaan. Isolasi filesystem karena itu bergantung pada keanggotaan namespace sekaligus topologi propagasi mount di dalamnya.
Pembuatan namespace menyalin topologi mount
Mount namespace baru yang dibuat dengan clone() atau unshare() dimulai dengan daftar mount yang berasal dari namespace yang sudah ada. Setelah dibuat, kedua namespace dapat mengubah tabel mount masing-masing secara independen, dengan tetap tunduk pada propagasi shared-subtree.
Batasan tersebut penting. Jika mount yang bersesuaian berstatus shared, hasil kloning mount itu tetap menjadi anggota peer group yang sama. Event mount atau unmount di bawah satu peer dapat dipropagasikan ke peer lain. Namespace tetap terpisah, tetapi perubahan topologi tertentu masih saling terhubung.
Perilaku ini menyelesaikan kebutuhan operasional nyata. Host dapat membuat filesystem yang baru dipasang terlihat oleh namespace dependen tanpa menjalankan operasi mount yang sama secara terpisah di setiap namespace. Mekanisme yang sama juga dapat merusak asumsi isolasi ketika perangkat lunak menganggap CLONE_NEWNS setara dengan tampilan filesystem yang sepenuhnya terputus.
Properti keamanannya jadi lebih sempit: mount namespace memisahkan keanggotaan tabel mount, sedangkan status propagasi mengendalikan aliran event di antara mount yang saling terkait.
Mount shared membentuk kanal event dua arah
Mount shared menjadi anggota sebuah peer group. Event mount dan unmount di bawah mount shared dipropagasikan ke mount lain dalam peer group tersebut, dan event dari peer itu dapat dipropagasikan kembali.
Relasi ini berkaitan dengan topologi mount. Relasi tersebut tidak menggabungkan kredensial proses, file descriptor, atau identitas namespace. Mekanisme propagasi juga tidak mereplikasi penulisan file biasa. Objek yang dipropagasikan adalah event mount dan unmount pada lokasi yang bersesuaian.
Perbedaan ini sangat penting bagi host berprivilege dan workload yang dibatasi. Jika path host dan path workload tetap menjadi peer dalam grup shared, operasi mount yang dilakukan dari sisi workload dapat merambat keluar ketika topologinya mengizinkan. Desain yang mengharapkan mount dari dalam workload tetap lokal harus memutus atau mengarahkan ulang relasi propagasi tersebut.
Peer group dapat melintasi batas namespace. Memeriksa bahwa dua proses memiliki identifier mount namespace yang berbeda saja tidak membuktikan bahwa event mount tidak dapat berpindah di antara tampilan filesystem keduanya.
Mount slave membuat propagasi menjadi searah
Mount slave menerima event propagasi dari master peer group, tetapi tidak mengirim event miliknya kembali ke master tersebut. Sifat ini membentuk batas asimetris yang berguna.
Sandbox dapat memerlukan mount dari sisi host sambil menjaga agar mount yang dibuat di dalam sandbox tidak muncul pada host. Menandai tree terkait sebagai slave dapat menyediakan arah tersebut. Event host mengalir masuk; event lokal tidak mengalir kembali melalui relasi master.
Sebuah mount juga dapat berstatus slave sekaligus shared. Dalam keadaan ini, mount menerima event dari master di sisi hulu dan dapat mendistribusikan event di antara peer group miliknya serta slave di sisi hilir. Topologi propagasi dengan demikian dapat membentuk hierarki, bukan sekadar pasangan namespace.
Karena itu, slave merupakan relasi berarah, bukan sinonim dari kondisi terisolasi. Status tersebut sengaja mempertahankan satu jalur propagasi.
Mount private memutus kedua arah propagasi
Mount private tidak mengirim maupun menerima event propagasi. Mengubah sebuah subtree menjadi private merupakan pilihan langsung ketika aktivitas mount di bawah subtree itu harus terputus dari propagasi peer.
Bentuk rekursif penting untuk tree yang memiliki mount bertingkat. Mengubah satu mount saja tidak otomatis menyatakan kebijakan yang dimaksud bagi setiap turunannya. Kode runtime sering menerapkan perubahan propagasi secara rekursif ketika menyiapkan tree mount terisolasi karena mount bertingkat dapat tetap memiliki relasi yang tidak sesuai dengan batas yang diharapkan untuk keseluruhan tree.
Status private tidak menyediakan seluruh properti keamanan filesystem. Proses masih dapat mengakses objek filesystem dasar yang sama melalui path yang terlihat di namespace masing-masing, dan kontrol akses discretionary atau mandatory tetap berlaku. Propagasi private mencegah event topologi melintasi relasi propagasi; status itu tidak membuat objek penyimpanan baru atau mencabut akses ke objek yang sudah ada.
Status unbindable juga memblokir replikasi bind
Mount unbindable memiliki perilaku propagasi private dan juga tidak dapat digunakan sebagai sumber bind mount. Dalam operasi recursive bind, subtree unbindable dipangkas dari tree hasil replikasi.
Properti tambahan itu berguna ketika sebuah mount tidak boleh direplikasi ke lokasi lain melalui bind mounting. Sifat ini berbeda dari status private biasa: keduanya menghentikan propagasi, tetapi hanya unbindable yang menambahkan pembatasan bind.
Perbedaan tersebut juga menunjukkan bahwa isolasi mount memiliki beberapa dimensi. Propagasi event mengendalikan perubahan topologi berikutnya, sedangkan kelayakan bind mengendalikan apakah subtree yang sudah ada dapat direplikasi ke lokasi mount lain. Sebuah desain keamanan dapat memerlukan salah satu atau kedua properti tersebut.
User namespace menambahkan batas privilege lain
Mount namespace memiliki user namespace pemilik. Ketika sebuah mount namespace memiliki privilege lebih rendah daripada namespace asal daftar mount yang disalin, kernel menerapkan pembatasan tambahan. Secara khusus, mount shared yang disalin ke mount namespace dengan privilege lebih rendah diturunkan menjadi slave agar event mount yang dibuat di namespace tersebut tidak dipropagasikan kembali ke namespace yang lebih berprivilege.
Kernel juga mengunci mount yang masuk sebagai satu unit dari namespace yang lebih berprivilege dalam kondisi yang ditetapkan antarmuka mount namespace. Hal ini mencegah namespace dengan privilege lebih rendah sekadar melakukan unmount terhadap mount pelindung tertentu yang diwarisi dari konteks dengan privilege lebih tinggi.
Aturan tersebut memperkuat batas, tetapi tidak membuat status propagasi menjadi tidak relevan. Kebijakan deployment tetap perlu menentukan event host mana yang boleh masuk ke namespace turunan dan subtree mana yang harus sepenuhnya private.
Kebijakan propagasi merupakan bagian dari konstruksi sandbox
Sandbox mount yang kokoh memiliki dua pertanyaan terpisah. Pertama, mount namespace mana yang ditempati proses. Kedua, relasi propagasi mana yang masih tersisa pada mount yang terlihat di sana.
Untuk subtree yang sepenuhnya lokal, propagasi private menghapus aliran event pada kedua arah. Untuk subtree yang perlu menerima mount host tanpa mengekspor event mount lokal, propagasi slave menyatakan kebijakan asimetris tersebut. Propagasi shared tepat digunakan hanya ketika distribusi event dua arah memang disengaja. Status unbindable menambahkan pembatasan terpisah terhadap replikasi bind.
Pilihan tersebut adalah aturan topologi yang dipaksakan kernel, bukan sekadar label yang melekat pada konsep container. Batas efektif terlihat pada graph mount itu sendiri. Pemisahan namespace menyediakan ruang bagi tampilan filesystem yang terisolasi; status propagasi menentukan event mount berikutnya yang tetap diizinkan melintasi ruang tersebut.