Permissions
Linux open() 系統呼叫和文件夾權限
我有一個程序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,這怎麼可能呢?
這些是root和U的組成員身份:
$groups root root : root $groups U U : U G
所以U有G作為次要組
$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)
這表明只有U是G的成員
就像評論中提到的@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)
當然,這不會添加任何其他目標使用者的組。