Gibt es eine Datei, die immer existiert und die von einem "normalen" Benutzer nicht angegeben werden kann?

14

Ich brauche das für einen Unit-Test. Es gibt eine Funktion, die lstat auf dem Dateipfad ausführt, der als Parameter übergeben wird. Ich muss den Codepfad auslösen, in dem das lstatfehlschlägt (weil die Codeabdeckung 90% erreichen muss)

Der Test kann nur unter einem einzelnen Benutzer ausgeführt werden. Daher habe ich mich gefragt, ob es in Ubuntu eine Datei gibt, die immer existiert, aber normale Benutzer haben keinen Lesezugriff darauf oder auf den Ordner. (Also lstatwürde es fehlschlagen, wenn es nicht als root ausgeführt wird.)

Eine nicht existierende Datei ist keine Lösung, da es dafür einen eigenen Codepfad gibt, den ich bereits auslöse.

BEARBEITEN: Der fehlende Lesezugriff auf die Datei allein reicht nicht aus. Damit lstatkann noch ausgeführt werden. Ich konnte es auslösen (auf meinem lokalen Computer, auf dem ich Root-Zugriff habe), indem ich einen Ordner in / root und eine Datei darin erstellte. Und Festlegen der Berechtigung 700 für den Ordner. Ich suche also nach einer Datei in einem Ordner, auf den nur root zugreifen kann.

Hockendes Kätzchen
quelle
6
IMHO/etc/shadow
Romeo Ninov
3
Sie können nicht davon ausgehen, dass eine Datei vorhanden ist, da Ihr Programm möglicherweise in einer Chroot-Umgebung oder einem separaten Namespace ausgeführt wird. Wenn die Annahme, dass / proc eingehängt ist, in Ordnung ist und init nichts Besonderes ist, /proc/1/fd/0sollte dies getan werden.
Mosvy
1
@mosvy Danke, das funktioniert auf meinem lokalen Rechner. Hmm, dann probiere ich es auch im QA- und Staging-Pool aus.
Crouching Kitten
2
Warum binden Sie Ihren Test - Code für einen bestimmten Geschmack von OS , wenn Sie könnten nur erstellen eine Wegwerf - Datei und die eigenen Lesezugriff auf mich entfernen?
Kilian Foth
4
Ich würde argumentieren, dass es nicht wirklich ein Komponententest ist , sobald es anfängt, abhängig von einem realen, anstatt von einem verspotteten Dateisystem.
Toby Speight

Antworten:

21

Auf modernen Linux-Systemen sollten Sie in der Lage sein /proc/1/fdinfo/0(Informationen für den Dateideskriptor 1 (stdout) des Prozesses von ID 1 ( initim Root-PID-Namespace, der als ausgeführt werden soll)root )).

Sie finden eine Liste mit (als normaler Benutzer):

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'

(Entfernen -type fSie diese Option, wenn Sie nicht auf normale Dateien beschränken möchten.)

/var/cache/ldconfig/aux-cacheist ein weiterer potenzieller Kandidat, wenn Sie nur Ubuntu-Systeme in Betracht ziehen müssen. Es sollte auf den meisten GNU-Systemen funktionieren, da /var/cache/ldconfiges mit dem ldconfigBefehl read + write + searchable to root erstellt wurde, der mit der GNU libc geliefert wird.

Stéphane Chazelas
quelle
1
Vielen Dank! Wenn es /proc/1/fdinfo/0auf Ubuntu 16.04 und 18.04 läuft, ist das mehr als genug.
Crouching Kitten
1
Das Verwenden von /proc/1/fdinfo/0funktioniert nicht unbedingt in einem Container (z. B. einem Docker-Container), und in CI werden häufig Komponententests in solchen Containern ausgeführt.
Philipp Wendler
@PhilippWendler, ich habe den Root-PID-Namespace bereits erwähnt. Das OP fragt nicht nach Containern, sondern nach Dateien, die im Dateisystem-Layout eines Ubuntu-Systems garantiert vorhanden sind. Da Container ein beliebiges Datei- und Verzeichnislayout enthalten können, kann diese Frage dort nicht beantwortet werden.
Stéphane Chazelas
12

In der Manpage von lstat (2) finden Sie Anregungen zu Fällen, in denen es zu Fehlern kommen kann, die nicht ENOENT entsprechen (Datei existiert nicht).

Das offensichtlichste ist:

Die EACCES-Suchberechtigung wird für eines der Verzeichnisse im Pfadpräfix von path verweigert .

Sie benötigen also ein Verzeichnis, in dem Sie nicht suchen können.

Ja, Sie können nach einem suchen, der bereits in Ihrem System vorhanden ist (möglicherweise, /var/lib/privatewenn es vorhanden ist?). Sie können jedoch auch selbst einen erstellen, mit dem Äquivalent von:

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile

Die lstat (2) -Operation schlägt hier mit EACCES fehl. (Das Entfernen aller Berechtigungen aus dem Verzeichnis stellt dies sicher. Möglicherweise benötigen Sie nicht einmal so viel und das chmod -xEntfernen der Ausführungsberechtigungen würde ausreichen, da Ausführungsberechtigungen für ein Verzeichnis erforderlich sind, um auf Dateien darunter zuzugreifen.)

