Layer 8Ehrlicher Tech-Support
BetriebssystemSchweregrad: Lästig

Linux: Datei in /tmp trotz Schreibrecht nicht löschbar

In /tmp darf jeder schreiben, aber rm scheitert an der Datei eines Kollegen. Schuld ist das t am Ende von drwxrwxrwt, das Sticky-Bit.

Aufwand:
ca. 10 Min.
Voraussetzung:
Ein Terminal, ls, stat und chmod aus GNU coreutils, sudo, nur wenn eine fremde Datei wirklich weg muss
Gilt für:
Linux mit GNU coreutils (chmod(1) aus coreutils 9.11; inode(7) und unlink(2) aus Linux man-pages 6.19)

Das Symptom

In /tmp liegt eine große, offensichtlich verwaiste Datei eines Kollegen und belegt Platz. Ein Blick auf das Verzeichnis beruhigt: Die Rechtemaske lautet drwxrwxrwt, alle dürfen lesen, schreiben, betreten. Also weg damit. rm verweigert trotzdem, mit Operation not permitted oder mit Permission denied. Mit sudo klappt es sofort, was den Verdacht nährt, mit den Rechten auf dem System sei etwas kaputt.

Die Kehrseite derselben Verwechslung trifft Admins: Für ein Team wird ein gemeinsames Ablageverzeichnis angelegt, großzügig mit chmod 777, damit niemand an Rechten scheitert. Ein paar Wochen später sind Dateien verschwunden oder umbenannt, und niemand will es gewesen sein. Technisch durfte es jeder.

Die „Layer 8“-Wahrheit

Im letzten Zeichen von drwxrwxrwt steckt mehr als ein Ausführrecht: Das t zeigt ein eigenes Bit an. chmod(1) nennt es das restricted deletion flag oder Sticky-Bit und beschreibt seine Wirkung auf Verzeichnisse genau: „For directories, it prevents unprivileged users from removing or renaming a file in the directory unless they own the file or the directory“. Der Satz endet mit dem Hinweis, dass man es üblicherweise auf weltweit beschreibbaren Verzeichnissen wie /tmp findet. Genau dafür ist es da.

Der Denkfehler liegt in der Annahme, Schreibrecht auf ein Verzeichnis sei Schreibrecht auf alles darin. Ohne Sticky-Bit stimmt das für das Löschen sogar: Wer ein Verzeichnis beschreiben und betreten darf, darf darin Namen entfernen, auch fremde. Mit Sticky-Bit nicht mehr. inode(7) zählt abschließend auf, wer dann löschen oder umbenennen darf: „only by the owner of the file, by the owner of the directory, and by a privileged process“. Der Kollege darf, root darf, man selbst nicht. Die Fehlermeldung ist dabei nicht einmal eindeutig. unlink(2) führt für diesen Fall „EPERM or EACCES“ auf, und errno(3) nennt dazu die beiden Texte: Operation not permitted beziehungsweise Permission denied. Die zweite Meldung klingt nach fehlendem Schreibrecht, obwohl genau das vorhanden ist.

Für das Teamverzeichnis gilt dasselbe Prinzip von der anderen Seite. 777 gibt allen alles, einschließlich des Löschens fremder Dateien. Die erste von vier Ziffern der Oktalschreibweise ist laut chmod(1) für Set-User-ID, Set-Group-ID und eben dieses Bit zuständig; 1777 heißt also: alle dürfen schreiben, aber jeder räumt nur seine eigenen Dateien weg. Wer das will, setzt es mit chmod +t nachträglich, ohne die anderen Rechte anzufassen.

Das Bit schützt dabei nicht den Inhalt, sondern den Namen im Verzeichnis. Ob jemand eine fremde Datei beschreiben darf, entscheiden ihre eigenen Rechte, und je nach Einstellung zusätzlich die Linux-Sperre protected_regular, die in solchen Verzeichnissen greift. Ein drwxrwxrwt ist also kein Freibrief, sondern eine Hausordnung: Jeder darf rein, jeder darf etwas abstellen, aber weggeräumt wird nur das Eigene.

