Forum: Knobelecke
Moderatoren: broesel, juergenThema: Race Conditions, Teil 2
Re: Race Conditions, Teil 2
Martin Conrad (webmaster) am 16.12.2010 um 19:00
Zitat:
Btw. TOCTOU ist die Bezeichnung für diese Art von Fehler.
http://en.wikipedia.org/wiki/Time-of-check-to-time-of-use
Jau, danke.
Der wirkliche Fehler liegt übrigens in meinen Augen im Rollensystem. Nicht, dass ich ne bessere Lösung hätte, aber suid und sudo werden immer Löcher aufreissen...
Bis denne
Martin
--
0xC0FFEE
Re: Race Conditions, Teil 2
broesel (webmaster) am 16.12.2010 um 23:13
Zitat:
Ich versteh aber noch nicht was du verlinken willst. stat() sollte doch nur die Einträge genauer untersuchen, nach denen es gefragt wurde und die andern einfach nach erfolglosem Namensvergleich überspringen?
Stimmt, aber den erfolglosen Namensabgleich kann man nutzen: Unmengen von Dateien im gleichen Verzeichnis anlegen, die alle den gleichen Hashwert wie "file.txt" haben. In der Kernel-internen Hashtabelle befindet sich dann "file.txt" in einer sehr langen Liste von anderen Namen, die erstmal durchsucht werden will. Das setzt natürlich voraus, dass wir genug Dateien anlegen können, um die Suche nach dem richtigen Dateinamen ausreichend zu verzögern.
Eine erfolgversprechendere Methode ist die folgende, welche auch in den Referenzen zu Patricks Wikipedia-Artikel zu finden ist, deshalb erspar ich euch die Mühe:
Wir legen eine sehr tiefe Verzeichnisstruktur an, welche im dazugehörigen Paper als "directory maze" bezeichnet wird:
/d/d/d/d/.../d/link1 -> link2
link2/d/d/.../d/link3 -> link4
link4/d/d/.../d/link5 -> ...
.../d/d/.../d/linkN
Dann löschen wir linkN. Ein Aufruf von stat() muss also erstmal jedes Verzeichnis auflösen und dann jedem symbolischen Link folgen, nur um dann herauszufinden dass der Link gar kein gültiges Ziel hat.
Die maximale Pfadlänge ist häufig begrenzt, üblicherweise auf 4096 Bytes. Pro Verzeichniskette können wir also etwas mehr als 2000 Verzeichnisse anlegen. Die maximale Linktiefe ist ebenfalls häufig begrenzt, unter Linux 2.6 beispielsweise auf 40 Level.
Das bringt uns auf etwas über 2000*40 = 80.000 directory lookups. Bei einer typischen Inode-Größe von 4096 Bytes sind das etwas mehr als 300MB, die von der Platte gelesen und anschließend geparst werden müssen. Da hilft auch kein RAID.
Während dieser Zeit sollte es uns möglich sein, dem stat() gewissermaßen unter der Nase weg file.txt zu ersetzen, um beispielsweise auf /etc/passwd zu zeigen.
Na denn auf zu Teil 3!
Gruss,
Philip
--
The C Programming Quiz
- bitte Fragen einreichen :)
Re: Race Conditions, Teil 2
Patrick am 17.12.2010 um 07:24
Nur wenn der Symlink file.txt auf nichts verweist, läuft das Programm durch.
Zeigt der Symlink auf etwas, bricht das Programm ab.
Oder möchte ich den Symlink ersetzen, während er überprüft wird?
So ganz habe ich das wohl nicht verstanden :-/
Nachtrag:
Bei dem auf Wikipedia gezeigten Angriff muss die Datei existieren.
Hier nicht.
--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.
Re: Race Conditions, Teil 2
Patrick am 17.12.2010 um 07:35
Theoretisch
--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.
Re: Race Conditions, Teil 2
broesel (webmaster) am 19.12.2010 um 00:12
Zitat:
Oder möchte ich den Symlink ersetzen, während er überprüft wird?
Genau! Zuerst wird das directory maze angelegt. "file.txt" ist ein Symlink und zeigt auf den Anfang davon. Dann wird das Programm gestartet. Während dieses sich jetzt durch das directory maze hangelt, löschen wir file.txt und legen einen neuen Symlink file.txt -> /etc/passwd (oder wohin auch immer) an.
Wenn das Programm am Ende des directory maze herausfindet, dass der letzte Symlink auf eine nicht existierende Datei zeigt, liefert stat() einen Wert ungleich 0 und das Programm läuft weiter, öffnet file.txt und schreibt dort rein.
Gruss,
Philip
--
The C Programming Quiz
- bitte Fragen einreichen :)