Es gibt eine andere kreative Möglichkeit, lstat (2) zum Scheitern zu bringen, indem Sie die Manpage lesen:

ENOTDIR Eine Komponente des Pfadpräfixes von path ist kein Verzeichnis.

Der Versuch, auf eine Datei wie /etc/passwd/nonexistentdiese zuzugreifen, sollte diesen Fehler auslösen, der sich wiederum von ENOENT ("Keine solche Datei oder Verzeichnis") unterscheidet und möglicherweise Ihren Anforderungen entspricht.

Ein anderer ist:

Der ENAMETOOLONG- Pfad ist zu lang.

Möglicherweise benötigen Sie einen wirklich langen Namen für diesen Namen. (Ich glaube, 4.096 Byte sind das typische Limit, aber Ihr System / Dateisystem hat möglicherweise einen längeren.)

Letztendlich ist es schwer zu sagen, ob eines davon tatsächlich für Sie nützlich sein wird. Sie möchten etwas, das das Szenario "Datei existiert nicht" nicht auslöst. Während dies normalerweise einen ENOENT-Fehler bedeutet, interpretieren in der Praxis viele Überprüfungen höherer Ebenen Fehler aus lstat (2) einfach als "nicht vorhanden". Zum Beispiel test -eoder das Äquivalent [ -e ...]aus der Shell könnte einfach alles oben Genannte als "nicht vorhanden" interpretieren, zumal es keine gute Möglichkeit gibt, eine andere Fehlermeldung zurückzugeben, und wenn kein Fehler zurückgegeben wird, bedeutet dies, dass die Datei vorhanden ist. Das ist mit Sicherheit nicht der Fall.

filbranden
quelle
@StephaneChazelas Großartiger Punkt! Aktualisiert.
Filbranden
6

Du kannst findes selbst.

Verwenden Sie /etc- das Verzeichnis der Konfigurationsdateien als Ausgangspunkt:

sudo find /etc -type f -perm 0400 -user root

Auf meinem System gibt dies nichts zurück.

Sie können eine weniger restriktive und zulässige Gruppe sein root(nur Benutzer rootsollten Mitglied der Gruppe sein root) und auf die Erlaubnis von achten 440:

sudo find /etc -perm 0440 -user root -group root

Auf meinem System gibt dies Folgendes zurück:

/etc/sudoers.d/README
/etc/sudoers

Bearbeiten:

Basierend auf Ihrer Bearbeitung suchen Sie nach einem Verzeichnis, das für den aufrufenden Benutzer nicht über die erforderlichen Berechtigungen verfügt, um die Auflistung von Verzeichnissen zu verhindern:

sudo find / -perm o-rwx -type d -user root -group root 

Hier suche ich nach Verzeichnissen ( -type d), denen die Perm-Bits zum Lesen, Schreiben und Ausführen für andere ( o-rwx) fehlen und die Eigentum von sind root:root.

Technisch gesehen würde nur das Fehlen des execute ( x) -Bits eine Verzeichnisauflistung ( lstat(2)) im Verzeichnis verhindern.

In der Ausgabe habe ich /run/systemd/inaccessible/auf meinem Systemd Init-basierten System gefunden.

In Bezug auf Dateien in /proc, /sys, /dev:

  • Diese Dateisysteme sind virtuelle Dateisysteme, dh sie befinden sich im Arbeitsspeicher und nicht auf der Festplatte

  • Wenn Sie sich darauf verlassen möchten /proc, verwenden Sie, /proc/1/dh verlassen Sie sich auf etwas unter PID 1, und verwenden Sie keine späteren PIDs, um Zuverlässigkeit / Konsistenz zu gewährleisten, da die späteren PIDs (Prozesse) nicht garantiert existieren.

heemayl
quelle
Danke, ich denke meine Frage ist falsch. Ich kann immer noch lstat-Dateien ohne Lesezugriff auf sie. Möglicherweise muss der Zugriff auf den Ordner eingeschränkt werden? (Ich habe den Titel geändert)
Crouching Kitten
Vielen Dank. Mit find / -type d -perm 0400 -user rootmir das Verzeichnis gefunden habe /proc/20/map_files/, wenn ich in diesem Ordner zu einem konfektionierten Dateinamen beziehen, wie /proc/20/map_files/asdasd, dann scheitert es immer. Existiert dieser Ordner immer auf Ubuntu?
Crouching Kitten
@CrouchingKitten, die Verzeichnisse in /proc/1/könnten sicherer sein, da init immer existiert. Aber das procist kein reguläres Dateisystem, falls es darauf ankommt.
Ilkkachu
Danke, ich habe eine positive Bewertung abgegeben, aber die andere Antwort akzeptiert, weil er sagte, es sei garantiert, dass es /proc/1/fdinfo/0auf dem modernen Ubuntus funktioniert.
Crouching Kitten
-perm o-rwxist wie -perm 0, Bits sind alle aus, um mit zu beginnen. Hier würdest du wollen ! -perm -1.
Stéphane Chazelas