Privileges

是否適合在 setresuid()/setreuid()/seteuid() 上使用 setuid()?

  • May 21, 2022

我有一個從 C 源文件編譯的可執行二進製文件

執行檔具有 setuid 權限

我注意到,如果執行檔的所有者是root,我可以使用

setuid(geteuid());

在編譯文件以將執行執行檔的程序的真實 UID設置為root時。然後,執行執行檔的任何人都可以以root身份執行它。

但是,我注意到只有當執行檔的所有者是root時才會發生這種情況。當我嘗試授予test_user執行檔的所有權(並修復權限以再次包含 setuid)時,它不起作用。在閱讀了這些文件頁面(123)並閱讀了這篇文章後,我注意到這setuid(new_euid)是為了更改有效 UID而不是執行執行檔的程序的真實 UID。只是碰巧,在特定情況下(有效的 UID是 root),setuid(new_euid)還設置了真實的 UID保存的 UID執行執行檔的程序到new_euid.

我通過使用setreuid代替解決了這個問題setuid,如下:

setreuid(geteuid(), geteuid());

這允許我將程序的真實 UID設置為**有效 UID(執行檔的所有者)並將有效 UID重置為其值(冗餘)。

我知道這在某些條件下會起作用,但同樣適用於使用,或更改真實 UID保存的 UID有效的 UIDsetuid()時更容易混淆,因為它們總是有效?setreuid()``setresuid()``seteuid()

此外:我知道這seteuid()似乎與此處setuid()解釋的差異相同(有效的 UID是 root)。這應該不允許 root 特權程序在刪除它們後重新獲得特權(因為所有 3 個 UID 都將使用 更改為相同的值)?那麼我是否應該只使用root 特權程序,即使它與例如相比不那麼清楚?setuid()``setuid()``setresuid()

我認為這setuid()可能是安全的,因為它不允許 root 特權程序在刪除後重新獲得特權,但是可以使用其他提到的功能來實現這種行為,而不會造成太大的混亂。

另一件事getuid()返回程序的真實 UID,同時setuid()用於修改有效 UID(除非特權),這也令人困惑。

這一切背後可能有一些駭人聽聞的歷史。正如您所說,setreuid()更清晰,並且由於它在標準中指定,我會使用它。然後虔誠地檢查返回值,然後進行getuid()驗證geteuid()

setresuid()不在 POSIX 中,所以它可能沒有那麼廣泛可用(不過,FreeBSD 和 OpenBSD 似乎有它)。如果實現setreuid()匹配文件,您不需要顯式設置保存的 UID,因為setreuid()應該為您設置它:

如果設置的是真實使用者ID(ruid不是-1),或者設置的有效使用者ID不等於真實使用者ID,則設置目前程序保存的set-user-ID等於新的有效使用者 ID。

再說一次,如果可能的話,完全避免使用 setuid 程序來支持例如單獨執行的特權程序並通過套接字與其通信可能是一個好主意。有很多東西從一個程序繼承給它的子程序,並且使用 setuid,特權較低的人可以將它們設置為特權較高的人。

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