Curl之父:我是如何枕著18萬行C程式碼還能安穩入睡的

作者丨 David Cassel
譯者丨明知山
策劃丨 Tina
Curl 作為一個安裝量超過 200 億次的開源專案,承載著極高的安全性和穩定性要求。其作者 Daniel Stenberg 透過嚴格的程式碼規範、工具化的錯誤預防、海量的測試體系,以及高效的漏洞修復流程,確保專案的可靠性。面對“是否用 Rust 重寫 Curl”的討論,他明確表示,Curl 不會被重寫,而是透過持續迭代和精細打磨來提升安全性。專案團隊不僅採用多層次的測試方法,還透過安全審計、漏洞賞金計劃等手段,不斷最佳化程式碼質量。這種對細節的極致追求,為開源軟體的長期維護和安全保障提供了寶貴的經驗。  
在本年度的 FOSDEM 開源大會上,Curl 作者 Daniel Stenberg 分享了“如何在你的 C 語言程式碼安裝量達到 200 億次時依然能睡得安穩”的秘訣。
Stenberg 認為,全球的 Curl 安裝量達到 200 億次可能還只是一個保守的估計。
這個數字無疑讓這個由他獨立開發的開源資料傳輸工具專案承擔起了“一點點”責任。
“當然,我們用的是最安全的程式語言。”他說道,這引得觀眾們一陣笑聲——因為 Curl 是用 C 語言編寫的。
他的演講既有趣又幹貨滿滿,令人信心倍增。
它還提供了一個鼓舞人心的例子,展示了當一個專案專注於更高層次的安全性時會發生什麼,以及這種承諾如何轉化為實際行動——尤其是在風險異常高的情況下。
這不是一個副業專案
在演講的最後,Stenberg 展示了一張有趣的幻燈片,模仿 O'Reilly 出版社的書皮,書名是《用 Rust 重寫 Curl,一個副業專案》(書皮上方還加了一句標語:“與其親自動手,不如告訴別人怎麼做”)。
“這本書非常受歡迎。”Stenberg 說道,並尖銳地指出,“但沒有人真正實現過。”
Curl 包含 18 萬行 C 語言程式碼,相當於《戰爭與和平》這部小說長度的 1.14 倍。Stenberg 說:“對於它的功能來說,這些程式碼算相當多了……它只是一個用來傳輸資料的工具。我們不會用 Rust 重寫 Curl,也不會用任何其他語言——我們不會重寫它。它已經在那裡了。”Stenberg 承認 Rust “可能是一種很棒的語言”,並表示第三方依賴項可以用 Rust 編寫,他預測未來在 Curl 專案中會有更多這樣的情況。
但目前 Curl 的程式碼庫仍然用 C 語言編寫,“我們只是耐心地迭代和打磨,隨著時間的推移不斷完善。不會有任何重寫。”
因此,他在演講中展示的其實是他在保持 Curl 安全性方面所做的工作。
雖然他們用 C 語言編寫程式碼,但 Stenberg 表示,他們已經禁止使用“一些容易出錯的函式”。
在演講結束時,有人要求舉例,Stenberg 首先提到了 gets()(Stack Overflow 上有評論者稱其為“製造緩衝區溢位的惡魔工具”),還有 scanf()、strcopy() 和 sprintf()。
“不管你經驗有多豐富——C 標準庫中的一些函式真的不建議在程式碼中使用。我們用工具檢查並禁止使用它們,這樣就不會不小心讓它們混進去了。”
測試,測試……
他們還有一種特殊的“折磨測試”,在除錯構建過程中,每個可能發生記憶體分配失敗的函式(如 malloc 或 calloc)都有一個包裝器,讓他們可以反覆呼叫這些函式——一直呼叫直到失敗。Stenberg 解釋說:“它們應該是優雅地失敗——沒有記憶體洩漏,沒有崩潰,只以錯誤碼的形式退出。這是測試退出路徑的絕佳方式,確保我們在退出時總是釋放和清理了資源。”
開發團隊並不會測試所有東西。他笑著說:“這可不是一個快速的過程。”因此,他們設計了一個系統,隨機測試一個較小的子集。他們還使用了持續整合,每一個拉取請求和程式碼提交都會執行 40 多萬個測試。“我記得大概一年前執行這些測試需要花費數小時,”他回憶道,但在對測試進行了最佳化之後,現在只需要 30 分鐘。“快速執行測試讓我們能夠立即瞭解程式碼變更的最新狀態。”
你可能聽說過“ CPU 秒”這個詞,即全功率使用伺服器級 CPU 一秒鐘—— 86400 個 CPU 秒加起來就是一整天的 CPU 時間。Stenberg 表示,目前“我們每天在 CI 上平均花費大約 10 個 CPU 天。”
為了確保整個專案的安全性,Stenberg 還提到了其他各種各樣的測試——甚至有一個是測試“程式碼風格是否正確,以及程式碼中的縮排和拼寫是否準確”。他們還有一個 CI 任務,用於確保程式碼中沒有任何二進位制程式碼塊。
還有單元測試、庫測試、工具測試,“當然,我們還有一直在檢查程式碼的分析器”——包括靜態和動態分析器。Curl 還是谷歌 OSS-Fuzz 專案的一部分。
“我們希望確保這 200 億次安裝都能正常執行。”
修復和發現漏洞
談到漏洞時,Stenberg 表示:“我們會盡快修復漏洞,按規定通知發行版,並非常詳細地記錄所有資訊,包括以 JSON 格式列出受影響的 Curl 版本。”這些資訊也會發布在 Curl 的官方網站上。Curl 專案現在也是一個官方的 CVE 編號機構,“這樣我們可以更好地管理我們自己的 CVE。”
他們非常重視發現漏洞,Stenberg 補充說:“我們進行了多次審計。”
Stenberg 回憶說,他們在 2016 年的第一次審計“發現了 7 個 CVE”,2022 年的審計又發現了 2 個 CVE。但他自豪地表示,2024 年的一次更嚴格的審計結果是 0 個 CVE——這是一個令人振奮的趨勢。審計是一項艱鉅的任務。“有人會花大量工時來檢視程式碼……對於一個小型開源專案來說,這不是一件容易做好的事情。你需要有足夠的資金支援,才能讓這一切成為可能。”
他指出,審計的成本“比我們多年的漏洞賞金計劃的總成本還要高”——儘管漏洞賞金計劃最終發現了更多的 CVE。
這個漏洞賞金計劃與 HackerOne 和網際網路漏洞賞金計劃(Internet Bug Bounty Program)合作開展。Stenberg 表示,自 2019 年 4 月啟動計劃的六年來,他們已經支付了超過 85000 美元。在 500 份漏洞報告中,有 76% 導致了 CVE(有 19% 是非 CVE 級別的漏洞)。“其他的報告並不都是無效的,”Stenberg 說,“但也確實有不少……我們會公開所有報告的後續討論,方便大家跟進……”
儘管“漏洞賞金”幻燈片上的最後一項只是提到“AI 垃圾報告越來越多”。
“實際上,目前我們收到的有效報告和‘AI 垃圾報告’的比例差不多,”Stenberg 表示——大約有 10% 到 15% !
全方位的安全性
該專案致力於實現最高級別的安全性,這種承諾似乎滲透到了每一個層面。
所有提交的程式碼都經過仔細評審——既有人工評審,也有機器評審。Stenberg 說:“現在我們有一個非常嚴格的程式碼風格”,這讓整個 18 萬行的程式碼庫看起來像是由一個作者編寫的(這種一致性使得程式碼更容易閱讀和除錯)。
“我們有大量的文件,涵蓋了原始碼、內部 API 和所有相關內容。”後來 Stenberg 解釋說,甚至還有文件檢查工具,不僅限於檢查拼寫和語法。“例如,我們會盡量避免在文件中使用英語縮寫,像“isn't”這樣的表達是不被允許的……諸如此類……”
該專案的開發團隊在訪問託管在 GitHub 上的原始碼時都使用雙因子認證……
GitHub 為他們提供了額外的測試資源,導致在 Mastodon 上引發了一些有趣的討論,例如,其他開源專案是否也應該從一開始就採用最嚴格的安全措施。
“我認為大多數開源專案都是從‘小’和‘簡單’起步的,”Stenberg 回應說,並補充道,“從一開始就做到盡善盡美,確保一切嚴格無誤,甚至是在還不確定專案是否能成功之前,可能並不明智。我認為很少有專案能做到……我們開始時幾乎每個環節都很鬆散……”
在後續的討論中,Curl 開發者 Stefan Eissing 開玩笑說,有時候感覺風險巨大。“我們有一些開源專案,‘感覺如果搞砸了,幾個星球的文明就會終結’。這可不是文明該有的運作方式。”
Stenberg 對 GitHub 給予他們的幫助心存感激,也許他希望這種水平的支援能夠延伸到更多正在努力解決自身問題的開原始碼庫上。
“放眼世界,許多專案仍然需要得到一些幫助……”
原文連結:
https://thenewstack.io/curls-daniel-stenberg-on-securing-180000-lines-of-c-code/
宣告:本文為 InfoQ 整理,不代表平臺觀點,未經許可禁止轉載。
今日好文推薦
被 GitHub 上的 Stable Diffusion 坑慘了?失業、欠帳、恐慌,工程師怒噴:AI軟體毀了我!
不用英偉達嚴選?DeepSeek 為何自研高效能檔案系統 3FS,挑戰行業“標準答案”
英偉達“賺錢機器”更強了!盈利創紀錄,黃仁勳:DeepSeek 為 GPU 降本,但下一代模型還離不開我
沒有“包袱”的火山引擎,跑贏“DeepSeek 大考”
直播預告
今年年初,扎克伯格宣佈 Meta 計劃用 AI 取代中級軟體工程師,與此同時,Salesforce 也表示今年將暫停招聘軟體工程師。種種跡象似乎都在進一步印證一個趨勢——AI 正在加速取代部分軟體工程崗位。在技術圈,人們一方面因 AI 帶來的生產力飛躍而興奮不已,另一方面,也難免瀰漫著一絲焦慮。
3 月 3 日晚 20:00 直播,一起圍繞“當下 AI 如何影響工程師的就業”、“工程師核心競爭力的再定義”等話題,探討工程師如何應對這場變革。

相關文章