2010-03-31 18 views
6
  • Ich möchte Daten an eine Datei in/tmp anhängen.
  • Wenn die Datei nicht existiert, möchte ich sie erstellen
  • Es ist mir egal, ob jemand anderes die Datei besitzt. Die Daten sind nicht geheim.
  • Ich möchte nicht, dass jemand in der Lage ist, dies in eine andere Datei oder in eine andere Datei zu schreiben.

Was ist der beste Weg, dies zu tun?Wie sollte ich vor harten Linkangriffen schützen?

Hier ist mein Gedanke:

fd = open("/tmp/some-benchmark-data.txt", O_APPEND | O_CREAT | O_NOFOLLOW | O_WRONLY, 0644); 
fstat(fd, &st); 
if (st.st_nlink != 1) { 
    HARD LINK ATTACK! 
} 

Problem mit dieser: Jemand die Datei zu einem gewissen kurzlebig Datei von mir verknüpfen kann, so dass /tmp/some-benchmark-data.txt das gleiche wie/tmp/tmpfileXXXXXX welches ein anderes Skript von mir benutzt (und korrekt mit O_EXCL und all dem geöffnet wurde). Meine Benchmarkdaten werden dann an diese/tmp/tmpfileXXXXXX-Datei angehängt, solange sie noch verwendet wird.

Wenn mein anderes Skript zufällig seine TTF-Datei geöffnet hat, dann lösche es, dann benutze es; dann würde der Inhalt dieser Datei durch meine Benchmark-Daten beschädigt werden. Dieses andere Skript müsste dann seine Datei zwischen dem open() und dem fstat() des obigen Codes löschen.

Also mit anderen Worten:

This script   Dr.Evil  My other script or program 
            open(fn2, O_EXCL | O_CREAT | O_RDWR) 
        link(fn1,fn2) 
open(fn1, ...) 
            unlink(fn2) 
fstat(..)=>link is 1 
write(...) 
close(...) 
            write(...) 
            seek(0, ...) 
            read(...) => (maybe) WRONG DATA! 

Und deshalb die oben genannte Lösung funktioniert nicht. Es gibt möglicherweise andere Angriffe.

Was ist der richtige Weg? Außerdem kein weltweit schreibbares Verzeichnis.

bearbeiten: Um gegen das Ergebnis zu schützen, dass die bösen Benutzer die Datei mit seinem/ihrem Besitz und Berechtigungen, oder einfach nur falsch Berechtigungen (durch harte erstellt Ihrer Datei verknüpfen und dann das Original zu entfernen, oder Hardlinks eines kurzlebige Datei von dir) Ich kann die Besitz- und Berechtigungsbits nach dem nlink check überprüfen.

Es würde kein Sicherheitsproblem geben, aber auch Überraschungen verhindern. Im schlimmsten Fall bekomme ich einige meiner eigenen Daten (aus einer anderen Datei) am Anfang der Datei, die aus einer anderen Datei kopiert wurden.

Edit 2: Ich denke, dass es fast unmöglich ist, den Namen einer Datei zu schützen, gegen jemanden hart Vernetzung, das heißt geöffnet, gelöscht und dann verwendet. Beispiele hierfür sind EXE-Packer, die manchmal sogar die gelöschte Datei über/proc/pid/fd-num ausführen. Wenn Sie damit fortfahren, würde die Ausführung des gepackten Programms fehlschlagen. lsof könnte wahrscheinlich herausfinden, ob jemand anders den Inode geöffnet hat, aber es scheint mehr Ärger zu geben, als es wert ist.

+0

Es ist nur ein Angriff, bevor die Datei erstellt wird. Wenn ich ein Standardbenutzer bin, kann ich einen Link zu jeder Datei erstellen (auch wenn ich nicht in diese Datei schreiben kann) in jedes Verzeichnis, in das ich schreiben kann. Das heißt, ich kann eine Datei mit dem Namen '/ tmp/foo' erstellen fester Link von '/ etc/passwd'. Wenn nun sein Programm nach '/ tmp/foo 'schreibt, schreibt es wirklich nach'/etc/passwd'. Er möchte dies vermeiden, indem er sicherstellt, dass er der erste Link zu dem von ihm geschaffenen Inode ist. – Gabe

