Dokumentasi kernel linux mengklaim:
Rootfs adalah contoh khusus dari ramfs (atau tmpfs, jika diaktifkan),
yang selalu ada di sistem 2.6. Anda tidak dapat meng-unmount rootfs ...
Pada semua sistem linux yang saya uji (kernel> 2.6 dan prosedur boot normal afaik, misalnya ubuntu 12.04), mount
tidak menampilkan rootfs
entri.
Namun, dengan gambar buildroot saat boot dengan .cpio
eksternal arsip, itu ada.
Dalam kasus apa ada rootfs
entri di mount
?
Jawaban yang Diterima:
- Pada sistem lama,
mount
mungkin tidak setuju dengan/proc/mounts
- Sering kali Anda tidak akan melihat
rootfs
di/proc/mounts
, tetapi masih terpasang. - Dapatkah kita membuktikan bahwa rootfs masih terpasang?
1. Pada sistem lama, mount
mungkin tidak setuju dengan /proc/mounts
man mount
mengatakan:“Program mount
dan umount
secara tradisional memelihara daftar sistem file yang saat ini dipasang di file /etc/mtab
.”
Pendekatan lama tidak benar-benar berfungsi untuk sistem file root. Sistem file root mungkin telah di-mount oleh kernel, bukan oleh mount
. Oleh karena itu entri untuk /
di /etc/mtab
mungkin dibuat-buat, dan belum tentu sinkron dengan daftar mount kernel saat ini.
Saya belum memeriksa secara pasti, tetapi dalam praktiknya saya tidak berpikir sistem apa pun yang menggunakan skema lama akan menginisialisasi mtab
untuk menampilkan baris dengan rootfs
. (Secara teori, apakah mount
menunjukkan rootfs
akan tergantung pada perangkat lunak yang pertama kali menginstal mtab
berkas).
man mount
melanjutkan:“file mtab yang sebenarnya masih didukung, tetapi pada sistem Linux saat ini, lebih baik menjadikannya symlink ke /proc/mounts sebagai gantinya, karena file mtab biasa yang disimpan di ruang pengguna tidak dapat bekerja dengan baik dengan ruang nama, wadah, dan Linux canggih lainnya. fitur.”
mtab diubah menjadi symlink di Debian 7, dan di Ubuntu 15.04.
1.1 Sumber
Laporan Debian #494001 – “debian-installer:/etc/mtab harus symlink ke /proc/mounts dengan linux>=2.6.26”
#494001 diselesaikan di sysvinit-2.88dsf-14. Lihat pesan penutup, tertanggal 14 Des 2011. Perubahan tersebut disertakan dalam Debian 7 “Wheezy”, dirilis pada 4 Mei 2013. (Menggunakan sysvinit-2.88dsf-41).
Ubuntu menunda perubahan ini hingga sysvinit_2.88dsf-53.2ubuntu1. Halaman changelog itu menunjukkan perubahan memasuki “vivid”, yang merupakan nama kode untuk Ubuntu 15.04.
2. Sebagian besar waktu Anda tidak akan melihat rootfs
di /proc/mounts
, tetapi masih terpasang
Pada Linux v4.17, dokumentasi kernel ini masih mutakhir. rootfs selalu ada, dan tidak akan pernah bisa dilepas. Tetapi seringkali Anda tidak dapat melihatnya di /proc/mounts.
Anda dapat melihat rootfs jika Anda boot ke shell initramfs. Jika initramf Anda adalah dracut
, seperti di Fedora Linux, Anda dapat melakukannya dengan menambahkan opsi rd.break
ke baris perintah kernel. (Misalnya di dalam boot loader GRUB).
switch_root:/# grep rootfs /proc/mounts
rootfs / rootfs rw 0 0
Saat dracut mengalihkan sistem ke sistem file root yang sebenarnya, Anda tidak dapat lagi melihat rootf di /proc/mounts. dracut dapat menggunakan switch_root
atau systemd
untuk melakukan ini. Keduanya mengikuti urutan operasi yang sama, yang disarankan dalam dokumen kernel tertaut.
Di beberapa posting lain, orang dapat melihat rootf di /proc/mounts setelah beralih dari initramfs. Misalnya di Debian 7:‘Bagaimana saya bisa mengetahui tentang “rootfs”‘. Saya pikir ini pasti karena kernel mengubah tampilannya /proc/mounts, di beberapa titik antara versi kernel di Debian 7 dan kernel v4.17 saya saat ini. Dari pencarian lebih lanjut, saya pikir rootfs ditampilkan di Ubuntu 14.04, tetapi tidak ditampilkan di Ubuntu 16.04 dengan kernel Ubuntu 4.4.0-28-generic.
Terkait:Linux – Apa arti huruf 'u' di /dev/urandom?Bahkan jika saya tidak menggunakan initramfs, dan meminta kernel me-mount sistem file root, saya tidak dapat melihat rootf di /proc/mounts. Ini masuk akal karena kode kernel juga tampaknya mengikuti urutan operasi yang sama.
Operasi yang menyembunyikan rootfs adalah chroot
.
switch_root:/# cd /sysroot
switch_root:/sysroot# mount --bind /proc proc
switch_root:/sysroot# grep rootfs proc/mounts
rootfs / rootfs rw 0 0
switch_root:/sysroot# chroot .
sh-4.4# cat proc/mounts
/dev/sda3 / ext4 ro,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
3. Bisakah kita membuktikan bahwa rootfs masih terpasang?
Yang terkenal, chroot
simple sederhana dapat diloloskan dari saat Anda menjalankan sebagai pengguna istimewa. Jika switch_root
tidak melakukan apa-apa selain chroot
, kita bisa membalikkannya dan melihat rootfnya lagi.
sh-4.4# python3
...
>>> import os
>>> os.system('mount --bind / /mnt')
>>> os.system('cat proc/mounts')
/dev/sda3 / ext4 ro,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
/dev/sda3 /mnt ext4 ro,relatime 0 0
>>> os.chroot('/mnt')
>>>
>>> # now the root, "/", is the old "/mnt"...
>>> # but the current directory, ".", is outside the root :-)
>>>
>>> os.system('cat proc/mounts')
/dev/sda3 / ext4 ro,relatime 0 0
>>> os.chdir('..')
>>> os.system('bash')
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
bash-4.4# chroot .
sh-4.4# grep rootfs proc/mounts
rootfs / rootfs rw 0 0
Namun, switch_root
lengkap urutan tidak dapat dibalik dengan teknik ini. Urutan lengkapnya tidak
-
Ubah direktori kerja saat ini (seperti dalam
/proc/self/cwd
), ke titik pemasangan sistem file baru:cd /newmount
-
Pindahkan sistem file baru, yaitu mengubah titik pemasangannya, sehingga berada tepat di atas direktori root.
mount --move . /
-
Ubah direktori root saat ini (seperti dalam
/proc/self/root
) agar sesuai dengan direktori kerja saat ini.chroot .
Dalam pelarian chroot di atas, kami dapat melintasi dari direktori root ext4
sistem file kembali ke rootfs
menggunakan ..
, karena ext4
filesystem dipasang pada subdirektori rootfs
. Metode escape tidak berfungsi saat ext4
sistem file dipasang di root direktori rootfs.
Saya dapat menemukan rootfs
menggunakan metode yang berbeda. (Setidaknya satu pengembang kernel penting menganggap ini sebagai bug di Linux).
http://archive.today/2018.07.22-161140/https://lore.kernel.org/lkml/[email protected]/
/* CURSED.c - DO NOT RUN THIS PROGRAM INSIDE YOUR MAIN MOUNT NAMESPACE */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /* open() */
#include <sys/mount.h>
#include <sched.h> /* setns() */
#include <sys/statfs.h>
int main() {
int fd = open("/proc/self/ns/mnt", O_RDONLY);
/* "umount -l /" - lazy unmount everything we can see */
umount2("/", MNT_DETACH);
/* reset root, by re-entering our mount namespace */
setns(fd, CLONE_NEWNS);
/* "stat -f /" - inspect the root */
struct statfs fs;
statfs("/", &fs);
}
Diuji pada Linux 4.17.3-200.fc28.x86_64:
$ make CURSED
cc CURSED.c -o CURSED
$ sudo unshare -m strace ./CURSED
...
openat(AT_FDCWD, "/proc/self/ns/mnt", O_RDONLY) = 3
umount2("/", MNT_DETACH) = 0
setns(3, CLONE_NEWNS) = 0
statfs("/", {f_type=RAMFS_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID}) = 0
^
^ result: rootfs uses ramfs code on this system
(Saya juga mengonfirmasi bahwa sistem file ini kosong seperti yang diharapkan, dan dapat ditulisi).