Die echte, verifizierte Lösung

1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:

  1. 1.

    Das t in der Rechtemaske lesen

    ls -ld zeigt die Rechte des Verzeichnisses selbst statt seines Inhalts. Steht dort drwxrwxrwt, zeigt das kleine t an letzter Stelle das Sticky-Bit an; chmod(1) verwendet für dieses Bit genau den Buchstaben t. Bei der Prüfung für diesen Eintrag erschien mit Ausführrecht für alle anderen ein kleines t (Modus 1777), ohne dieses Recht ein großes T (Modus 1776). Damit ist die naheliegende Erklärung für das gescheiterte rm gefunden, bevor irgendjemand an den Rechten herumschraubt. Dasselbe gilt für jedes andere Verzeichnis mit diesem Bit.

    ls -ld /tmp
    
  2. 2.

    Eigentümer der Datei prüfen

    stat mit eigenem Format zeigt Rechtemaske, Eigentümer und Namen in einer Zeile: %A steht für die Rechte in lesbarer Form, %U für den Namen des Eigentümers, %n für den Dateinamen. Gehört die Datei einem anderen Benutzer und das Verzeichnis ebenfalls nicht mir, ist das Löschen in einem Verzeichnis mit Sticky-Bit für mich gesperrt, egal wie offen das Verzeichnis sonst ist.

    stat -c '%A %U %n' /tmp/bericht.csv
    
  3. 3.

    Den richtigen Weg zum Löschen wählen

    Am saubersten löscht der Eigentümer seine Datei selbst, denn er weiß, ob noch ein Programm sie braucht. Muss es ohne ihn gehen, darf ein privilegierter Prozess sie entfernen, praktisch also root über sudo. Vorher lohnt die Frage, ob die Datei wirklich verwaist ist, denn root löscht auch die Arbeitsdatei eines Programms, das gerade noch läuft. Das Sticky-Bit sorgt nur dafür, dass diese Entscheidung nicht jeder Benutzer nebenbei trifft.

    sudo rm /tmp/bericht.csv
    
  4. 4.

    Gemeinsame Ablagen absichern

    Wer für ein Team ein gemeinsames, für alle beschreibbares Verzeichnis anlegt, setzt das Sticky-Bit selbst, sonst kann jeder die Dateien aller anderen löschen oder umbenennen. chmod +t setzt nur dieses Bit und lässt die übrigen Rechte in Ruhe; die Oktalschreibweise 1777 setzt alles auf einmal. Danach zeigt ls -ld das t am Ende, und jeder kann nur noch seine eigenen Dateien entfernen.

    chmod +t /srv/team-ablage
    ls -ld /srv/team-ablage
    
  5. 5.

    Bit entfernen, wenn gegenseitiges Löschen gewollt ist

    Soll in einem Verzeichnis tatsächlich jeder alles löschen dürfen, etwa in einer kleinen Arbeitsgruppe mit gemeinsamer Verantwortung, entfernt chmod -t das Bit wieder. Das ist ehrlicher, als die Rechte weiter aufzubohren oder Dateien reihum per sudo zu löschen. Für /tmp selbst gilt das ausdrücklich nicht: chmod(1) nennt das Bit gerade für weltweit beschreibbare Verzeichnisse wie /tmp als üblich.

    chmod -t /srv/team-ablage
    

Häufige Fragen (FAQ)

?Warum darf ich die Datei nicht löschen, obwohl /tmp für alle beschreibbar ist?

Weil auf /tmp zusätzlich das Sticky-Bit gesetzt ist, das t am Ende von drwxrwxrwt. Die Handbuchseite chmod(1) beschreibt es für Verzeichnisse so: „it prevents unprivileged users from removing or renaming a file in the directory unless they own the file or the directory“. Schreibrecht auf das Verzeichnis reicht dort also nicht, um fremde Dateien zu entfernen. Löschen dürfen nur der Eigentümer der Datei, der Eigentümer des Verzeichnisses und ein privilegierter Prozess.