+0

@gabe: richtig. Deshalb würde ich st_nlink überprüfen. Sie können eine neue Verknüpfung zu Dateien anderer Personen erstellen, diese jedoch nicht entfernen (die Linkanzahl verringern). – Thomas

+0

Guter Punkt, Thomas. Wenn mein Kommentar komisch aussieht, habe ich auf einen anderen Kommentar geantwortet, der seitdem gelöscht wurde. – Gabe

Antwort

2

Was auch immer Sie tun, Sie erhalten in der Regel eine Race Condition, in der jemand anders eine Verbindung erstellt und sie dann löscht, wenn Ihr fstat() - Systemaufruf ausgeführt wird.

Sie haben nicht genau gesagt, was Sie verhindern möchten. Es gibt sicherlich Kernel-Patches, die verhindern, dass (harte oder symbolische) Links zu Dateien, die Sie nicht besitzen, in weltweit schreibbaren Verzeichnissen (oder Sticky-Verzeichnissen) erstellt werden.

Es in das nicht weltweit beschreibbare Verzeichnis zu bringen scheint das Richtige zu sein.

SELinux, das scheint, das Standardsicherheits-Linux zu sein, kann in der Lage sein, Richtlinie zu konfigurieren, Benutzern zu verbieten, schlechte Sachen zu tun, die Ihre APP brechen.

Im Allgemeinen, wenn Sie als root laufen, erstellen Sie keine Dateien in/tmp. Eine andere Möglichkeit besteht darin, setfsuid() zu verwenden, um Ihre Dateisystem-Benutzer-ID auf jemand anderen zu setzen. Wenn die Datei von diesem Benutzer nicht beschreibbar ist, schlägt die Operation einfach fehl.

+0

Ich dachte daran, aber wenn sie einen Link zu einer Datei erstellen, die sie nicht besitzen, können sie diesen Link nicht löschen. In einem o + t-Verzeichnis, das/tmp ist, können Sie nur Dateien (Links) löschen, deren Eigentümer Sie sind. Daher können sie st_nlink nicht wieder auf 1 reduzieren. – Thomas

+0

Ja, aber sie können es möglicherweise aus dem anderen Verzeichnis löschen, in dem sie sich befindet, wenn sie Schreibzugriff haben. – MarkR

+0

Aber was gewinnen sie dann? Ist das nicht dasselbe, als wenn sie die Datei in/tmp als erste Stelle erstellen, an die sie angehängt werden? – Thomas

1

Kurz von dem, was Sie gerade dargestellt ist, die einzige andere, was ich versucht habe, endete fast ebenso racey und teurer, Gründung inotify Uhren auf/tmp vor, um die Datei zu erstellen, die für den Fang den Fall eines erlaubt Hardlink in einigen Fällen.

Allerdings ist es immer noch sehr rassig und ineffizient, da Sie auch eine breite erste Suche nach/tmp durchführen müssen, zumindest bis zu dem Level, auf dem Sie die Datei erstellen möchten.

Dort (nach meinem Wissen) ist keine "sichere" Möglichkeit, diese Art von Rennen zu vermeiden, außer nicht mit Word beschreibbare Verzeichnisse. Was sind die Konsequenzen, wenn jemand Ihren E/A über eine feste Verbindung abfängt? Würden Sie etwas Nützliches erhalten oder Ihre Anwendung nur undefiniertes Verhalten aufweisen?

+0

Die Daten selbst sind nicht geheim. Es ist nur ein Benchmarking von Daten. "Funktion X hat 2 Sekunden gebraucht". – Thomas

Verwandte Themen