2013-05-18 73 views
1

根據issetugid的手冊頁,呼叫應該是(1)警告uid/gid變化;或(2)警告可能受污染的環境。函數名稱提示了第三個目的。issetugid的用途?

第一個問題:它的目的是什麼?

當我看到可用的實現(例如,Linux系統作爲一個庫,因爲Linux內核不提供API上),我發現了以下內容:

if (getuid() != geteuid()) return 1; 
if (getgid() != getegid()) return 1; 
return 0; 

在Solaris上,它看起來如下:

return ((curproc->p_flag & SUGID) != 0); 

我有點懷疑,但是這部分是因爲它很難明白什麼樣的跨平臺geteuidgetegid回報功能 - 例如,BSD,Linux,Unix和Solaris操作系統。

第二個問題:Linux代碼在語義上是否等同於Solaris代碼?

第三個問題:是否geteuidgetegid跨平臺實現?對於擁有三位身份證明系統的系統如何 - 真實,有效並保存?

第四個問題:在這裏唯一的id是否是有效的id?

如果一個進程以UID = 0開始,並暫時放棄權限,那麼saved就會發揮作用。暫時丟棄root的進程不需要exec,並且不應該被污染。

第五個問題:是否會暫時丟棄根感染的進程?

第六個問題:如果一個進程的有效id是被保存的id被認爲是有問題的?

+0

所陳述的主要理由罵issetugid-在setuid或setgid程序或程序 ,一個成功的高管後,有更多的權限運行時,以保證安全 行爲。你可能會使它比實際更復雜。 –

+0

謝謝吉姆。我處於困境 - 我正在審覈一些使用該函數的代碼。在Linux上,該庫提供API,因爲它不是。但我不知道它應該做的(因爲它的非標),或者如果它有效地做這件事([設置uid揭祕](http://www.cs.berkeley.edu/~daw/papers/setuid- usenix02.pdf))。 – jww

回答

4

六個問題有點多,以設計爲一個回答的問題,特別是如果沒有一個人知道答案,所有六個,但我會盡力的系統回答...

1)目的issetugid()的目的是讓圖書館知道它們是否被用於一個以提升特權運行的程序中,以便它們可以避免諸如信任LD_LIBRARY_PATH,NLSPATH等的風險行爲。環境變量會讓調用者加載可能會濫用提升特權。你可以看到它的一些歷史討論,如ncurses 4.1 security bug thread

2)該代碼似乎不如BSD & Solaris版本安全,因爲它沒有考慮保存的setid位。

3)它們在不同的內核上可能有不同的實現 - 查看平臺源代碼以找出答案。

4)5)& 6)不,是的,是的 - 一個可以將其euid或egid更改回更高級別的進程仍然不相信導致它加載用戶提供的代碼來利用它們的環境變量。

+0

〜alanc - 「六個問題有點多,以設計爲一個問題的系統回答......」是的,同意。這是一個職位與多個問題,或多個職位(與大量複製/粘貼)與一個問題之間的權衡。 – jww

+0

感謝您回答問題2和4.我有同樣的感受。另外,你看到的比賽是一個問題(這是因爲Linux(和其它操作系統一個不太重要的問題)是全種族的)。 – jww

+0

如果代碼是多線程的,那麼,檢查的getuid/geteuid /等等的當前結果。如#2所示可以與setuid/seteuid /等競爭。根據誰贏得比賽,調用並返回不同的答案。 – alanc

2

我不知道issetugid(),但我可以通過閱讀BSD或Solaris手冊頁瞭解到。該函數來自OpenBSD。1)OpenBSD的issetugid(2)手冊說:「如果進程是setuid或setgid作爲最後的或其他先前的execve()系統調用的結果,則issetugid()函數返回1,否則返回0。然後建議使用issetugid()來檢查環境變量中指定的文件是否可以安全地打開。

2)不,您的Linux和Solaris代碼不相同。運行setuid的進程可能會將其真實uid設置爲其有效的uid,而不清除其環境變量。例如,uid_t uid = geteuid(); setresuid(uid, uid, uid);會將真實用戶和保存的用戶界面設置爲有效的用戶界面。然後,您的Linux issetugid()將返回0,但Solaris issetugid()將返回1.

Solaris在執行時檢查SUGID進程標誌。 Illumos是Solaris的免費分支,它在執行文件時在src/uts/common/os/exec.c中設置SUGID。 OpenBSD具有類似的邏輯。 OpenBSD的手冊說,

如果一個子進程執行一個新的可執行文件,一個新的issetugid狀態將被確定。此狀態基於現有進程的uid,euid,gid和egid權限以及可執行文件的模式。如果新的可執行文件模式是setuid或setgid,或者現有進程正在使用uid!= euid或gid!= egid執行新映像,則新進程將被視爲issetugid。

Solaris和OpenBSD比較執行時的ID。你的Linux代碼延遲比較,直到調用issetugid(),所以它不是等價的。

3)geteuid()getegid()函數似乎在任何地方都是這樣做的;他們只需返回有效的用戶標識和有效的組標識。

4)保存的id不重要。該過程可能在不清除其環境變量的情況下更改了這些ID。真實的,有效的或保存的id沒有告訴我們是誰爲當前進程設置了環境變量。

5)至少在OpenBSD和Solaris上,暫時丟棄root的進程不會被污染。 OpenBSD的手冊頁說,

issetugid()系統調用的結果不受對setuid(),setgid()或其他此類調用的調用的影響。在fork()的情況下,子進程繼承相同的狀態。

issetugid()的狀態只受execve()的影響。

當進程臨時將setuid()或seteuid()放在根上時,它不會執行文件,因此其issetugid()值不會更改。

但FreeBSD,DragonFly BSD和NetBSD更嚴格地定義了issetugid()。 FreeBSD的手冊issetugid(2)說,如果它被作爲execve的(2)系統調用其具有任一組的setuid或setgid位(和額外的特權的結果創建的給予結果

的方法受到了污染),或者自從它開始執行以來它已經更改了任何真實的,有效的或保存的用戶或組ID。

使用這些系統,刪除根的進程確實將其issetugid()值強制爲1。

6)否,有效的ID等於保存的ID不玷污的處理。如果是這樣,那麼每個進程都會受到污染,因爲每個進程都會在執行時將其保存的id設置爲其有效標識。