![Seltsames Verhalten von pivot_root(".", ".") im Mount-Namespace](https://rvso.com/image/168809/Seltsames%20Verhalten%20von%20pivot_root(%22.%22%2C%20%22.%22)%20im%20Mount-Namespace.png)
Ich versuche, Container zu verstehen und bin auf einen Trick gestoßen, den anscheinend die LXC-Entwickler gefunden haben, siehediese runc PR: Sie können aufrufen pivot_root(".", ".")
, wodurch die Notwendigkeit eines Verzeichnisses, in das die alte Wurzel eingefügt werden kann, entfällt. Dies führt jedoch dazu, dass sich der Mount-Namespace merkwürdig verhält:
unshare --user --map-root-user --mount bash -c "
mount --bind containerfs bindmountpoint
cd bindmountpoint
pivot_root . .
# this is fine:
ls -l /
# this is not fine:
ls -l /..
"
Das übergeordnete Element von .
, auf das über ./..
oder zugegriffen wird /..
, /proc/<any>/cwd/..
zeigt auf die Wurzel des Root-Mount-Namespace (Verschachtelung habe ich noch nicht ausprobiert)! Es zeigt nicht auf das übergeordnete Element von containerfs
oder bindmountpoint
, sondern tatsächlich auf die Wurzel des Root-/äußeren Mount-Namespace.
Wenn ich es versuche nsenter --user --preserve-credentials --mount --target=<pid>
, wird das CWD dieses neuen Prozesses entsprechend an der Wurzel des Root-Mount-Namespace platziert.
Nichts davon passiert, wenn ich pivot_root(".", "oldroot")
. Das Verhalten verschwindet auch, wenn das alte Stammverzeichnis ausgehängt wird, entweder über einen Dateideskriptor umount -l /
oder umount -l /proc/1/cwd
.
Ich habe diese Abfolge von Systemaufrufen auch von einem benutzerdefinierten C-Programm aus ausprobiert, da die Dokumentation pivot_root
nur Garantien für den aktuellen Prozess gibt (also mache ich alles im selben Prozess). Das Verhalten ist dasselbe wie bei den oben gezeigten Schritten für mehrere Prozesse mit CLI-Tools.
Auf einem 5.3-Kernel getestet.
Was passiert, wenn ich laufe pivot_root(".", ".")
?
Antwort1
pivot_root(new_root, put_old)
verschiebt das alte Stammverzeichnis des aufrufenden Prozesses (das ein Stammverzeichnis eines Mounts sein muss) auf put_old
und setzt new_root
an dessen Stelle. Anschließend setzt es das aktuelle Verzeichnis und das Stammverzeichnis jedes Prozesses, der auf das alte Stammverzeichnis gesetzt war, auf new_root
.
Nachdem also pivot_root(".", ".")
das alte Stammverzeichnis über dem neuen Stammverzeichnis gemountet wurde.
Wenn ..
andernfalls ein Verzeichnis aufgelöst würde, auf dem ein anderes Verzeichnis gemountet ist, wird es tatsächlich in das Verzeichnis aufgelöst, das oben gemountet ist. Dies entspricht dem historischen Verhalten von Unix und Linux ..
, wo es außer im Stammverzeichnis eines Dateisystems keine spezielle Behandlung bei der Pfaddurchquerung gab und diese durch einen auf der Festplatte gespeicherten Verzeichniseintrag implementiert wurde.
Dies ist kein Aussteigen aus dem Mount-Namespace.
Antwort2
Sieht aus wie ein echter Fehler ...
Prüfen Sie den neuesten Kernel Ihrer Distribution und melden Sie ihn mit allen Details (hängen Sie Ihr Testprogramm an!).