?Warum klappt es mit sudo?

Weil root als privilegierter Prozess ausgenommen ist. inode(7) formuliert die Regel für ein Verzeichnis mit gesetztem S_ISVTX vollständig: „a file in that directory can be renamed or deleted only by the owner of the file, by the owner of the directory, and by a privileged process.“ unlink(2) wird bei Linux genauer und nennt als Voraussetzung die Fähigkeit CAP_FOWNER. Dass sudo funktioniert, beweist also nicht, dass mit den Rechten etwas kaputt ist, sondern dass die Regel genau so greift wie beschrieben.

?Was ist der Unterschied zwischen chmod 777 und chmod 1777?

Genau dieses Bit. In der vierstelligen Oktalschreibweise steht die erste Ziffer laut chmod(1) für Set-User-ID (4), Set-Group-ID (2) und das Sticky-Bit (1). 777 gibt allen Lese-, Schreib- und Ausführrecht und erlaubt damit in einem Verzeichnis auch, fremde Dateien zu löschen oder umzubenennen. 1777 gibt dieselben Rechte, setzt aber zusätzlich das Sticky-Bit, sodass jeder nur noch seine eigenen Dateien entfernen kann. Das ist die Kombination, die /tmp üblicherweise trägt.

?Darf ich die fremde Datei wenigstens überschreiben?

Das Sticky-Bit selbst regelt laut chmod(1) und inode(7) nur das Löschen und Umbenennen; über den Inhalt entscheiden die Rechte der Datei. Linux legt in solchen Verzeichnissen aber eine zweite Sperre darüber. Ist die Einstellung protected_regular aktiv, verweigert open(2) mit EACCES das Öffnen mit O_CREAT für eine vorhandene reguläre Datei, die weder dem Aufrufer noch dem Verzeichniseigentümer gehört, wenn das Verzeichnis sticky und für alle oder die Gruppe beschreibbar ist. Laut proc_sys_fs(5) bedeutet in /proc/sys/fs/protected_regular der Wert 0 keine Einschränkung, 1 die Sperre für weltweit beschreibbare Verzeichnisse mit Sticky-Bit und 2 zusätzlich für gruppenweit beschreibbare. Auf dem System, auf dem dieser Eintrag geprüft wurde, stand dort 1.

?Warum heißt das Ding eigentlich Sticky-Bit?

Der Name stammt aus der Zeit, als das Bit bei Programmdateien eine andere Aufgabe hatte. chmod(1) schreibt dazu: „For regular files on some older systems, the bit saves the program's text image on the swap device so it will load more quickly when run; this is called the sticky bit.“ Für Verzeichnisse heißt dasselbe Bit dort restricted deletion flag, also eingeschränktes Löschen. Was das Bit auf heutigen Linux-Systemen bei gewöhnlichen Dateien bewirkt, sagt die Handbuchseite nicht; sie beschreibt nur die älteren Systeme und die Bedeutung für Verzeichnisse.

Belege

Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.

Zuletzt geprüft am . Dokumentation altert – ein Datum daneben ist der einzige ehrliche Umgang damit.

Auch zu finden unter

Verwandte Fehler

OSLästigPermission denied

Permission denied, obwohl man root ist

Selbst als root verweigert das System den Zugriff. Meist ist das Dateisystem schreibgeschützt eingehängt oder die Datei ist unveränderlich.

OSLästigUNPROTECTED PRIVATE KEY FILE

SSH: Permissions for key are too open

SSH verweigert den Schlüssel, weil die Rechte zu offen seien? Ein privater Schlüssel darf nur dir gehören — mit einem chmod ist es in Sekunden behoben.

SWAnfängerfehlerPermission denied

bash: ./script.sh: Permission denied

Shell-Skript startet nicht mit 'Permission denied'? Meist fehlt nur das Ausführbar-Recht. So machst du es lauffähig – und findest seltenere Ursachen.