Warum kann ich keinen "Hardlink" zu einer Datei aus einem "mount --bind" -Verzeichnis im selben Dateisystem erstellen?

9

Ursprüngliches Problem

Ich habe eine Datei in einem Dateisystem: /data/src/file

und ich möchte es fest verknüpfen mit: /home/user/proj/src/file

aber /homeist auf einer Festplatte und /dataist auf einer anderen, so dass ich eine Fehlermeldung bekomme:

$ cd /home/user/proj/src
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Okay, ich habe gelernt, dass ich keine feste Verbindung zwischen Geräten herstellen kann. Macht Sinn.

Problem zur Hand

Also dachte ich, ich würde Lust bekommen und einen srcOrdner binden , der sich im /dataDateisystem befindet:

$ mkdir -p /data/other/src
$ cd /home/user/proj
$ sudo mount --bind /data/other/src src/
$ cd src
$ # (now we're technically on `/data`'s file system, right?)
$ ln /data/src/file .
ln: failed to create hard link './file' => '/data/src/file': Invalid cross-device link

Warum funktioniert das immer noch nicht?

Problemumgehung

Ich weiß, dass ich dieses Setup richtig habe, weil ich den festen Link herstellen kann, solange ich mich im "echten" /dataVerzeichnis anstatt im gebundenen befinde.

$ cd /data/other/src
$ ln /data/src/file .
$ # OK
$ cd /home/user/proj/src
$ ls -lh
total 35M
-rw------- 2 user user 35M Jul 17 22:22 file

$

Einige Systeminformationen

$ uname -a
Linux <host> 4.10.0-24-generic #28-Ubuntu SMP Wed Jun 14 08:14:34 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

$ findmnt
.
.
.
├─/home                               /dev/sdb8   ext4       rw,relatime,data=ordered
│ └─/home/usr/proj/src             /dev/sda2[/other/src]
│                                                 ext4       rw,relatime,data=ordered
└─/data                               /dev/sda2   ext4       rw,relatime,data=ordered

$ mountpoint -d /data
8:2

$ mountpoint -d /home/usr/proj/src/
8:2

Hinweis : Ich habe die Datei- und Verzeichnisnamen manuell geändert, um die Situation klarer zu gestalten, sodass die Befehlsanzeigen möglicherweise ein oder zwei Tippfehler enthalten.

jdk1.0
quelle
2
Es spielt keine Rolle, wo Sie Ordner mounten. Sie befinden sich physisch auf verschiedenen Partitionen. Jede Partition hat eine eigene Dateitabelle und der Hardlink wird nur in dieser Tabelle aufgezeichnet.
user996142
2
Der Punkt hier ist, dass sich Dateien NICHT auf physisch unterschiedlichen Partitionen befinden. Es ist dasselbe Dateisystem von derselben Partition. Der Unterschied ist das Bind Mount.
Roaima
Das Bind Mount ist nur eine Fiktion. Die Datenstrukturen auf den Datenträgern werden nicht geändert. Die Dateisysteme sind physisch immer noch getrennt.
Bob Eager
Wenn ich jedoch den Hardlink auf erstelle, /datakann ich über das Bind-Mount-Verzeichnis auf den Inode zugreifen. Daher muss sich entweder der Bind-Mount auf derselben Partition befinden wie /dataoder der Hardlink funktioniert geräteübergreifend, was illegal sein sollte, aber trotzdem funktioniert. Was vermisse ich?
JDK1.0

Antworten:

6

Es gibt einen enttäuschenden Mangel an Kommentaren im Code . Es ist, als ob niemand es jemals für nützlich gehalten hätte, da die Time-Bind-Mounts in Version 2.4 implementiert wurden. Sicherlich müssten Sie nur ersetzen, .mnt->mnt_sbwo es heißt .mnt...

Weil es Ihnen eine Sicherheitsgrenze um einen Teilbaum gibt.

