Linux
為什麼我不能硬連結到我不擁有的文件,即使我可以移動它?
範例腳本:
#!/bin/sh -e sudo useradd -m user_a sudo useradd -m user_b -g user_a sudo chmod g+w /home/user_a set +e sudo su user_a <<EOF cd umask 027 >> file_a >> file_b >> file_c ls -l file_* EOF sudo su user_b <<EOF cd umask 000 rm -f file_* ls -l ~user_a/ set -x mv ~user_a/file_a . cp ~user_a/file_b . ln ~user_a/file_c . set +x ls -l ~/ EOF sudo userdel -r user_b sudo userdel -r user_a
輸出:
-rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_a -rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_b -rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_c total 0 -rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_a -rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_b -rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_c + mv /home/user_a/file_a . + cp /home/user_a/file_b . + ln /home/user_a/file_c . ln: failed to create hard link ‘./file_c’ => ‘/home/user_a/file_c’: Operation not permitted + set +x total 0 -rw-r----- 1 user_a user_a 0 Jul 11 12:26 file_a -rw-r----- 1 user_b user_a 0 Jul 11 12:26 file_b userdel: user_b mail spool (/var/mail/user_b) not found userdel: user_a mail spool (/var/mail/user_a) not found
你執行的是哪個系統?在 Linux 上,該行為是可配置的,通過
/proc/sys/fs/protected_hardlinks
(或sysctl fs.protected_hardlinks
)。該行為描述於
proc(5)
:
/proc/sys/fs/protected_hardlinks
(Linux 3.6 起)當該文件中的值為0 時,對硬連結的創建沒有任何限制(即這是Linux 3.6 之前的歷史行為)。當此文件中的值為 1 時,只有滿足以下條件之一,才能創建指向目標文件的硬連結:
- 呼叫程序具有 CAP_FOWNER 能力…
- 創建連結的程序的文件系統 UID 與目標文件的所有者 (UID) 匹配…
- 以下所有條件均成立:
+ 目標是一個正常文件; + 目標文件未啟用其 set-user-ID 模式位; + 目標文件沒有同時啟用其 set-group-ID 和 group-executable mode 位;和 + 呼叫者有權讀取和寫入目標文件(通過文件的權限遮罩或因為它具有合適的功能)。
這樣做的理由應該很清楚:
此文件中的預設值為 0。將值設置為 1 可防止由基於硬連結的檢查時間、使用時間競爭引起的長期存在的安全問題,最常見於全域可寫目錄,例如作為 /tmp。
在 Debian 系統
protected_hardlinks
和類似的protected_symlinks
預設系統上,因此在沒有文件寫入權限的情況下創建連結是行不通的:$ ls -ld . ./foo drwxrwxr-x 2 root itvirta 4096 Jul 11 16:43 ./ -rw-r--r-- 1 root root 4 Jul 11 16:43 ./foo $ mv foo bar $ ln bar bar2 ln: failed to create hard link 'bar2' => 'bar': Operation not permitted
設置
protected_hardlinks
為零會解除限制:# echo 0 > /proc/sys/fs/protected_hardlinks $ ln bar bar2 $ ls -l bar bar2 -rw-r--r-- 2 root root 4 Jul 11 16:43 bar -rw-r--r-- 2 root root 4 Jul 11 16:43 bar2