在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在Rust被很多項目使用以后,其實際安全性表現(xiàn)到底如何呢?

華為開發(fā)者社區(qū) ? 來源:華為開發(fā)者社區(qū) ? 2020-09-04 11:53 ? 次閱讀

近幾年,Rust語言以極快的增長速度獲得了大量關(guān)注。其特點是在保證高安全性的同時,獲得不輸C/C++的性能,讓系統(tǒng)編程領(lǐng)域難得的出現(xiàn)了充滿希望的新選擇。在Rust被很多項目使用以后,其實際安全性表現(xiàn)到底如何呢?

今年6月份,來自3所大學(xué)的5位學(xué)者在ACM SIGPLAN國際會議(PLDI'20)上發(fā)表了一篇研究成果,針對近幾年使用Rust語言的開源項目中的安全缺陷進行了全面的調(diào)查。這項研究調(diào)查了5個使用Rust語言開發(fā)的軟件系統(tǒng),5個被廣泛使用的Rust庫,以及兩個漏洞數(shù)據(jù)庫。調(diào)查總共涉及了850處unsafe代碼使用、70個內(nèi)存安全缺陷、100個線程安全缺陷。

在調(diào)查中,研究員不光查看了所有漏洞數(shù)據(jù)庫中報告的缺陷和軟件公開報告的缺陷,還查看了所有開源軟件代碼倉庫中的提交記錄。通過人工的分析,他們界定出提交所修復(fù)的BUG類型,并將其歸類到相應(yīng)的內(nèi)存安全/線程安全問題中。

內(nèi)存安全問題的分析

這項研究調(diào)查了70個內(nèi)存安全問題。針對于每個問題,研究者仔細的分析了問題出現(xiàn)的根因(cause)和問題導(dǎo)致的效果(effect)。問題根因是通過修改問題時提交的patch代碼來界定的——即編碼的錯誤發(fā)生在哪兒;問題的效果是指代碼運行造成可觀察的錯誤的位置,比如出現(xiàn)緩沖區(qū)溢出的代碼位置。由于從根因到效果有個傳遞過程,這兩者有時候是相隔很遠的。根據(jù)根因和效果所在的代碼區(qū)域不同,研究者將錯誤分為了4類:safe -> safe、safe -> unsafe、unsafe -> safe、unsafe -> unsafe。比如:如果編碼錯誤出現(xiàn)在safe代碼中,但造成的效果體現(xiàn)在unsafe代碼中,那么就歸類為safe -> unsafe。

另一方面,按照傳統(tǒng)的內(nèi)存問題分類,問題又可以分為空間內(nèi)存安全(Wrong Access)和時間內(nèi)存安全(Lifetime Violation)兩大類,進一步可細分為緩沖區(qū)溢出(Buffer overflow)、解引用空指針(Null pointer dereferencing)、訪問未初始化內(nèi)存(Reading uninitialized memory)、錯誤釋放(Invalid free)、釋放后使用(Use after free)、重復(fù)釋放(Double free)等幾個小類。根據(jù)這兩種分類維度,問題的統(tǒng)計數(shù)據(jù)如下:

從統(tǒng)計結(jié)果中可以看出,完全不涉及unsafe代碼的內(nèi)存安全問題只有一個。進一步調(diào)查發(fā)現(xiàn)這個問題出現(xiàn)在Rust早期的v0.3版本中,之后的穩(wěn)定版本編譯器已經(jīng)能攔截這個問題。因此可以說:Rust語言的safe代碼機制能非常有效的避免內(nèi)存安全問題,所有穩(wěn)定版本中發(fā)現(xiàn)的內(nèi)存安全問題都和unsafe代碼有關(guān)。

然而,這并不意味著我們只要檢查所有unsafe代碼段就能有效發(fā)現(xiàn)問題。因為有時候問題根因會出現(xiàn)在safe代碼中,只是效果產(chǎn)生在unsafe代碼段。論文中舉了一個例子:(hi3ms沒有Rust代碼編輯功能,只能拿其他語言湊合下了)

Css代碼

pub fn sign(data: Option<&[u8]>) { let p = match data { Some(data) => BioSlice::new(data).as_ptr(), None => ptr::null_mut(), }; unsafe { let cms = cvt_p(CMS_sign(p)); } }

在這段代碼中,p是raw pointer類型,在safe代碼中,當(dāng)data含有值(Some分支)時,分支里試圖創(chuàng)建一個BioSlice對象,并將對象指針賦給p。然而,根據(jù)Rust的生命周期規(guī)則,新創(chuàng)建的BioSlice對象在match表達式結(jié)束時就被釋放了,p在傳給CMS_sign函數(shù)時是一個野指針。這個例子中的unsafe代碼段沒有任何問題,如果只檢視unsafe代碼,不可能發(fā)現(xiàn)這個釋放后使用的錯誤。對此問題修改后的代碼如下:

Css代碼

pub fn sign(data: Option<&[u8]>) { let bio = match data { Some(data) => Some(BioSlice::new(data)), None => None, }; let p = bio.map_or(ptr::null_mut(),|p| p.as_ptr()); unsafe { let cms = cvt_p(CMS_sign(p)); } }

修改后的代碼正確的延長了bio的生命周期。所有的修改都只發(fā)生在safe代碼段,沒有改動unsafe代碼。 既然問題都會涉及unsafe代碼,那么把unsafe代碼消除掉是否可以避免問題?研究者進一步的調(diào)查了所有BUG修改的策略,發(fā)現(xiàn)大部分的修改涉及了unsafe代碼,但是只有很少的一部分修改完全移除了unsafe代碼。這說明unsafe代碼是不可能完全避免的。

unsafe的價值是什么?為什么不可能完全去除?研究者對600處unsafe的使用目的進行了調(diào)查,發(fā)現(xiàn)其中42%是為了復(fù)用已有代碼(比如從現(xiàn)有C代碼轉(zhuǎn)換成的Rust代碼,或者調(diào)用C庫函數(shù)),22%是為了改進性能,剩下的14%是為了實現(xiàn)功能而繞過Rust編譯器的各種校驗。

進一步的研究表明,使用unsafe的方法來訪問偏移的內(nèi)存(如slice::get_unchecked()),和使用safe的下標(biāo)方式訪問相比,unsafe的速度可以快4~5倍。這是因為Rust對緩沖區(qū)越界的運行時校驗所帶來的,因此在某些性能關(guān)鍵區(qū)域,unsafe的作用不可缺少。

需要注意的是,unsafe代碼段并不見得包含unsafe的操作。研究者發(fā)現(xiàn)有5處unsafe代碼,即使去掉unsafe標(biāo)簽也不會有任何編譯錯誤——也就是說,從編譯器角度它完全可以作為safe代碼。將其標(biāo)為unsafe代碼是為了給使用者提示關(guān)鍵的調(diào)用契約,這些契約不可能被編譯器檢查。一個典型的例子是Rust標(biāo)準(zhǔn)庫中的String::from_utf8_unchecked()函數(shù),這個函數(shù)內(nèi)部并沒有任何unsafe操作,但是卻被標(biāo)為了unsafe。其原因是這個函數(shù)直接從用戶提供的一片內(nèi)存來構(gòu)造String對象,但并沒有對內(nèi)容是否為合法的UTF-8編碼進行檢查,而Rust要求所有的String對象都必須是合法的UTF-8編碼字符串。

也就是說,String::from_utf8_unchecked()函數(shù)的unsafe標(biāo)簽只是用來傳遞邏輯上的調(diào)用契約,這種契約和內(nèi)存安全沒有直接關(guān)系,但是如果違反契約,卻可能導(dǎo)致其他地方(有可能是safe代碼)的內(nèi)存安全問題。這種unsafe標(biāo)簽是不能去除的。

即便如此,在可能的情況下,消除unsafe代碼段確實是個有效的安全改進方法。研究者調(diào)查了130個去掉unsafe的修改記錄,發(fā)現(xiàn)其中43個通過代碼的重構(gòu)把unsafe代碼段徹底改為了safe代碼,剩下的87個則通過將unsafe代碼封裝出safe的接口來保證了安全性。

線程安全問題的分析

這項研究調(diào)查了100個線程安全問題。問題被分為了兩類:阻塞式問題(造成死鎖)和非阻塞式問題(造成數(shù)據(jù)競爭),其中阻塞式問題有59個,之中55個都和同步原語(Mutex和Condvar)有關(guān):

雖然Rust號稱可以進行“無畏并發(fā)”的編程,并且提供了精心設(shè)計的同步原語以避免并發(fā)問題。然而,僅僅用safe代碼就可能導(dǎo)致重復(fù)加鎖造成的死鎖,更糟糕的是,有些問題甚至是Rust的特有設(shè)計所帶來的,在其他語言中反而不會出現(xiàn)。論文中給出了一個例子:

Css代碼

fn do_request() { //client: Arc> match connect(client.read().unwrap().m) { Ok(_) => { let mut inner = client.write().unwrap(); inner.m = mbrs; } Err(_) => {} }; }

這段代碼中,client變量被一個讀寫鎖(RwLock)保護。RwLock的方法read()和write()會自動對變量加鎖,并返回LockResult對象,在LockResult對象生命周期結(jié)束時,自動解鎖。

顯然,該段代碼的作者以為client.read()返回的臨時LockResult對象在match內(nèi)部的匹配分支之前就被釋放并解鎖了,因此在match分支中可以再次用client.write()對其加鎖。但是,Rust語言的生命周期規(guī)則使得client.read()返回的對象的實際生命周期被延長到了match語句結(jié)束,所以該段代碼實際結(jié)果是在read()的鎖還沒有釋放時又嘗試獲取write()鎖,導(dǎo)致死鎖。

根據(jù)生命周期的正確用法,該段代碼后來被修改成了這樣:

Css代碼

fn do_request() { //client: Arc> let result = connect(client.read().unwrap().m); match result { Ok(_) => { let mut inner = client.write().unwrap(); inner.m = mbrs; } Err(_) => {} }; }

修改以后,client.read()返回的臨時對象在該行語句結(jié)束后即被釋放,不會一直加鎖到match語句內(nèi)部。

對于41個非阻塞式問題,其中38個都是因為對共享資源的保護不當(dāng)而導(dǎo)致的。根據(jù)對共享資源的不同保護方法,以及代碼是否為safe,這些問題進一步被分類如下:

38個問題中,有23個發(fā)生在unsafe代碼,15個發(fā)生在safe代碼。盡管Rust設(shè)置了嚴格的數(shù)據(jù)借用和訪問規(guī)則,但由于并發(fā)編程依賴于程序的邏輯和語義,即使是safe代碼也不可能完全避免數(shù)據(jù)競爭問題。論文中給出了一個例子:

Css代碼

impl Engine for AuthorityRound { fn generate_seal(&self) -> Seal { if self.proposed.load() { return Seal::None; } self.proposed.store(true); return Seal::Regular(...); } }

這段代碼中,AuthorityRound結(jié)構(gòu)的proposed成員是一個boolean類型的原子變量,load()會讀取變量的值,store()會設(shè)置變量的值。顯然,這段代碼希望在并發(fā)操作時,只返回一次Seal::Regular(...),之后都返回Seal::None。但是,這里對原子變量的操作方法沒有正確的處理。如果有兩個線程同時執(zhí)行到if語句,并同時讀取到false結(jié)果,該方法可能給兩個線程都返回Seal::Regular(...)。 對該問題進行修改后的代碼如下,這里使用了compare_and_swap()方法,保證了對原子變量的讀和寫在一個不可搶占的原子操作中一起完成。

Css代碼

impl Engine for AuthorityRound { fn generate_seal(&self) -> Seal { if !self.proposed.compare_and_swap(false, true) { return Seal::Regular(...); } return Seal::None; } }

這種數(shù)據(jù)競爭問題沒有涉及任何unsafe代碼,所有操作都在safe代碼中完成。這也說明了即使Rust語言設(shè)置了嚴格的并發(fā)檢查規(guī)則,程序員仍然要在編碼中人工保證并發(fā)訪問的正確性。

對Rust缺陷檢查工具的建議

顯然,從前面的調(diào)查可知,光憑Rust編譯器本身的檢查并不足以避免所有的問題,甚至某些晦澀的生命周期還可能觸發(fā)新的問題。研究者們建議對Rust語言增加以下的檢查工具:

1. 改進IDE。當(dāng)程序員選中某個變量時,自動顯示其生命周期范圍,尤其是對于lock()方法返回的對象的生命周期。這可以有效的解決因為對生命周期理解不當(dāng)而產(chǎn)生的編碼問題。

2. 對內(nèi)存安全進行靜態(tài)檢查。研究者們實現(xiàn)了一個靜態(tài)掃描工具,對于釋放后使用的內(nèi)存安全問題進行檢查。在對參與研究的Rust項目進行掃描后,工具新發(fā)現(xiàn)了4個之前沒有被發(fā)現(xiàn)的內(nèi)存安全問題。說明這種靜態(tài)檢查工具是有必要的。

3. 對重復(fù)加鎖問題進行靜態(tài)檢查。研究者們實現(xiàn)了一個靜態(tài)掃描工具,通過分析lock()方法返回的變量生命周期內(nèi)是否再次加鎖,來檢測重復(fù)加鎖問題。在對參與研究的Rust項目進行掃描后,工具新發(fā)現(xiàn)了6個之前沒有被發(fā)現(xiàn)的死鎖問題。

論文還對動態(tài)檢測、fuzzing測試等方法的應(yīng)用提出了建議。

結(jié)論

1. Rust語言的safe代碼對于空間和時間內(nèi)存安全問題的檢查非常有效,所有穩(wěn)定版本中出現(xiàn)的內(nèi)存安全問題都和unsafe代碼有關(guān)。 2. 雖然內(nèi)存安全問題都和unsafe代碼有關(guān),但大量的問題同時也和safe代碼有關(guān)。有些問題甚至源于safe代碼的編碼錯誤,而不是unsafe代碼。 3. 線程安全問題,無論阻塞還是非阻塞,都可以在safe代碼中發(fā)生,即使代碼完全符合Rust語言的規(guī)則。 4. 大量問題的產(chǎn)生是由于編碼人員沒有正確理解Rust語言的生命周期規(guī)則導(dǎo)致的。 5. 有必要針對Rust語言中的典型問題,建立新的缺陷檢測工具。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3638

    瀏覽量

    94000
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4829

    瀏覽量

    69071
  • Rust
    +關(guān)注

    關(guān)注

    1

    文章

    230

    瀏覽量

    6670

原文標(biāo)題:前沿技術(shù)探討:Rust語言真的安全嗎?

文章出處:【微信號:Huawei_Developer,微信公眾號:華為開發(fā)者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    對稱加密技術(shù)實際應(yīng)用中如何保障數(shù)據(jù)安全

    對稱加密技術(shù)實際應(yīng)用中保障數(shù)據(jù)安全主要通過以下幾個方面: 密鑰的安全性: 對稱加密的安全性高度依賴于密鑰的保密
    的頭像 發(fā)表于 12-16 13:59 ?246次閱讀

    電池的安全性測試項目有哪些?

    電池的安全性測試是保證電池實際使用過程中穩(wěn)定、安全的重要手段。通過一系列嚴格的測試項目,能夠有效評估電池
    的頭像 發(fā)表于 12-06 09:55 ?666次閱讀
    電池的<b class='flag-5'>安全性</b>測試<b class='flag-5'>項目</b>有哪些?

    電池安全性測試關(guān)鍵:圓柱與軟包電池測試設(shè)備指南

    機、過充/過放測試儀、熱失控測試儀、電池短路測試儀以及壓力測試機等。通過這些儀器的配合使用,可以全面檢測電池的安全性、可靠,確保電池實際應(yīng)用中的穩(wěn)定性和
    的頭像 發(fā)表于 12-06 09:35 ?364次閱讀
    電池<b class='flag-5'>安全性</b>測試關(guān)鍵:圓柱與軟包電池測試設(shè)備指南

    Parker派克防爆電機實際應(yīng)用中的安全性能如何保證?

    Parker防爆電機通過防爆外殼、國際安全標(biāo)準(zhǔn)、專用防爆認證、低火花設(shè)計、定制化繞組、應(yīng)用案例驗證及溫度管理,確保實際應(yīng)用中的安全性能,防止爆炸風(fēng)險,保障安全
    的頭像 發(fā)表于 11-21 10:58 ?160次閱讀
    Parker派克防爆電機<b class='flag-5'>在</b><b class='flag-5'>實際</b>應(yīng)用中的<b class='flag-5'>安全性</b>能如何保證?

    電氣安裝中通過負載箱實現(xiàn)最大效率和安全性

    電氣安裝中,負載箱是一種常用的設(shè)備,主要用于模擬實際的電力負載,以便進行各種電氣設(shè)備的測試和調(diào)試。通過負載箱,可以實現(xiàn)最大效率和安全性,從而提高電氣設(shè)備的運行性能和使用壽命。 負載箱可以實現(xiàn)最大
    發(fā)表于 11-20 15:24

    智能系統(tǒng)的安全性分析

    智能系統(tǒng)的安全性分析是一個至關(guān)重要的過程,它涉及多個層面和維度,以確保系統(tǒng)各種情況下都能保持安全、穩(wěn)定和可靠。以下是對智能系統(tǒng)安全性的分析: 一、數(shù)據(jù)
    的頭像 發(fā)表于 10-29 09:56 ?322次閱讀

    固態(tài)電池安全性怎么樣

    固態(tài)電池安全性方面表現(xiàn)出顯著的優(yōu)勢,這主要得益于其獨特的固態(tài)電解質(zhì)結(jié)構(gòu)。以下是對固態(tài)電池安全性的詳細分析:
    的頭像 發(fā)表于 09-15 11:47 ?932次閱讀

    未來嵌入式系統(tǒng)的黃金搭檔 MCX N947遇上Rust

    基于 Rust安全性和性能引入了 RustRust很多優(yōu)勢,內(nèi)存安全、并發(fā)
    的頭像 發(fā)表于 07-25 09:14 ?1416次閱讀
    未來嵌入式系統(tǒng)的黃金搭檔 MCX N947遇上<b class='flag-5'>Rust</b>

    請問DM平臺訪問安全性如何控制?

    DM平臺訪問安全性如何控制?
    發(fā)表于 07-25 06:10

    NFC風(fēng)險與安全性:揭示NFC技術(shù)高安全性的真相

    在數(shù)字化日益普及的今天,NFC(近場通信)技術(shù)因其便捷和高效廣泛應(yīng)用。然而,當(dāng)提及NFC時,一些人可能會聯(lián)想到潛在的風(fēng)險。本文將深入探討NFC風(fēng)險,并強調(diào)其高安全性的特性,揭示
    的頭像 發(fā)表于 06-29 13:03 ?1759次閱讀

    藍牙模塊的安全性與隱私保護

    藍牙模塊作為現(xiàn)代無線通信的重要組成部分,智能家居、可穿戴設(shè)備、健康監(jiān)測等多個領(lǐng)域得到了廣泛應(yīng)用。然而,隨著藍牙技術(shù)的普及,其安全性和隱私保護問題也日益凸顯。本文將探討藍牙模塊在數(shù)
    的頭像 發(fā)表于 06-14 16:06 ?628次閱讀

    開關(guān)電源安全性測試項目有哪些?如何測試?

    總結(jié)而言,通過對開關(guān)電源進行過壓保護、過流保護、短路保護、絕緣電阻測試、高壓測試以及溫升測試等一系列全面的安全性檢測,可以充分評估電源的可靠安全性和穩(wěn)定性。NSAT-8000電源測試系統(tǒng)提供了
    的頭像 發(fā)表于 05-23 17:41 ?1057次閱讀
    開關(guān)電源<b class='flag-5'>安全性</b>測試<b class='flag-5'>項目</b>有哪些?如何測試?

    M8_6pin公頭安全性怎樣

    德索工程師說道M8_6pin公頭安全性方面表現(xiàn)出色。它嚴格按照電氣安全標(biāo)準(zhǔn)進行設(shè)計,具有優(yōu)異的電氣性能。額定電壓和額定電流是評價插頭電氣安全性
    的頭像 發(fā)表于 05-05 13:46 ?305次閱讀
    M8_6pin公頭<b class='flag-5'>安全性</b>怎樣

    Rust效率領(lǐng)先C++兩倍,內(nèi)存安全成國家安全議題

    這項發(fā)現(xiàn)由谷歌安卓平臺工具及庫的工程總監(jiān)Lars Bergstrom日前召開的Rust Nation英國峰會揭示。盡管此前業(yè)內(nèi)對Rust安全性和穩(wěn)定性存在一定爭議,特別是其‘uns
    的頭像 發(fā)表于 04-01 15:37 ?993次閱讀

    谷歌捐款100萬美元給Rust基金會,以增強C++與Rust的交互

    如今,谷歌多項核心業(yè)務(wù)仍以 C++為主要編程語言,雖然無法直接使用Rust替代現(xiàn)有的C++程序,但谷歌依然選擇支持Rust基金會的“Interop Initiative”計劃,幫助那些選用C++的機構(gòu)更為順暢地過渡至
    的頭像 發(fā)表于 02-19 15:41 ?708次閱讀
    主站蜘蛛池模板: 欧美精品国产第一区二区 | 久久影院午夜伦手机不四虎卡 | 波多久久夜色精品国产 | 国产精品片 | 亚洲精品理论 | 狠狠色噜噜狠狠狠狠97老肥女 | 日韩精品在线第一页 | ts在线视频| 男人操女人视频在线观看 | 国产日日操 | 天堂bt在线种子网 | 亚洲色图偷窥自拍 | 中国色老头 | 亚洲欧洲一区二区三区在线 | 四虎海外在线永久免费看 | 欧美黄视频在线观看 | 亚洲四虎永久在线播放 | 国产3p在线播放 | 午夜精品一区二区三区在线视 | 国产久视频 | 操的好爽 | 女同性进行性行为视频 | 免费看久久 | 欧美操操操操 | 午夜精品在线免费观看 | 狠狠做深爱婷婷久久一区 | 黄黄网站| 亚洲人成电影在线 | 欧美三级一区二区三区 | 亚洲成色www久久网站 | 国产农村三片免费网站 | 操狠狠| 日本高清一区二区三区不卡免费 | 一本在线免费视频 | 噜噜噜色网 | www.五月婷婷.com| 日本欧洲亚洲一区在线观看 | 国产三级在线免费 | 免费观看午夜在线欧差毛片 | 深爱婷婷激情网 | 伊人久久大香线蕉综合爱婷婷 |