PS: Das wurde schon einige Male diskutiert, aber um Suchen zu vermeiden: Betrachten Sie zB mount --bind / tmp / tmp; Jetzt haben Sie eine Situation, in der Benutzer keine Links zu anderen Root-Fs erstellen können, obwohl sie / tmp für sie beschreibbar haben. Ähnliche Techniken funktionieren für andere Isolationsanforderungen - im Grunde können Sie das Umbenennen / Verknüpfen auf einen bestimmten Teilbaum beschränken. IOW, es ist eine bewusste Funktion. Beachten Sie, dass Sie eine Reihe von Bäumen in Chroot binden und vorhersehbare Einschränkungen erhalten können, unabhängig davon, wie das Material ein Jahr später im Hauptbaum usw. neu angeordnet wird.

- Al Viro

Es gibt ein konkretes Beispiel weiter unten im Thread

Immer wenn mount -r --bind ordnungsgemäß funktioniert (mit dem ich Kopien der erforderlichen gemeinsam genutzten Bibliotheken in Chroot-Jails platziere und gleichzeitig die Freigabe des Seitencaches erlaube), würde diese Funktion die Sicherheit beeinträchtigen.

mkdir /usr/lib/libs.jail
for i in $LIST_OF_LIBRARIES; do
ln /usr/lib/$i /usr/lib/libs.jail/$i
done
mount -r /usr/lib/libs.jail /jail/lib
chown prisoner /usr/log/jail
mount /usr/log/jail /jail/usr/log
chrootuid /jail prisoner /bin/untrusted &

Zwar sollte der Schutz ausreichen, aber ich möchte lieber vermeiden, dass der Gefangenenlink /jail/lib/libfoo.so (Schreiben gibt EROFS zurück) nach / jail / usr / log führt, wo er möglicherweise beschreibbar ist.

sourcejedi
quelle
-1

Der Grund, warum Sie keine geräteübergreifende Verknüpfung durchführen können, liegt darin, dass Sie Mehrdeutigkeiten einführen. Der Verzeichniseintrag für die Datei enthält (in einfachen Systemen) die i-Node-Nummer für die betreffende Datei. Ein fester Link (nur ein weiterer Verzeichniseintrag) muss ebenfalls dieselbe i-Node-Nummer enthalten. Dies ist in Ordnung, aber i-Node-Nummern sind nur innerhalb eines einzelnen Dateisystems eindeutig (sie sind normalerweise eine dichte Menge ab 1).

Ihr Bind Mount behebt dieses Problem nicht. Ja, es erstellt eine Art "Fiktion" der Struktur, aber was es nicht tut, ist, alle i-Knoten in einem Dateisystem neu zu nummerieren, um sicherzustellen, dass sie alle in beiden betroffenen Dateisystemen eindeutig sind! Das wäre dumm.

Diese Einschränkung gab es auf UNIX-Systemen schon immer. Die symbolische Verbindung wurde teilweise erfunden, um dies zu lösen. Ich weiß, dass sie funktionell nicht ganz gleich sind, aber normalerweise sind sie in Ordnung.

Versuchen Sie einen symbolischen Link? ( ln -s)

Bob Eager
quelle
Es würde keinen Namen für eine hier neu nummerierte Inode geben. Es gibt nur ein zugrunde liegendes Dateisystem mit zwei Ansichten.
Gilles 'SO - hör auf böse zu sein'
Ein Grund, warum ich keine symbolische Verbindung wollte, war, dass meine Wege lang waren und es unordentlich war, eine zu machen ls -l. Zuerst ein bisschen albern, aber dann führte es zu einem Kaninchenbau und ich wurde neugierig, was mit den harten Links los war ...
jdk1.0
@ Gilles, das habe ich gesagt. Der Punkt, den ich machte, war, dass eine Inode-Umnummerierung lächerlich wäre. Keine Ahnung, warum eine richtige Antwort abgelehnt wurde.
Bob Eager
Sie kommen zu dem richtigen Schluss, aber Ihre Erklärung ist an so vielen Stellen falsch, dass Ihre Antwort insgesamt sehr irreführend ist. Eine gute Erklärung finden Sie in der Antwort von sourcejedi.
Gilles 'SO - hör auf böse zu sein'
Ich sehe überhaupt keine Fehler, obwohl ich zugeben muss, dass ich klarer hätte sein können.
Bob Eager