Hallo,
ich bin auf ein seltsames Problem im Zusammenhang mit openat() gestoßen, das merkwürdigerweise nur bei den 32bit-Treibern auftritt, aber nicht bei den 64bit-Treibern. Das Problem wurde in
https://forums.gentoo.org/viewtopic-t-991874.html beschrieben, aber ich fasse hier noch einmal zusammen.
Problembeschreibung: Mit tar-1.27.1 (bei tar-1.26 scheint eine andere Implementierung das Problem zu vermeiden, andere Versionen habe ich nicht getestet) entpacke man zweimal ein Archiv (mit relativen Pfaden) in das selbe Directory. Beim zweitenmal versucht tar, die Dateien nach "/" statt in das aktuelle Directory zu entpacken. Wenn man /etc/ld.so.preload entfernt, verschwindet das Problem, so dass die sundtek-Treiber zumindest implizit mitverantwortlich sind. Das Problem tritt nur bei 32bit, nicht aber bei 64bit auf. Bei 32bit tritt das Problem sowohl mit glibc-2.17 als auch mit glibc-2.19 auf.
Analyse: Obwohl tar-1.27.1 zwar eine Fallback-Implementation von openat() mitbringt, wird diese (zumindest auf meinem System) anscheinend nicht benutzt, sondern direkt die glibc-Funktion openat() aufgerufen. "strace" zeigt, dass openat() vom Sundtek-Treiber anscheinend (direkt oder indirekt) überladen wird, und dass sich der openat()-Bibliotheksaufruf von tar dadurch effektiv in folgende Aufrufe (auf dem 32Bit-System) übersetzt:
openat(AT_FDCWD, "somedir/somefile", O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0644) = -1 EEXIST (File exists)
readlink("/proc/self/fd/-100", 0xfbcf5293, 100) = -1 ENOENT (No such file or directory)
open("/somedir/somefile", O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0644) = -1 ENOENT (No such file or directory)
Auf dem 64bit-System ohne das Problem sieht die Übersetzung anders auf:
openat(AT_FDCWD, "somedir/somefile", O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0644) = -1 EEXIST (File exists)
unlinkat(AT_FDCWD, "somedir/somefile", 0) = 0
openat(AT_FDCWD, "somedir/somefile", O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0644) = 4
Anders als bei 32bit wird bei 64bit also weder der merkwürdige "readlink()"-Aufruf ausgeführt, noch wird ein open() mit vorgestelltem "/" aufgerufen.
Edit: Möglicherweise tritt das Problem erst mit neueren Versionen des Sundtek-Treibers auf; ich kann aber nicht mehr nachvollziehen, seit wann, und habe ältere Versionen jetzt auch nicht systematisch getestet.