%3F.png)
Ich bin auf bizarres Verhalten gestoßen, wenn ichchown(2)innerhalb einer Fakeroot-Umgebung. Das folgende Minimalprogramm veranschaulicht das Problem:
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
int main() {
//choose a reasonably unique filename
char path[30];
sprintf(path, "./file-%d", getpid());
//create file
close(creat(path, 0644));
//chown to some random UID/GID
chown(path, 4444, 4444);
//stat again (result can be seen in strace below)
struct stat s;
stat(path, &s);
return 0;
}
Angenommen, das ist main.c
. Jetzt führe ich Folgendes innerhalb eines aus fakeroot bash
:
$ gcc -o main main.c
$ strace -v ./main
...
creat("./file-10872", 0644) = 3
close(3) = 0
...
lchown("./file-10872", 84, 84) = -1 EPERM (Operation not permitted)
stat("./file-10872", {st_dev=makedev(8, 3), st_ino=3932971, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1001, st_gid=100, st_blksize=4096, st_blocks=0, st_size=0, st_atime=2015/10/31-20:12:07, st_mtime=2015/10/31-20:12:07, st_ctime=2015/10/31-20:12:07}) = 0
...
$ ls -l file-10872
-rw-r--r-- 1 4444 4444 0 31. Okt 20:12 file-10872
Was können wir hier sehen?
- Der
chown
Aufruf ist mit EPERM (Operation Not Permitted) fehlgeschlagen. - Nachfolgend
stat
wird angezeigtst_uid=1001, st_gid=100
, welche meine echte (nicht gefälschte) UID und GID ist (was komisch ist, denn wenn ich Fakeroot richtig verstehe, sollte zumindest angezeigt werdenst_uid=0, st_gid=0
). - Das Nachfolgende
ls -l
in derselben Datei zeigt, dass derchown
Vorgang ERFOLGREICH war, obwohlchown
ein Fehler gemeldet wurde, und das Nachfolgendestat
hat dies bestätigt.
Was zum Teufel ist hier los? Habe ich einen Fehler in Fakeroot gefunden oder ist das nur ein Missverständnis darüber, wie Fakeroot funktioniert?
(Meine fakeroot
Version ist 1.20.2 und mein System ist Arch Linux mit allen Updates.)
Aktualisieren:Jonas Wielicki hat richtig darauf hingewiesen, dass strace auf Systemaufrufebene arbeitet und daher irreführend ist, da die Ergebnisse der Systemaufrufe von libfakeroot verstümmelt werden, bevor sie an das Programm selbst zurückgegeben werden. Es stellt sich heraus, dass nach stat(path, &s)
die struct stat s
neue UID und GID enthalten ist. Aber es ist immer noch verwirrend, dass chown
mit EPERM fehlschlägt.
Antwort1
chown
gibt tatsächlich Null zurück, wenn es unter ausgeführt wird fakeroot
. Somit gilt gemäß errno(3)
:
Sein Wert ist nur dann von Bedeutung, wenn der Rückgabewert des Aufrufs einen Fehler anzeigt (d. h. -1 bei den meisten Systemaufrufen; -1 oder NULL bei den meisten Bibliotheksfunktionen). Eine erfolgreiche Funktion darf errno ändern.
Der Wert in errno
ist nicht signifikant und chown
ist tatsächlich nicht fehlgeschlagen.
Wie bereits in den Kommentaren erläutert, strace
enthält die Ausgabe wie erwartet EPERM und nicht gefälschte UIDs/GIDs als strace
Spuren unterhalb der Fakeroot- LD_PRELOAD
Bibliothek. Das Drucken der UID/GID aus dem Programm zeigt die korrekte (gefälschte) Ausgabe.