
Ich versuche zu verstehen, warum sudo hier keine Berechtigung hat
touch fred.txt
/tmp$ ls -la fred.txt
-rw-rw-r-- 1 me me 0 Dec 12 15:40 fred.txt
/tmp$ sudo -i
~# cd /tmp
/tmp# echo hi >> fred.txt
-bash: fred.txt: Permission denied
/tmp# chmod 666 fred.txt
/tmp# ls -la fred.txt
-rw-rw-rw- 1 me me 0 Dec 12 15:40 fred.txt
/tmp# echo hi >> fred.txt
-bash: fred.txt: Permission denied
id
uid=0(root) gid=0(root) groups=0(root)
So wie ich es verstehe, sollte die Berechtigung 666 dem Besitzer, der Gruppe und anderen die Berechtigung zum Lesen und Schreiben der Datei erteilen. Sicherlich hat sudo, das als Root agiert, wie der ID-Befehl zeigt, mit der Berechtigung „andere“ Zugriff auf die Datei.
Was verstehe ich hier falsch?
Antwort1
Es hat etwas zu tun mitdieses Commitim Linux-Kernel. /tmp
Ist oft „weltweit beschreibbar“ (wobei hier „Welt“ „andere“ bedeutet) und „sticky“:
$ stat /tmp/
...
Access: (1777/drwxrwxrwt) Uid: ( 0/ root) Gid: ( 0/ root)
...
chmod(2)
:
...
S_ISVTX (01000) sticky bit (restricted deletion flag, as described in unlink(2))
...
S_IWOTH (00002) write by others
...
Wie in der Commit-Nachricht erwähnt, verhindert es nicht direkt, dass Sie in eine betroffene Datei schreiben, sondern nur, dass Sie eine solche Datei mit öffnen O_CREAT
, was ein Flag füropen()
Das wird normalerweise so gesetzt, dass die Dateierstellung ausgelöst wird, wenn das Ziel noch nicht existiert. Daher können Sie auch mit nicht gesetztem Flag in eine betroffene Datei schreiben (was mit möglich ist dd
):
# ls -l /tmp/meh
-rwxrwxrwx 1 tom tom 0 Dec 12 17:33 /tmp/meh
# id
uid=0(root) gid=0(root) groups=0(root)
# echo test | dd of=/tmp/meh oflag=append conv=notrunc
dd: failed to open '/tmp/meh': Permission denied
# echo test | dd of=/tmp/meh oflag=append conv=notrunc,nocreat
0+1 records in
0+1 records out
5 bytes copied, 9.4981e-05 s, 52.6 kB/s
#
Beachten Sie, dass es hier lediglich darum geht, ob das Flag gesetzt ist, nicht jedoch darum, ob eine Datei erstellt werden muss, da die Datei im betreffenden Fall immer vorhanden ist.
O_CREAT
Beachten Sie auch, dass die Datei, wie in der Commit-Nachricht erwähnt, nicht mit nicht geöffnet werden konnteNurweil es nicht dem Benutzer gehörte, der versucht hat, es zu öffnen ( root
), sondern auch, weil sein Besitzer ( ) nicht mit dem Besitzer ( ) des Verzeichnisses ( ) tom
identisch ist . Wenn es so gehört hätte wie es war, wäreroot
/tmp
/tmp/
tom
/tmp/meh
root
fähigum es mit zu öffnen O_CREAT
.
Siehe auchdieses Commitin systemd, das den „Schutz“ auf Distributionen aktiviert, die es übernommen haben:
# sysctl fs.protected_regular
fs.protected_regular = 1
Beachten Sie, dass die zugehörigen Sysctlskann auch gesetzt werden 2
(oder 0
).