一、Android沿用Linux權限模型
沙箱,對使用者來說可以理解為一種安全環境,對惡意訪問者來說是一種限制。
在Android系統中,應用(通常)都在一個獨立的沙箱中運行,即每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。Dalvik經過優化,允許在有限的內存中同時高效地運行多個虛擬機的實例,並且每一個Dalvik應用作為一個獨立的Linux進程執行。Android這種基於Linux的進程“沙箱”機制,是整個安全設計的基礎之一。
Android從Linux繼承了已經深入人心的類Unix進程隔離機制與最小權限原則,同時結合移動終端的具體應用特點,進行了許多有益的改進與提升。具體而言,進程以隔離的用戶環境運行,不能相互干擾,比如發送信號或者訪問其他進程的內存空間。因此,Android沙箱的核心機制基於以下幾個概念:標准的Linux進程隔離、大多數進程擁有唯一的用戶ID(UID),以及嚴格限制文件系統權限。
Android系統沿用了Linux的UID/GID權限模型,即用戶ID和用戶組ID,但並沒有使用傳統的passwd和group文件來存儲用戶與用戶組的認證憑據,作為替代,Android定義了從名稱到獨特標識符Android ID(AID)的映射表。初始的AID映射表包含了一些與特權用戶及系統關鍵用戶(如system用戶/用戶組)對應的靜態保留條目。
除了AID,Android還使用了輔助用戶組機制,以允許進程訪問共享或受保護的資源。例如,sdcard_rw用戶組中的成員允許進程讀寫/sdcard目錄,因為它的加載項規定了哪些用戶組可以讀寫該目錄。這與許多Linux發行版中對輔助用戶組機制的使用是類似的。除了用來實施文件系統訪問,輔助用戶組還會被用於向進程授予額外的權限。權限是關於允許或限制應用程序(而不是用戶)訪問設備資源。
Android擴展了Linux內核安全模型的用戶與權限機制,將多用戶操作系統的用戶隔離機制巧妙地移植為應用程序隔離。在linux中,一個用戶標識(UID)識別一個給定用戶;在Android上,一個UID則識別一個應用程序。在安裝應用程序時向其分配UID。應用程序在設備上存續期間內,其UID保持不變。僅限用於允許或限制應用程序(而非用戶)對設備資源的訪問。如此,Android的安全機制與Linux內核的安全模型完美銜接!不同的應用程序分別屬於不同的用戶,因此,應用程序運行於自己獨立的進程空間,與UID不同的應用程序自然形成資源隔離,如此便形成了一個操作系統級別的應用程序“沙箱”。
二、Android沙箱模型
1、應用程序在獨立的進程
應用程序進程之間,應用程序與操作系統之間的安全性由Linux操作系統的標准進程級安全機制實現。在默認狀態下,應用程序之間無法交互,運行在進程沙箱內的應用程序沒有被分配權限,無法訪問系統或資源。因此,無論是直接運行於操作系統之上的應用程序,還是運行於Dalvik虛擬機的應用程序都得到同樣的安全隔離與保護,被限制在各自“沙箱”內的應用程序互不干擾,對系統與其他應用程序的損害可降至最低。Android應用程序的“沙箱”機制如下圖 1,互相不具備信任關系的應用程序相互隔離,獨自運行,箭頭訪問是禁止的:
圖 1.應用程序在獨立的進程
Android 是一個多用戶系統,每個應用是一個獨立的用戶。系統為每個應用分配一個唯一的用戶標識(UID),並為應用中所有文件設置該用戶才能訪問的權限。每個進程中有一個獨立的VM。每個應用在自己的進程中運行,應用的組件需要執行時,系統創建該進程;當系統內存不存時,系統會銷毀該進程。
2、應用程序在同一個進程(共享UID)
Android 應用程序運行在它們自己的 Linux 進程上,並被分配一個惟一的用戶 ID。默認情況下,運行在基本沙箱進程中的應用程序沒有被分配權限,因而防止了此類應用程序訪問系統或資源。但是 Android 應用程序可以通過應用程序的 manifest 文件請求權限。
通過做到以下兩點,Android 應用程序可以允許其他應用程序訪問它們的資源:
(1)聲明適當的 manifest 權限;
(2)與其他受信任的應用程序運行在同一進程中,從而共享對其數據和代碼的訪問。
在很多情況下,源自同一開發者或同一開發機構的應用程序,相互間存在信任關系。Android系統提供一種所謂共享UID(SharedUserID)機制,使具備信任關系的應用程序可以運行於同一進程空間。通常 ,這種信任關系由應用程序的數字簽名確定,並且需要應用程序在manifest文件中使用相同的UID。共享UID的應用程序進程空間如下圖:
圖 2.應用程序共享UID
不同的應用程序可以運行在相同的進程中。對於此方法,首先必須使用相同的私鑰簽署這些應用程序,然后必須使用 manifest 文件給它們分配相同的 Linux 用戶 ID,這可以通過用相同的值/名定義 manifest 屬性 android:sharedUserId 來做到。通過sharedUserId,擁有同一個User id的多個APK安裝包可以配置成運行在同一個進程中.所以默認就是可以互相訪問任意數據. 也可以配置成運行成不同的進程, 同時可以訪問其他APK的數據目錄下的數據庫和文件.就像訪問本程序的數據一樣。這樣就為同一個機構發開的不同App之間的數據共享,提供了便利。