標籤:
原文地址:http://android-developers.blogspot.com/2016/05/hardening-media-stack.html
Posted by Dan Austin and Jeff Vander Stoep, Android Security team
為了使Android更加安全,我們鼓勵並獎勵那些發現漏洞的研究者。2015年,Google修複了mediaserver’s libstagefright的一系列bug。我們在2015年8月和9月的security bulletin上發布了這些問題的更新。
除了每個月基本的解決問題外,我們也在做一個新的安全功能,以強化現有的安全模型,並提供額外的深度防禦。這些防禦措施試圖達到兩個目的:
- Prevention:修複bug,防止它們變成漏洞
- Containment:隔離那些處理不受信任內容的組件,以保護系統
Preventionlibstagefright中發現的大部分漏洞都是由無符號整型溢出引起的堆溢出。一些的整型溢出使得攻擊者可以分配一個比實際到達資料所需要空間小的緩衝區,從而引起堆的緩衝區溢位。
無符號整型溢出造成的結果是非常明確的,但隨後引發的行為可能是不期望的或者不安全的。相比之下,在C/C++中,有符號整型溢出被認為是不明確的行為,這意味著溢出造成的後果是沒保證的,並且編譯器的作者通常會從引發的後果中選擇一個最快或最簡單的。我們對編譯器做出修改,使得編譯器在有符號和無符號整型溢出時都能提供一個更安全的預設結果。
UndefinedBehaviorSanitizer(UBSan)是LLVM/Clang 編譯器工具鏈的一部分,用於檢測那些未定義的或意料之外的行為。UBSan會檢查多種類型的未定義和不安全行為,包括有符號和無符號整型溢出。這些檢測會將代碼添加到可運行檔案中,在運行時檢測整型溢出。例如,圖1展示的是原研究人員打上補丁後的libstagefright的MPEG4Extractor控制項的parseChunk函數的原始碼。這次修改,包含在圖中的黑色框中,看起來防止了整型溢出。很不幸的是,SIZE_MAX和size是32位值,chunk_size是64位值,這造成不完全檢測和潛在的整型溢出。在紅色框中,size和chunk_size的加法可能引起整型溢出,並建立了一個比size元素小的緩衝區。隨後的memcpy操作可能導致可用記憶體的崩潰,因為藍色框中的size+chunk_size可能會小於size。關於這個漏洞的潛在利用向量的機制的詳細描述,請看Project Zero。
圖1:原始碼展示了一個微妙的無符號整型溢出
圖2將上面的程式碼片段產生的組合語言與通過integer sanitization enabled編譯的第二版本做了對比。圖2紅框中是引起整型溢出的加法操作。
在unsanitized版本中,size(R6)和chunk_size(R7)相加,有可能會導致R0溢出且小於size。本該按size分配的緩衝區被指定為R0的大小,然後size個位元被拷貝進去R0大小的緩衝區。如果R0小於size(R6),這會引起記憶體崩潰。
在sanitized版本中,size(R7)和chunk_size(R5)相加,並把結果儲存到R0。然後,R0和R7比較,如果R0小於R7,程式會指向CC情況的代碼,R3被設為1。如果R3為1,且設定了執行位,那麼發生記憶體溢出,並且觸發異常終止,從而避免記憶體崩潰。
注意,由補丁引發的不完全檢測並不包含在圖2中。溢出發生在緩衝區分配時的加法操作。sanitized版本中增加的觸發操作,把可被利用的漏洞轉化為無害的異常終止。
雖然整型sanitizer原本是作為代碼清潔工具的,它們有效阻止大部分已知的libstagefright漏洞。啟動整型溢出檢查只是第一步。找出並修複整型溢出(大部分是不可被利用的),以防止運行時異常終止,這體現了Android`s media team的努力。大部分被發現的溢出都被修複,剩餘的(主要是效能的原因)被確認和標記為安全的,以防止運行時異常終止。
在Android N中,在整個media stack中都可以進行有符號和無符號整型溢出的檢測,這就包括了libstagefright。這使得利用整型溢出變得更困難,同時也可以防止將來會引進新的整型溢出Bug。
Containment在Android M和更早的版本,mediaserver進程負責大部分和多媒體相關的任務。這以為它要訪問所有和這些任務相關的許可權,儘管它運行在它自己的沙箱中,但它仍需要訪問大量的資源和功能。這就是為什麼2015年時libstagefright Bug具有重大意義——mediaserver可以訪問Android裝置上一些重要的資源,包括相機,麥克風,顯卡,電話,藍芽以及網路。
根源分析表示libstagefright Bug主要發生在解析檔案格式和多媒體解碼器的代碼中。這並不奇怪,解析複雜檔案格式和編碼器試圖加速是很困難的,大量的邊緣情況使得代碼容易受到偶然的和惡意的畸形輸入攻擊。
然而,多媒體解析器不需要訪問大部分mediaserver持有的許可權。基於這個原因,media ream重新設計了Android N的mediaserver,使得它更好的遵循最少特權原則。圖3展示了整塊mediaserver和它的許可權被如何分割,這種分割是基於下面的方法:
- 解析代碼被移進持有很少或沒有許可權的非特權沙箱
- 需要敏感許可權的組件被移進了分離沙箱,這個沙箱只能訪問該組件所需要的特定資源。例如,只有cameraserver可能訪問相機,只有audioserver可能訪問藍芽,只有drmserver可能訪問DRM資源。
將Android N和更早期版本做對比,libstagefright Bug帶來的潛在影響展示了這種策略的價值。在取得libstagefright可執行代碼前允許整塊mediaserver訪問所有的許可權和可用資源(包括顯卡驅動,相機驅動,sockets等),會暴露大範圍的核心攻擊面。
在Android N中,libstagefright運行在只能訪問非常少許可權的多媒體編碼器沙箱中。SELinux阻止對相機、麥克風、圖片、電話、藍芽、網路的訪問和動態代碼的載入。Seccomp進一步限制與核心的互動。這意味著libstagefright通過減少核心暴露的攻擊面,使得攻擊者能訪問的許可權更少,也減緩了特權增加。
Conclusion這個多媒體強化項目是一場持續不斷的努力,它集中於把功能移進低許可權的沙箱,並進一步減少授予這些沙箱的許可權。雖然這裡討論的技術被用在Android 多媒體架構,但它同時適用於Android程式碼程式庫。這些強化技術或其他技術,正在積極地應用於Android的其他組件。
Hardening the media stack