1. 程式人生 > >淺入淺出 Android 安全: Android Linux 核心層安全

淺入淺出 Android 安全: Android Linux 核心層安全

轉載:https://www.jianshu.com/p/ac84963b9e48

 

來源:Yury Zhauniarovich | Publications

譯者:飛龍

協議:CC BY-NC-SA 4.0

作為最廣為人知的開源專案之一,Linux 已經被證明是一個安全,可信和穩定的軟體,全世界數千人對它進行研究,攻擊和打補丁。 不出所料,Linux 核心是 Android 作業系統的基礎[3]。 Android 不僅依賴於 Linux 的程序,記憶體和檔案系統管理,它也是 Android 安全架構中最重要的元件之一。 在 Android 中,Linux 核心負責配置應用沙盒,以及規範一些許可權。

2.1 應用沙盒

讓我們考慮一個 Android 應用安裝的過程。 Android 應用以 Android 軟體包(.apk)檔案的形式分發。 一個包由 Dalvik 可執行檔案,資源,本地庫和清單檔案組成,並由開發者簽名來簽名。 有三個主要媒介可以在 Android 作業系統的裝置上安裝軟體包:

  • Google Play
  • 軟體包安裝程式
  • adb install 工具

Google Play 是一個特殊的應用,它為使用者提供查詢由第三方開發人員上傳到市場的應用,以及安裝該應用的功能。雖然它也是第三方應用,但 Google Play 應用(因為使用與作業系統相同的簽名進行簽名)可訪問 Android 的受保護元件,而其他第三方應用則缺少這些元件。如果使用者從其他來源安裝應用,則通常隱式使用軟體包安裝程式。此係統應用提供了用於啟動軟體包安裝過程的介面。由 Android 提供的adb install

工具主要由第三方應用開發人員使用。雖然前兩個媒介需要使用者在安裝過程中同意權限列表,但後者會安靜地安裝應用。這就是它主要用於開發工具的原因,旨在將應用安裝在裝置上進行測試。該過程如圖 2.1 的上半部分所示。此圖顯示了 Android 安全體系結構的更詳細的概述。我們將在本文中參考它來解釋這個作業系統的特性。

在 Linux 核心層配置應用沙箱的過程如下。 在安裝過程中,每個包都會被分配一個唯一的使用者識別符號(UID)和組識別符號(GID),在裝置的應用生命週期內不會更改。 因此,在 Android 中每個應用都有一個相應的 Linux 使用者。 使用者名稱遵循格式app_x,並且該使用者的 UID 等於Process.FIRST_APPLICATION_UID + x

,其中Process.FIRST_APPLICATION_UID常量對應於10000。例如,在圖 2.1 中,ex1.apk包在安裝期間獲得了使用者名稱app 1,UID 等於 10001

在 Linux 中,記憶體中的所有檔案都受 Linux 自定義訪問控制(DAC)的約束。訪問許可權由檔案的建立者或所有者為三種使用者型別設定:檔案的所有者,與所有者在同一組中的使用者和所有其他使用者。對於每種型別的使用者,分配讀,寫和執行(r-w-x)許可權的元組。因此,因為每個應用都有自己的 UID 和 GID,Linux 核心強制應用在自己的隔離地址空間內執行。除此之外,應用唯一的 UID 和 GID 由 Linux 核心使用,以實現不同應用之間的裝置資源(記憶體,CPU 等)的公平分離。安裝過程中的每個應用也會獲得自己的主目錄,例如/data/data/package_name,其中package_name是 Android 軟體包的名稱,例如com.ex.ex1,在 Android 中,這個資料夾是內部儲存目錄,其中應用將私有資料放在裡面。分配給此目錄的 Linu x 許可權只允許“所有者”應用寫入並讀取此目錄。有一些例外應該提到。使用相同證書籤名的應用能夠在彼此之間共享資料,可以擁有相同的 UID 或甚至可以在相同的程序中執行。

這些架構決策在 Linux 核心層上建立了高效的應用沙箱。 這種型別的沙箱很簡單,並基於 Linux 可選訪問控制模型(DAC)的驗證。 幸運的是,因為沙盒在 Linux 核心層上執行,原生代碼和作業系統應用也受到本章[3]中所描述的這些約束的約束。

2.2 Linux 核心層上的許可權約束

通過將 Linux 使用者和組所有者分配給實現此功能的元件,可以限制對某些系統功能的訪問。 這種型別的限制可以應用於系統資源,如檔案,驅動程式和套接字。 Android 使用檔案系統許可權和特定的核心補丁(稱為 Paranoid Networking)[13]來限制低階系統功能的訪問,如網路套接字,攝像機裝置,外部儲存器,日誌讀取能力等。

使用檔案系統許可權訪問檔案和裝置驅動程式,可以限制程序對裝置某些功能的訪問。例如,這種技術被應用於限制應用對裝置相機的訪問。 /dev/ cam裝置驅動程式的許可權設定為0660,屬於root所有者和攝像機所有者組。這意味著只有以root身份執行或包含在攝像機組中的程序才能讀取和寫入此裝置驅動程式。因此,僅包括在相機組中的應用程式可以與相機互動。許可權標籤和相應組之間的對映在檔案框架/base/data/etc/platform.xml中定義,摘錄如清單 2.1 所示。因此,在安裝過程中,如果應用程式已請求訪問攝像機功能,並且使用者已批准該應用程式,則還會為此應用程式分配一個攝像機 Linux 組 GID(請參閱清單 2.1 中的第 8 行和第 9 行)。因此,此應用程式可以從/dev/cam裝置驅動程式讀取資訊。

1 ...
 2 <permissions> 
 3 ...
 4 <permission name=”android.permission.INTERNET” > 
 5 <group gid=”inet” /> 
 6 </permission> 
 7 
 8 <permission name=”android.permission.CAMERA” > 
 9 <group gid=”camera” /> 
10 </permission> 
11 
12 <permission name=”android.permission.READ_LOGS” > 
13 <group gid=”log” />
14 </permission> 
15 ...
16 </permissions>

作者:ApacheCN_飛龍
連結:https://www.jianshu.com/p/ac84963b9e48
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

Android 中有一些地方可以用於設定檔案、驅動和 Unix 套接字的檔案系統許可權:init程式,init.rc配置檔案,ueventd.rc配置檔案和系統 ROM 檔案系統配置檔案。 它們在第 3 章中會詳細討論。

在傳統的 Linux 發行版中,允許所有程序啟動網路連線。 同時,對於移動作業系統,必須控制對網路功能的訪問。 為了在 Android 中實現此控制,需要新增特殊的核心補丁,將網路設施的訪問限制於屬於特定 Linux 組或具有特定 Linux 功能的程序。 這些針對 Android 的 Linux 核心補丁已經獲得了 Paranoid 網路的名稱。 例如,對於負責網路通訊的AF_INET套接字地址族,此檢查在kernel/net/ipv4/af_inet.c檔案中執行(參見清單 2.2 中的程式碼片段)。 Linux 組和 Paranoid 網路的許可權標籤之間的對映也在platform.xml檔案中設定(例如,參見清單 2.1 中的第 4 行)。

 

1 ...
 2 #ifdef CONFIG_ANDROID_PARANOID_NETWORK 
 3 #include <linux/android_aid.h> 
 4 
 5 static inline int current_has_network ( void ) 
 6 { 
 7   return in_egroup_p (AID_INET) || capable (CAP_NET_RAW) ; 
 8 } 
 9 #else 
10 static inline int current_has_network ( void ) 
11 { 
12   return 1; 
13 } 
14 #endif 
15 ... 
16 
17 /* 
18 * Create an inet socket . 
19 */ 
20 
21 static int inet create ( struct net *net , struct socket *sock , int protocol , 
22                          int kern ) 
23 { 
24   ...
25   if (!current_has_network() ) 
26     return −EACCES; 
27   ...
28 }

作者:ApacheCN_飛龍
連結:https://www.jianshu.com/p/ac84963b9e48
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

類似的 Paranoid 網路補丁也適用於限制訪問 IPv6 和藍芽[19]。

這些檢查中使用的常量在核心中硬編碼,並在kernel/include/linux/android_aid.h檔案中規定(參見清單 2.3)。

1 ...
 2 #ifndef LINUX_ANDROID_AID_H 
 3 #define LINUX_ANDROID_AID_H 
 4 
 5 /* AIDs that the kernel treats differently */ 
 6 #define AID_OBSOLETE_000 3001 /* was NET_BT_ADMIN */ 
 7 #define AID_OBSOLETE_001 3002 /* was NET_BT */ 
 8 #define AID_INET 3003 
 9 #define AID_NET_RAW 3004 
10 #define AID_NET_ADMIN 3005 
11 #define AID_NET_BW_STATS 3006 /* read bandwidth statistics */ 
12 #define AID_NET_BW_ACCT 3007 /* change bandwidth statistics accounting */ 
13 
14 #endif

作者:ApacheCN_飛龍
連結:https://www.jianshu.com/p/ac84963b9e48
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。


因此,在 Linux 核心層,通過檢查應用程式是否包含在特殊預定義的組中來實現 Android 許可權。 只有此組的成員才能訪問受保護的功能。 在應用程式安裝期間,如果使用者已同意所請求的許可權,則該應用程式包括在相應的 Linux 組中,因此獲得對受保護功能的訪問。