LWN:給 io_uring 添加 audit 支持!
關(guān)注了就能看到更多這么棒的文章哦~
Auditing io_uring
By Jonathan Corbet
June 3, 2021
DeepL assisted translation
https://lwn.net/Articles/858023/
io_uring 子系統(tǒng)于 2019 年首次推出以來,已經(jīng)迅速成為執(zhí)行高帶寬的異步 I/O 操作的首選方式。它引起了許多開發(fā)人員的注意,包括最近那些關(guān)注安全更甚于性能的開發(fā)者?,F(xiàn)在,安全社區(qū)的一些成員感嘆在 io_uring 中缺乏考慮安全性,因此希望在這個領(lǐng)域中添加 audit 和 Linux security module 的支持來彌補這一缺陷。這個工作目前看來很困難,甚至引出了一個不那么讓人高興的后備解決方案。
Linux 的 audit 機制允許監(jiān)控和記錄系統(tǒng)中所有重要的活動。例如,有人想知道誰查看了一個特定的文件,那么具備 audit 功能的系統(tǒng)就可以提供這個答案。audit 能力是獲得一些安全認(rèn)證的必要條件,而這些認(rèn)證又是在一些對安全比較敏感的環(huán)境中部署 Linux 的必要條件。其實相對來說只有一小部分 Linux 系統(tǒng)打開了 audit 功能,但發(fā)行版提供方幾乎無一例外地在他們的內(nèi)核中都啟用了 audit。
audit 機制反過來又依賴分散于內(nèi)核源代碼中的許多 hook 代碼。每當(dāng)某一個人們可能感興趣的事件發(fā)生時,就會通過適當(dāng)?shù)?hook 被報告給 audit 代碼。然后 audit 子系統(tǒng)會根據(jù)一組從用戶空間加載進(jìn)來的規(guī)則來控制哪些事件需要被報告給用戶空間。
在 io_uring 被開發(fā)出來時(當(dāng)然現(xiàn)在仍是在進(jìn)行中),開發(fā)人員對性能和功能非常關(guān)注。而 audit 這類的安全特性并不是他們的首要任務(wù),所以他們當(dāng)然也就忽略了要添加相關(guān)的 hook,或者說沒有考慮過如何能在符合性能目標(biāo)前提下也支持 audit?,F(xiàn)在,io_uring 出現(xiàn)在更多發(fā)行版的內(nèi)核之中了(也就是 audit 可能會被缺省啟用的那些內(nèi)核),因此安全相關(guān)的開發(fā)者開始有些擔(dān)心了。如果 io_uring 成為了規(guī)避所有 audit 監(jiān)控的一種方式,這對于維持安全認(rèn)證來說不是一種好做法。
Adding security support
5 月下旬的時候,Paul Moore(audit 子系統(tǒng)的維護(hù)者)發(fā)布了一組補丁,向 io_uring 添加了 Linux security module(LSM)和 audit 功能。LSM 方面相對簡單一些,因為 io_uring 執(zhí)行的操作已經(jīng)被 LSM hook 涵蓋了,所以所需要做的只是增加兩個新的 hook 來判斷具體是哪種 io_uring 操作。具體來說,這兩個 hook 控制(進(jìn)程之間)共享信息,而這些信息就是存儲在 ring buffer 中用于向內(nèi)核傳達(dá)操作請求的。詳情請見 patch。patch set 中的這一部分似乎沒有什么爭議。
audit 代碼則不一樣了。因為 io_uring 的核心代碼已經(jīng)被仔細(xì)優(yōu)化過了,希望能盡可能快地完成處理所有的 request 以及相應(yīng)的結(jié)果。io_uring 的使用場景中可能會有每秒執(zhí)行數(shù)百萬次的 I/O 操作,所以這里增加任何開銷都是不受歡迎的。如果在 ring buffer 的操作中添加 audit 相關(guān)的 hook 的話,就會拖慢了 io_uring 最關(guān)鍵的性能指標(biāo),因此引起 Pavel Begunkov 的負(fù)面評價:"所以,這組 patch 在最繁忙的函數(shù)之一的每個請求中都增加了兩個帶有 memory load 操作的 if(即 current->audit_context)。不可能接受這樣的改動"。
Begunkov 建議,也許可以在運行時通過 patch 方式來加上 audit hook,就像 tracepoints 和 kprobes 的工作方式那樣。Moore 回應(yīng)說,audit 子系統(tǒng)不支持這樣的 patch 方式,而且這樣做可能會引起一些本質(zhì)問題:"我感覺它會違反那些安全認(rèn)證"。因此,這似乎不是一個可能的解決方向。
同時,io_uring 的維護(hù)者 Jens Axboe 做了一些測試。一個簡單的 random-read 測試在使用了 audit hook 后,即使沒有加載任何實際有效的 audit rule,速度也降低了近 5%。其他各類基準(zhǔn)測試也得到了同樣的結(jié)果,哪怕是在使用更新過之后的 patch set(尚未公開發(fā)布)也一樣。為了 5% 的性能提升,內(nèi)核開發(fā)者可能會需要數(shù)月的辛勤工作,如果因為 audit hook 而導(dǎo)致這么大的性能損失,對他們來說就是一顆苦果。
Axboe 指出,以前通過老的異步 I/O 系統(tǒng)調(diào)用接口啟動 read 和 write 操作時,是不會被 audit 的。"在過去的二十年里,是不是說明這并不是一個問題?" 他同意一些操作(比如打開或刪除文件)應(yīng)該被 audit,但他認(rèn)為對讀寫操作進(jìn)行 audit 則 "只是純粹的噪音,一點用都沒有"。由于這些操作是對性能影響最大的操作,因此如果能讓 audit hook 不影響這些操作,可能是一個解決方案。
Moore 提出了一個基于這個想法的方案,也就是只對特定的、精心選擇的那些操作才會使能 audit hook。io_uring dispatcher 中有一個很方便的 switch 語句,可以很容易地用來只對需要關(guān)注的操作進(jìn)行 audit 檢測。他希望聽聽大家的意見,但到目前為止還沒有多少回復(fù)。正如 Begunkov 指出的,一個很重要的問題是哪些操作需要進(jìn)行 audit。對打開文件這個操作添加一個 audit 調(diào)用一般不太會影響到人們,而如果對 poll 這類操作添加 audit 的話則是另一回事了。Moore 已經(jīng)提出了一組他認(rèn)為值得 audit 的操作集合作為討論的基礎(chǔ)。
Threads and grumbles
如果幸運的話,這個解決方案會被大家都接受。根據(jù) Moore 的說法,如果在 io_uring 中不能支持 audit 的話,那就更加不妙了:
如果我們不能在這里找到一個解決方案,我們將需要使 io_uring 和 audit 互不兼容,我認(rèn)為這不符合用戶的最佳利益,而且肯定會讓發(fā)行版提供方頭痛。
"頭痛 "這個詞并不特別準(zhǔn)確。如果這兩個功能是互不兼容的話,那么就不可能編譯出一個能同時支持這兩個功能的內(nèi)核。因此,發(fā)行商將不得不提供兩個不同的內(nèi)核(他們總是竭力避免這種情況),或者從這兩個功能中選擇一個來支持。希望事情不會發(fā)展到這一步。
同時,雙方的開發(fā)者都表達(dá)了一些不滿,但安全開發(fā)者很明確地表示,他們更希望看到 audit 從一開始就設(shè)計在 io_uring 中。正如 Casey Schaufler 所說:
如果 audit 和 LSM 的需求在一開始就被包含到 io_uring 的設(shè)計中的話,那就會非常方便了。性能方面的影響可以直面去解決。否則的話,今后可能不得不重新進(jìn)行改造了。
Richard Guy Briggs 也抱怨說:"許多安全方面的擔(dān)心似乎總是事后才想到的,因此導(dǎo)致必須在后來補上。" 這兩個評論的意思都是說,如果有足夠的先見之明的話,現(xiàn)在遇到的困難本來是可以避免的。
這可能算是一個公平的批評意見。內(nèi)核開發(fā)者在開發(fā)新的功能時,常常把安全問題留到今后考慮。對于像 audit 這樣相對小眾的功能來說更是如此,因為它一般不可能在開發(fā)系統(tǒng)中啟用。內(nèi)核社區(qū)對安全開發(fā)人員可能有點不友好,認(rèn)為他們總是把安全放在第一位(居然超越了性能要求)。這樣的一個討論環(huán)境似乎就是告訴大家可以先把安全問題丟在一邊、等以后再解決。
不過,也應(yīng)該指出,io_uring 自 2019 年初以來一直在公開進(jìn)行開發(fā)。它已經(jīng)在郵件列表(和 LWN)中得到了大量的討論,但安全社區(qū)并沒有將這些信息作為他們應(yīng)該盡快提出建議來支持 audit 的線索。很少有內(nèi)核開發(fā)者能夠在實現(xiàn)每秒百萬次操作的 I/O 子系統(tǒng)的同時,還能設(shè)計好 security hook 并且不影響性能。也許 io_uring 的開發(fā)者從一開始就應(yīng)該考慮安全問題,但他們也應(yīng)該從一開始就得到幫助。
內(nèi)核社區(qū)對于增加像 io_uring 這樣的新功能時,很少有一些必須的規(guī)定,這一點很讓人驚訝。理論上來說,新的系統(tǒng)調(diào)用應(yīng)該要有 man page,但是真的哪天有 man page 先出現(xiàn)了的時候,人們肯定會感到驚訝。在一個有更多正規(guī)流程的項目中,就很有可能會堅持新功能在對 LSM 和 audit 等機制有了適當(dāng)支持之前是不能合入的。這可能會迫使人們更早地與安全開發(fā)人員開始互動,從而避免發(fā)生這種問題。
但這并不是我們所處的世界。從來沒有人會根據(jù) check list 來逐項檢查,確保在合并一個新的子系統(tǒng)之前,所有的工作都已經(jīng)逐項完成了。因此,內(nèi)核社區(qū)將不得不繼續(xù) “混日子”,盡其所能地支持所需的功能。這不會是最后一次出現(xiàn)這種要為了安全機制來改造現(xiàn)有的內(nèi)核功能的事情。可以說,這不是最好的方法,但一般來說最終總還是能完成工作的。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。
長按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開源社區(qū)的各種新近言論~
