LWN:Fedora 和 pkexec!
關(guān)注了就能看到更多這么棒的文章哦~
Fedora and pkexec
By Jake Edge
February 2, 2022
DeepL assisted translation
https://lwn.net/Articles/883547/
pkexec 中那個(gè)煩人的漏洞已經(jīng)在 Linux 世界中激起了漣漪,引出了對(duì)底層 polkit 授權(quán)工具包(authorization toolkit)的大量安全更新。它也引出了最近在 Fedora 開(kāi)發(fā)郵件列表中關(guān)于 pkexec(用來(lái)以另一個(gè)用戶的身份運(yùn)行程序)是否真的有必要、或者說(shuō)是否在某些或所有發(fā)行版中有必要的討論。但是 pkexec 被許多不同的 Fedora 組件所使用,尤其是在桌面版本 Fedora 中,在需要以另一個(gè)用戶的權(quán)限運(yùn)行程序時(shí),它也許是一個(gè)比其他選項(xiàng)更好的選擇。
Adam Williamson 在 PwnKit 漏洞披露的第二天提出了這個(gè)問(wèn)題。正如他所指出的,這是一個(gè)長(zhǎng)期存在的(從 2009 年第一個(gè)版 pkexec 開(kāi)始)本地 root 權(quán)限升級(jí)問(wèn)題。這讓他開(kāi)始思考:
這個(gè)問(wèn)題和周圍的一些評(píng)論,促使我想知道——為什么 `pkexec'仍然有必要存在?尤其是,為什么它仍然是我們?cè)诿恳粋€(gè) Fedora 安裝中都默認(rèn)使用的東西?
我的印象中,pkexec 是一個(gè)讓我們擺脫 consolehelper 的笨辦法:一些應(yīng)用沒(méi)有被改寫(xiě)成在 policykit 下的正確方式,他們?nèi)匀幌M麄€(gè)應(yīng)用以 root 身份運(yùn)行,而 pkexec 是實(shí)現(xiàn)這一目的的一種方法。
consolehelper 是另外一個(gè)允許用戶以其他用戶身份運(yùn)行代碼的程序,而 PolicyKit 是 polkit 的舊稱。2013 年的時(shí)候,F(xiàn)edora Usermode Migration 這個(gè)功能的設(shè)計(jì)目標(biāo)就是將 consolehelper 的所有用戶者都轉(zhuǎn)移到 polkit。Williamson 想知道,當(dāng)前的 Fedora 中有哪些部分仍然需要 pkexec(畢竟其更像是一個(gè)拼湊的用法)。但是,由于它被包含在 polkit 軟件包中,而 polkit 的使用非常廣泛,也許可以把 pkexec 分割成一個(gè) sub-package,只在真正需要它的地方安裝,這是他的建議。
在后續(xù)的討論中,Williamson 指出,根據(jù) Usermode migration 的 bug ticket 看來(lái)它還沒(méi)有完成。Fedora 中仍有 15 個(gè)軟件包需要 consolehelper。Peter Robinson 說(shuō),其中大部分 "似乎是歷史遺留" 軟件包,沒(méi)有再被普遍使用了。
Michael J Gruber 開(kāi)玩笑地問(wèn),他是否應(yīng)該把他的軟件包從 pkexec 切換到使用基于 consolehelper 的 beesu 包裝過(guò)的 su 命令上去,因?yàn)?beesu 在 Fedora 中仍然存在。但 Williamson 說(shuō)他可不建議這么做:
并不是說(shuō) pkexec 在本質(zhì)上比任何其他做差不多的事情(也就是提示輸入某個(gè)密碼,然后以 root 身份運(yùn)行整個(gè)應(yīng)用程序)的工具更糟糕。不幸的是 pkexec 碰巧有一個(gè)巨大的安全缺陷,但如果有人決定仔細(xì)檢查進(jìn)去的話,其他做同樣事情的工具沒(méi)準(zhǔn)也有安全缺陷。問(wèn)題是,*整個(gè)設(shè)計(jì)* 就不是最優(yōu)的。
他說(shuō),我們的想法是,應(yīng)該讓?xiě)?yīng)用程序轉(zhuǎn)而使用 polkit 提供的其他機(jī)制,以進(jìn)行他們的特權(quán)操作。對(duì)于那些不進(jìn)行這種改變的應(yīng)用程序來(lái)說(shuō),pkexec 是一個(gè) "不那么好的第二選擇",可以讓它們能繼續(xù)工作。刪除 consolehelper 是為了減少發(fā)行版需要注意的 "以 root 身份運(yùn)行命令" 的工具的總數(shù),盡管這還沒(méi)有完全完成。"從 pkexec 切換到其他任何 '以 root 身份運(yùn)行東西'的工具都不能算是改進(jìn)。"
如果你無(wú)論如何都要以 root 身份運(yùn)行程序, pkexec 可能比使用 sudo 或其他選項(xiàng)更好,Lennart Poettering 認(rèn)為。pkexec 已經(jīng)使用 polkit 進(jìn)程間通信(IPC)機(jī)制來(lái)請(qǐng)求以 root 身份運(yùn)行二進(jìn)制文件,這在他看來(lái)是一個(gè)優(yōu)越的模式:
我的意思是,polkit 有一些問(wèn)題,但我非??隙?,"pkexec" 本身我認(rèn)為并不是大問(wèn)題?;蛘邠Q個(gè)說(shuō)法:像 su/sudo/setpriv/runuser/suid binaries 這些工具的整個(gè)理念才是[有問(wèn)題的]:也就是說(shuō),我非??隙ǎ绻覀兡芟到y(tǒng)地禁止通過(guò) execve() 獲得權(quán)限,而把重點(diǎn)放在把權(quán)限操作委托給 IPC 服務(wù)上,我們會(huì)過(guò)得更好——當(dāng)然,這種做法與傳統(tǒng) UNIX 相比有很大區(qū)別。
[…] "pkexec "是一個(gè)?短小?的程序,它實(shí)際上只運(yùn)行了很少的特權(quán)代碼。這使得它比 "sudo" 這個(gè)[巨大的]代碼怪物要好上許多倍。它有一個(gè)更小的 安全規(guī)模(security footprint),而且比 "sudo" 更容易 review。這實(shí)際上是很有價(jià)值的。
但是 Sam Varshavchik 反對(duì)這樣的觀點(diǎn),他不認(rèn)為把特權(quán)操作轉(zhuǎn)移到 IPC 機(jī)制(比如 socket)的另一端,真的會(huì)解決什么根本問(wèn)題。當(dāng)前的問(wèn)題是,一些以 root 身份運(yùn)行的程序有 bug:
在 suid[也就是 setuid]二進(jìn)制文件中可被利用的 bug,如果出現(xiàn)在等價(jià)的無(wú) suid 的程序中,也同樣可以被利用,攻擊方式完全相同。如果你在 suid 二進(jìn)制文件中由于精心設(shè)計(jì)的命令行參數(shù)或環(huán)境變量而導(dǎo)致緩沖區(qū)溢出,那么如果你用一個(gè)相同的 bug-for-bug 實(shí)現(xiàn)來(lái)替換 suid 二進(jìn)制文件,使用 socket 來(lái)仔細(xì)傳遞相同的環(huán)境變量或參數(shù)給本地 root 權(quán)限的二進(jìn)制程序,并且產(chǎn)生相同的緩沖區(qū)溢出,那么你猜怎么著:你仍然有相同的漏洞。
suid 不是問(wèn)題所在。execve 執(zhí)行的程序?qū)⒗^承環(huán)境變量以及打開(kāi)的文件描述符,也許還有一些其他的東西,而一個(gè)接受 socket 連接的獨(dú)立 daemon 程序是沒(méi)有這些東西的。但這些是大多數(shù)漏洞利用的東西,所以清理掉環(huán)境變量和已打開(kāi)的文件描述符可以彌補(bǔ)這個(gè)漏洞。要利用其他內(nèi)容的話,攻擊者就需要更加費(fèi)力了。
然而,Poettering 并不這樣看。在執(zhí)行 setuid 二進(jìn)制文件時(shí),會(huì)有大量的狀態(tài)變化,而且這些狀態(tài)會(huì)隨著時(shí)間的推移而增加:
setuid/setgid 的問(wèn)題在于,被調(diào)用的特權(quán)進(jìn)程繼承了很多隱含的狀態(tài)和上下文,而人們并沒(méi)有真正意識(shí)到、或完全理解這些狀態(tài)和上下文。也就是說(shuō),它不僅僅是 env vars 和 argv[],還包括 cgroup membership、audit fields 字段、security context 安全上下文、打開(kāi)的 fds、子進(jìn)程 pids、父進(jìn)程 pids、cpu mask、IO/CPU 調(diào)度優(yōu)先級(jí)、各種 prctl()設(shè)置、tty 控制、signal mask+handler,…等等。甚至不清楚什么會(huì)被繼承下來(lái),因?yàn)檫M(jìn)程一直在不斷增加更多的屬性。
如果你通過(guò) IPC 來(lái)對(duì)特定的操作進(jìn)行特權(quán)執(zhí)行,你就會(huì)得到保證,無(wú)論做什么,都是在一個(gè)定義良好的、原始的執(zhí)行環(huán)境中完成的,不會(huì)隱性地泄露上下文。IPC 消息是?全部的?脆弱攻擊面了,這是我們能做到的最小的攻擊面。這很好。
Varshavchik 說(shuō),雖然所有這些上下文和狀態(tài)都存在于 setuid 程序中,但根本問(wèn)題是在程序本身:
而這些都沒(méi)有任何區(qū)別,除非代碼本身也有一個(gè)潛在的邏輯錯(cuò)誤。而這將是真正的問(wèn)題。那么,問(wèn)題就來(lái)了,有多少漏洞利用了這些特別的資源,比如 cgroup members、tty control 以及所有其他那些不被注意的屬性?我想可能有幾個(gè),但我想不起來(lái)了。另一方面,完成 execve("/bin/bash") 的漏洞也同樣有效,因?yàn)?root 守護(hù)進(jìn)程中有同樣的潛在 bug,可以通過(guò)其前端或 suid 程序觸發(fā)。一個(gè)經(jīng)過(guò)消毒的環(huán)境不會(huì)有什么幫助。
但對(duì)于 setuid 程序來(lái)說(shuō),完全凈化環(huán)境是很難或不可能做到的,Poettering 說(shuō)。有許多相互交互的屬性是由 setuid 二進(jìn)制程序的調(diào)用者(也就是攻擊者)控制的,而且這個(gè)數(shù)字還在不斷增加:
你可能*希望*沒(méi)有通過(guò)所有這些代碼的交互引入錯(cuò)誤,但我想說(shuō)的是,"struct task "和內(nèi)核中的相關(guān)對(duì)象一直在被擴(kuò)展,而那些沒(méi)有預(yù)料到這些添加物的 suid 程序?qū)⒈槐┞对谄渲?,而且即使他們想重置它們,也不能理智地重置,因?yàn)橥ǔi_(kāi)發(fā)人員不能展望未來(lái)(而且 cgroup 的東西甚至根本不能合理地重置)。
Varshavchik 想拿到一些數(shù)據(jù)依據(jù),來(lái)證明這里設(shè)想的各種漏洞的情況。他和 Poettering 來(lái)回討論了一陣有什么算是合適的數(shù)據(jù),但沒(méi)有真正達(dá)成一致。Poettering 在結(jié)束他對(duì)這個(gè)子話題的參與時(shí)指出,他可以理解 "你對(duì) suid 和 sudo 的熱愛(ài)",但他和其他人認(rèn)為它們是 "一個(gè)非常糟糕的主意"。Varshavchik 認(rèn)為他并不是對(duì)這些機(jī)制感到著迷:
我說(shuō)不上喜歡或者不喜歡 suid + sudo,就跟我喜歡我的螺絲刀差不多。我對(duì)這兩者都不感冒。兩者都只是工具。兩者都可以被人們正確使用。兩者也都可以被人們以錯(cuò)誤的方式使用。但是,并不會(huì)因?yàn)檫@一點(diǎn)而用扳手來(lái)替代螺絲刀。
Demi Marie Obenour 建議,被一個(gè) setuid 二進(jìn)制文件繼承哪些狀態(tài)信息,應(yīng)該由該二進(jìn)制文件來(lái)選擇。"狀態(tài)的繼承絕對(duì)應(yīng)該是精心選擇過(guò)的,但某些 audit 數(shù)據(jù)可能例外,如 audit user ID"。從事 Linux audit 系統(tǒng)開(kāi)發(fā)工作的 Steve Grubb 說(shuō),audit 依賴于二進(jìn)制文件繼承 security context 和 audit 信息,所以現(xiàn)有的 polkit 機(jī)制是不夠的。如果采用 kdbus 這樣的內(nèi)核機(jī)制,那么這個(gè)問(wèn)題就可以避免了。就目前的情況來(lái)看,polkit "不能滿足我們的安全要求":
[……]因?yàn)?policy 是千變?nèi)f化的 javascript, 而不是一些可以被什么掃描程序來(lái)檢查的一些固定配置,所以無(wú)法確定應(yīng)該允許哪些狀態(tài),拒絕哪些狀態(tài)。而且決定是否能訪問(wèn),也并不經(jīng)過(guò) audit 系統(tǒng)。因此,我們對(duì)那些使用了 IPC 啟動(dòng)的應(yīng)用程序,很少能了解它的訪問(wèn)控制以及信息流情況。
Setuid 可能對(duì)某些人來(lái)說(shuō)是很令人討厭的。但它的屬性是眾所周知的,完全可以對(duì)平臺(tái)提供一定程度的保證。
他并不是唯一一個(gè)抱怨 polkit 的 JavaScript 配置機(jī)制的人,因?yàn)檫@被許多人看作是一個(gè)糟糕的設(shè)計(jì)決策。同時(shí),Andrew Lutomirski 說(shuō),實(shí)現(xiàn)一個(gè)內(nèi)核內(nèi)的 IPC 機(jī)制是很困難的問(wèn)題。他對(duì) setuid 也有一些想法:
我希望在 Linux 內(nèi)核中看到一個(gè)很好的 IPC 安全模型,但我還沒(méi)有見(jiàn)過(guò)可靠的提案出來(lái)。這個(gè)問(wèn)題是?非常難的?。
至于 setuid,我強(qiáng)烈認(rèn)為 setuid 無(wú)論是在過(guò)去和現(xiàn)在都是一個(gè)錯(cuò)誤。執(zhí)行一個(gè)進(jìn)程不應(yīng)該增加權(quán)限。
回到他最初的主題,Williamson 指出,這個(gè)話題的討論已經(jīng)很清楚地表明,目前至少有一些 Fedora 的桌面版之類的發(fā)布(spin)需要 pkexec,不過(guò):"這不是一個(gè)容易回答的問(wèn)題,因?yàn)槲覀兊拇虬到y(tǒng)并沒(méi)有區(qū)分哪些東西需要?polkit?哪些東西需要?pkexec?。" Fedora 項(xiàng)目負(fù)責(zé)人 Matthew Miller 認(rèn)為這至少是可以修改的:"我想,第一步可能是把 pkexec 拆成一個(gè) subpackage,然后逐漸消滅對(duì)它的依賴。"
這就是目前為止的所有情況了。把 pkexec 拿出來(lái)它打包,似乎是一個(gè)好的計(jì)劃,不管它是否應(yīng)該慢慢地從實(shí)際使用中移除出去。如果出現(xiàn)另一個(gè)漏洞,也會(huì)更加容易地追查哪些其他 package 在使用它。長(zhǎng)期來(lái)說(shuō),轉(zhuǎn)向更多的或完全是 polkit 式的權(quán)限提升功能可能不一定會(huì)實(shí)現(xiàn)。在這條道路上的共識(shí)尚未完全弄清楚,而且這也是一個(gè)發(fā)行版中不希望看到大量改動(dòng)的領(lǐng)域,至少不太會(huì)有很多代碼 review。
就像大多數(shù)(所有?)漏洞一樣,真正的罪魁禍?zhǔn)资侨狈?duì)代碼的集中安全審查(focused security review)。對(duì)于 setuid 二進(jìn)制文件以及其他那些以 root 身份運(yùn)行的代碼來(lái)說(shuō),review 應(yīng)該是必須的,但目前還不清楚是否有大量密集的 review 正在進(jìn)行。每當(dāng)另一個(gè)影響廣泛的漏洞出現(xiàn)時(shí),我們就會(huì)被提醒,但相關(guān)的影響似乎很快都會(huì)消失,事情又恢復(fù)了 "正常"。這是一個(gè)相當(dāng)令人擔(dān)憂的狀態(tài)。
全文完
LWN 文章遵循 CC BY-SA 4.0 許可協(xié)議。
長(zhǎng)按下面二維碼關(guān)注,關(guān)注 LWN 深度文章以及開(kāi)源社區(qū)的各種新近言論~
