http://www.pronix.de -> Forum -> Knobelecke

Forum: Knobelecke

Moderatoren: broesel, juergen

Thema: 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 (externer link) - bitte Fragen einreichen :)

 

Re: Race Conditions, Teil 2

Patrick am 17.12.2010 um 07:24

Wieso file.txt ersetzen?
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

Nach meinen jetzigen Beobachtungen würde ich den Symlink file.txt auf eine nicht existierende Datei im Cron-Verzeichnis anlegen. Als Parameter wird eine Zeichenkette übergeben, die per Cron als root entsprechende Rechte verteilt.
Theoretisch Grafik: Smilie Gluecklich

--
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 (externer link) - bitte Fragen einreichen :)