Linux

為什麼我不能硬連結到我不擁有的文件,即使我可以移動它?

  • July 14, 2017

範例腳本:

#!/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

引用自:https://unix.stackexchange.com/questions/377676