星期三, 11月 24, 2010

set-user-id (suid), set-group-id (sgid), saved-suid 筆記

set-user-id (suid), set-group-id (sgid), saved-suid 筆記

在 stat.st_mode 的 masks:
S_ISUID    0004000   set UID bit
S_ISGID    0002000   set-group-ID bit (see below)

當 process 在執行時,實際上的 user/group id 是如此表對映的:

User IDs and group IDs associated with each process

real user ID
real group ID
who we really are

effective user ID
effective group ID
supplementary group IDs
used for file access permission checks

saved set-user-ID
saved set-group-ID
saved by exec functions

一般來說,process 的權限是以 real user/group id 為主的,但是當 st_mode 中的
set-user-id 或 set-group-id 屬性開啟時,這意思是執行 process 時會以檔案擁有
者的身份來執行,例如我現在是用 ken 登入,但是當我執行 passwd 修改密碼時,
passwd 其實是以 root 權限在執行的,因為 passwd 有 set-user-id (suid)。

所謂的 EUID 與 EGID 是 effective user/group ID。
這東西就是指 process 在跑的時候,是用什麼身份在跑。
通常 EUID/EGID 會與現在的 UID/GID 相同,
但是當執行檔有SUID/SGID(set-user-ID, set-group-ID)屬性時,
則這個 process 在執行時,EUID/EGID 會變成檔案 owner 的 ID。

舉個最常見的例子,passwd 這隻程式因為要存取 /etc/passwd 或 /etc/shadow,
所以這個檔案在執行時必須要有 root 權限才能寫入,
但是你一定會很納悶,那為什麼我用一般 user 登入,
一樣可以用 passwd 來改自己的密碼呢?
答案就在於 passwd 有 SUID,
所以 passwd 在執行時,其 UID (或稱 real user ID) 即使是一般 user,
但是 EUID 其實是 root,這樣才能對 /etc/passwd 之類的檔案有存取權。
SGID 也是一樣的道理,因為早期系統沒有 mkdir system call,
為了使用只有 root 才能呼叫的 mknod 來產生目錄,就要利用到 SGID。
但是現代一些 UNIX-Like 的 implement 對 SGID 的繼承方式其實是有微妙的差異的。
如 BSD 與 Linux 在某些系統呼叫上對這個 bit 的處理都不太一樣。

至於 saved suid 是用來保存 suid 的,主要用途如下:


* saved suid 是 2001 年的 POSIX.1 標準, 在編譯階段可檢查 _POSIX_SAVED_IDS 定義.
* 在 runtime 階段可以透過呼叫 sysconf 帶入 _SC_SAVED_IDS 參數來檢查.
* 此屬性與兩個函式相關, exec 與 setuid.
* 這個屬性無法在執行階段取得, 此屬性是用來供 setuid 切換 effective uid 時用來比對的.
* saved uid 是用來供 setuid 函式能夠在 real uid 跟 saved suid 中切換 effective uid 用.

Refer to APUE 2E chapter 4.4, 8.11 and 10.9.

沒有留言: