sudo не может записать во временный файл

sudo не может записать во временный файл

Я пытаюсь понять, почему у sudo нет здесь разрешения.

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)

Насколько я понимаю, разрешение 666 должно давать владельцу, группе и другим разрешение на чтение/запись файла. Surly sudo, который действует как root, как видно из команды id, имеет доступ к файлу под разрешением «другие».

Что я здесь не понимаю?

решение1

Это как-то связано сэто совершитьв ядре Linux. Часто /tmpявляется «доступным для записи всем» («world» здесь означает «другие») и «прилипающим»:

$ 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
...

Как упоминалось в сообщении о коммите, это не запрещает вам записывать данные в затронутый файл, но запрещает открывать такой файл с помощью O_CREAT, что является флагом дляopen()который обычно устанавливается для запуска создания файла, если цель еще не существует. Таким образом, вы все равно можете записать в затронутый файл с неустановленным флагом (что можно сделать с помощью 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
# 

Обратите внимание, что речь идет исключительно о том, установлен ли флаг, а не о том, нужно ли создавать файл, поскольку в рассматриваемом случае файл всегда существует.

Также обратите внимание, что, как указано в сообщении о коммите, файл не может быть открыт O_CREATбезтолькопотому что он не принадлежал пользователю, который пытался его открыть ( root), но также потому что его владелец ( tom) отличается от владельца ( root) каталога ( /tmp). Если бы /tmp/он принадлежал tomкак /tmp/mehбыл, rootбыл быспособныйчтобы открыть его с помощью O_CREAT.

Также смэто совершитьв systemd, который включает «защиту» на дистрибутивах, которые ее приняли:

# sysctl fs.protected_regular
fs.protected_regular = 1

Обратите внимание, что соответствующие sysctlsтакже может быть установлено 2(или 0).

Связанный контент