Android Binder機制淺析

來源:互聯網
上載者:User

標籤:

Binder是Android上一種IPC機制,重要且較難理解。由於Linux上標準IPC在靈活和可靠性存在一定不足,Google基於OpenBinder的設計和構想實現了Binder。

本文只簡單介紹其實現,並重點討論Binder安全相關的內容。詳細的Binder設計與實現分析,參考附錄4篇文章。

一、Binder 實現

Android Binder由Client、Server、Service Manager和Binder驅動4個組件組成,引自網路。

在類UNIX系統中,進程是相互獨立的,一個進程不能訪問另一個進程的記憶體空間。然而核心控制著所有進程,因此可以暴露一個介面用作IPC。在Binder中這個介面就是/dev/binder裝置,該裝置由Binder核心驅動程式實現。

Binder驅動是整個Binder架構的核心,所有IPC都通過它來實現。

的Client與Server可以看作2個進程,其IPC通過對/dev/binder的ioctl實現。從Android源碼可以看到,ioctl使用binder_write_read的結構體收發資料。

其中write_buffer包含驅動要執行的命令,read_buffer包含使用者層需要執行的命令:

binder_write實現對bs->fd的ioctl()操作:

bs->fd是開啟/dev/binder得到的檔案描述符:

實際資料如何在進程間傳輸呢?

Binder驅動管理著每個進程的一部分地址空間。Binder管理的記憶體,對於進程是唯讀,其寫操作由核心模組實施。當一個進程向另一個進程發送訊息時,核心在目標進程的記憶體空間申請一部分空間,接著直接將資料從發送進程複製進去。然後它將接收訊息的具體位置,通過一個短訊息通知給接收進程。因為訊息在接收者的記憶體空間,接收者可以直接存取到訊息。當進程不再需要這個資料時,它通知Binder驅動來釋放這一記憶體塊。

可以發現,資料經過了一次複製,所以Binder的效率不如共用記憶體。

Android中更高層次的IPC抽象,如Intent(跨進程組件間傳遞帶有關聯資料的命令),Messenger(支援跨進程訊息通訊的對象),ContentProvider(暴露跨進程資料管理介面的組件),均是基於Binder實現的。

二、Binder 安全

展示Binder IPC架構的一個簡單例子。

每個通過Binder架構實現IBinder介面,允許被訪問調用的對象都可被稱作Binder對象。對Binder對象的調用在一個Binder交易處理(transaction)內部實現,其中包括一個對目標對象的引用、需執行方法的ID和一個資料緩衝區。

Binder驅動會將調用進程的ID(PID)和有效使用者ID(EUID)自動添加到交易處理資料。被調用進程可以檢查PID和EUID,然後基於內部實現邏輯來決定是否執行所請求的方法。

因為PID和EUID是由核心填寫的,所以調用者進程不能通過偽造身份標識來擷取超出系統允許的許可權。這是Android安全模型的核心之一,所有更高層次抽象,比如許可權,均是建立在它之上。調用者的PID和EUID通過類android.os.Binder的getCallingPid()和getCallingUid()來訪問,他們是Android公開API的一部分。

三、Binder 令牌

Binder對象的一個重要屬性是它具有跨進程、獨一無二的身份標識。因此如果進程A建立了一個Binder對象,然後將之傳遞給進程B,進程B再將之傳遞給進程C,那麼對這3個進程的調用,均由同一個Binder對象處理。實際上,進程A會通過記憶體位址直接引用Binder對象,而進程B和C使用Binder對象的控制代碼。

核心負責維護活動的Binder對象與它們在其他進程中的控制代碼之間的映射關係。因為一個Binder的標誌符是獨一無二的,並且由核心負責維護,所以使用者空間進程除非通過IPC機制處理,否則不可能建立一個Binder對象的副本或擷取相關引用(後面介紹如何獲得Binder對象引用)。因此Binder對象是唯一的、不可偽造的、可通訊的對象,可以作為安全性權杖使用。

這也使得Android可以使用基於權能的安全模型(capability-based security)。

基於權能的安全模型中,通過賦予程式一個不可偽造的權能,授權程式對特定資源的存取權限。在Android中,Binder對象可以表示權能。

在這種使用方式下,Binder對象又被稱作Binder令牌(Binder Token)。一個Binder令牌可以是一種權能,也可以是一個目標資源。一個進程擁有一個Binder令牌,授權該進程對Binder對象的完全存取控制許可權,從而使其能夠在目標對象上執行Binder交易處理操作。如果Binder對象實現了多個動作(基於Binder交易處理的code參數,選擇要執行的動作),只要調用者擁有一個Binder對象的引用,就可以執行任意操作。如果需要更細粒度的存取控制,那麼每個操作需要相應實現必要的許可權檢查,這通常利用調用者進程的PID和EUID來實現。

以上看到,擷取了Binder對象引用(Binder令牌)後,就擷取了目標Binder對象的完整存取,如果Binder交易處理操作涉及敏感動作,這是危險的。  

在Android中,通常對於system(UID 10000)或root(UID 0)許可權下啟動並執行調用進程,允許執行所有操作,而對於其他進程要執行額外的許可權檢查。因此控制對一個重要Binder對象的訪問,有2種方式:一是通過限制誰可以獲得Binder對象的引用,另一個是執行該Binder對象動作前,檢查調用者的身份標誌(需要Binder對象自己實現)。

Binder對象可以沒有其他功能實現,只被作為權能使用。這種模式下,多個協作進程可同時擁有同一個Binder對象,而作為服務端的進程(處理用戶端請求)使用Binder令牌來驗證它的用戶端,就像Web伺服器使用會話Cookie一樣。

四、Binder 對象訪問

出於安全考慮,Android控制著對Binder對象的訪問,與Binder對象通訊的唯一方法是使用該對象的引用。但很多Binder對象需要被全域訪問的(尤其是系統服務)。分發所有Binder對象到每個進程是不切實際的,所以需要一種機制,來允許進程主動發現和擷取這些Binder對象的引用。

Android使用servicemanger原生守護進程實現了這種發現機制。

servicemanger先於系統服務啟動,因此系統服務在啟動時,傳遞服務名和一個Binder對象引用到servicemanger進行註冊。一旦註冊成功,任何用戶端都可以通過服務名擷取它的Binder對象引用。然而大部分系統服務有額外的許可權檢查,所以獲得引用不能自動確保對它所有功能的訪問。

同時因為在servicemanger上註冊後,任何人都可以訪問該Binder對象引用,所以出於安全考慮,只有一部分在白名單內的系統進程才可以註冊為系統服務。

可以通過service list命令查看登入系統服務列表,該命令返回每個登入服務的名稱和實現的IBinder介面。

五、附錄

Android處理序間通訊(IPC)機制Binder簡要介紹和學習計劃

Android深入淺出之Binder機制

Android Bander設計與實現 - 設計篇

Android Binder設計與實現 - 實現篇

Android Binder機制淺析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.