Permissions

Linux open() 系統呼叫和文件夾權限

  • November 17, 2017

我有一個程序P,它由 root 擁有的程序生成。創建P後,呼叫 setguid() 和 setuid() 並以使用者U身份執行。

程序P嘗試在文件夾F (在根文件系統中)上創建文件****f ,該文件夾由 root 擁有並具有以下權限:

drwxrwx---    2 root     root

函式呼叫如下所示:

open(path , O_CREAT | O_RDWR , 0660);

如果我執行命令ps -e -o cmd,uid,euid,ruid,suid,gid,egid,rgid,sgid ,結果如下:

/my/process    500   500   500   500   500   500   500   500

這證實了程序P沒有以 root 身份執行,但是即使程序以使用者U身份執行也足夠奇怪,文件f是在文件夾F下創建的,該文件夾應該只能由 root 及其組成員寫入:

-rw-rw---- 1 U U

所以該文件歸U所有。

如果我嘗試從 bash 中做同樣的事情,我會得到預期的“Permission Denied”:

$ touch /F/f
touch: cannot touch `/F/f': Permission denied

如果我將文件夾F權限設置為:

drwx------    2 root     root

然後 open() 呼叫失敗,如預期的“Permission Denied”。

為什麼P在授予 root 組寫入權限後可以在該文件夾中創建文件?

ps命令顯示所有 uid 和 gid 都設置為相關的使用者 id,這怎麼可能呢?

這些是rootU的組成員身份:

$groups root
root : root

$groups U
U : U G

所以UG作為次要組

$lid -g root
root(uid=0)
sync(uid=5)
shutdown(uid=6)
halt(uid=7)
operator(uid=11)

$lid -g U
U(uid=500)

$lid -g G
U(uid=500)

這表明只有UG的成員

就像評論中提到的@jdwolf 一樣,問題可能是補充組。setgid()不會刪除它們。

一個簡單的測試,./drop這裡是一個程序,它呼叫setregid()setreuid()將 GID 和 UID 更改為nobody,然後執行id

# id
uid=0(root) gid=0(root) groups=0(root)
# ./drop
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup),0(root)

仍然是零組。添加setgroups(0, NULL)(在 之前setuid())刪除該組:

# ./drop2
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)

當然,這不會添加任何其他目標使用者的組。

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