Android 安全機制2 沙箱機制
阿新 • • 發佈:2019-02-08
Android 系統沿用了Linux系統的UID/GID(使用者組ID)的許可權模型,但是並沒有使用Linux傳統的passwd和group檔案來儲存使用者與使用者組的
憑證資訊,作為替代,Android定義了從名稱到獨特識別符號的Android ID(AID)對映表。初始的對映表中定義了一些特權使用者和一些系統關
鍵使用者。並且保留了一段AID範圍,用於提供給原生應用作為UID。
下面是從原始碼中擷取的預定義的系統特權使用者和使用者組:(system/core/include/private/android_filesystem_config.h)
/* This is the master Users and Groups config for the platform.
* DO NOT EVER RENUMBER
*/
#define AID_ROOT 0 /* traditional unix root user */
#define AID_SYSTEM 1000 /* system server */
#define AID_RADIO 1001 /* telephony subsystem, RIL */
#define AID_BLUETOOTH 1002 /* bluetooth subsystem */
#define AID_GRAPHICS 1003 /* graphics devices */
#define AID_INPUT 1004 /* input devices */
#define AID_AUDIO 1005 /* audio devices */
#define AID_CAMERA 1006 /* camera devices */
#define AID_LOG 1007 /* log devices */
#define AID_COMPASS 1008 /* compass device */
#define AID_MOUNT 1009 /* mountd socket */
#define AID_WIFI 1010 /* wifi subsystem */
#define AID_ADB 1011 /* android debug bridge (adbd) */
#define AID_INSTALL 1012 /* group for installing packages */
#define AID_MEDIA 1013 /* mediaserver process */
#define AID_DHCP 1014 /* dhcp client */
#define AID_SDCARD_RW 1015 /* external storage write access */
#define AID_VPN 1016 /* vpn system */
#define AID_KEYSTORE 1017 /* keystore subsystem */
#define AID_USB 1018 /* USB devices */
#define AID_DRM 1019 /* DRM server */
#define AID_MDNSR 1020 /* MulticastDNSResponder (service discovery) */
#define AID_GPS 1021 /* GPS daemon */
#define AID_UNUSED1 1022 /* deprecated, DO NOT USE */
#define AID_MEDIA_RW 1023 /* internal media storage write access */
#define AID_MTP 1024 /* MTP USB driver access */
#define AID_UNUSED2 1025 /* deprecated, DO NOT USE */
#define AID_DRMRPC 1026 /* group for drm rpc */
#define AID_NFC 1027 /* nfc subsystem */
#define AID_SDCARD_R 1028 /* external storage read access */
#define AID_CLAT 1029 /* clat part of nat464 */
#define AID_LOOP_RADIO 1030 /* loop radio devices */
#define AID_MEDIA_DRM 1031 /* MediaDrm plugins */
#define AID_PACKAGE_INFO 1032 /* access to installed package details */
#define AID_SDCARD_PICS 1033 /* external storage photos access */
#define AID_SDCARD_AV 1034 /* external storage audio/video access */
#define AID_SDCARD_ALL 1035 /* access all users external storage */
#define AID_SHELL 2000 /* adb and debug shell user */
#define AID_CACHE 2001 /* cache access */
#define AID_DIAG 2002 /* access to diagnostic resources */
編號3000系列只用於輔助使用者組
/* The 3000 series are intended for use as supplemental group id's only.
* They indicate special Android capabilities that the kernel is aware of. */
#define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */
#define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */
#define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
#define AID_NET_RAW 3004 /* can create raw INET sockets */
#define AID_NET_ADMIN 3005 /* can configure interfaces and routing tables. */
#define AID_NET_BW_STATS 3006 /* read bandwidth statistics */
#define AID_NET_BW_ACCT 3007 /* change bandwidth statistics accounting */
#define AID_NET_BT_STACK 3008 /* bluetooth: access config files */
其他部分預定義的UID
#define AID_MISC 9998 /* access to misc storage */
#define AID_NOBODY 9999
#define AID_APP 10000 /* first app user */
#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
#define AID_USER 100000 /* offset for uid ranges for each user */
#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
#define AID_SHARED_GID_END 59999 /* start of gids for apps in each user to share */
在Java層的程式碼中也定義了一套系統預置的UID,他和android_filesystem_config.h中定義的值是相互對應的,也就是說,
相同的UID表示相同的含義。
/**
* Defines the UID/GID under which system code runs.
*/
public static final int SYSTEM_UID = 1000;
/**
* Defines the UID/GID under which the telephony code runs.
*/
public static final int PHONE_UID = 1001;
/**
* Defines the UID/GID for the user shell.
* @hide
*/
public static final int SHELL_UID = 2000;
/**
* Defines the UID/GID for the log group.
* @hide
*/
public static final int LOG_UID = 1007;
/**
* Defines the UID/GID for the WIFI supplicant process.
* @hide
*/
public static final int WIFI_UID = 1010;
/**
* Defines the UID/GID for the mediaserver process.
* @hide
*/
public static final int MEDIA_UID = 1013;
/**
* Defines the UID/GID for the DRM process.
* @hide
*/
public static final int DRM_UID = 1019;
/**
* Defines the UID/GID for the group that controls VPN services.
* @hide
*/
public static final int VPN_UID = 1016;
/**
* Defines the UID/GID for the NFC service process.
* @hide
*/
public static final int NFC_UID = 1027;
/**
* Defines the UID/GID for the Bluetooth service process.
* @hide
*/
public static final int BLUETOOTH_UID = 1002;
/**
* Defines the GID for the group that allows write access to the internal media storage.
* @hide
*/
public static final int MEDIA_RW_GID = 1023;
/**
* Access to installed package details
* @hide
*/
public static final int PACKAGE_INFO_GID = 1032;
/**
* Defines the start of a range of UIDs (and GIDs), going from this
* number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
* to applications.
*/
public static final int FIRST_APPLICATION_UID = 10000;
/**
* Last of application-specific UIDs starting at
* {@link #FIRST_APPLICATION_UID}.
*/
public static final int LAST_APPLICATION_UID = 19999;
/**
* First uid used for fully isolated sandboxed processes (with no permissions of their own)
* @hide
*/
public static final int FIRST_ISOLATED_UID = 99000;
/**
* Last uid used for fully isolated sandboxed processes (with no permissions of their own)
* @hide
*/
public static final int LAST_ISOLATED_UID = 99999;
/**
* First gid for applications to share resources. Used when forward-locking
* is enabled but all UserHandles need to be able to read the resources.
* @hide
*/
public static final int FIRST_SHARED_APPLICATION_GID = 50000;
/**
* Last gid for applications to share resources. Used when forward-locking
* is enabled but all UserHandles need to be able to read the resources.
* @hide
*/
public static final int LAST_SHARED_APPLICATION_GID = 59999;
解釋一下部分UID:
(1) AID_APP(Process.FIRST_APPLICATION_UID): 使用者安裝的APK的UID的起始ID,為 10000.
Process.LAST_APPLICATION_UID 使用者安裝的APK的終結ID,為19999,也就是說,Android系統上最多能安裝9999個應用,
實際情況是不是這樣呢?我們將在後續的分許中給予驗證
(2) AID_ISOLATED_START(FIRST_ISOLATED_UID): 完全隔絕的沙箱程序中UID的開始編號。
AID_ISOLATED_END(LAST_ISOLATED_UID):完全隔絕的沙箱程序中UID的結束編號。這裡稍微做一些深入的探討:
從這段程式碼可以看到,isIsolated()這個方法就是根據uid來判斷的。
/**
* Returns whether the current process is in an isolated sandbox.
* @hide
*/
public static final boolean isIsolated() {
int uid = UserHandle.getAppId(myUid());
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
}
那麼,到底isolated表示什麼含義呢?系統服務Service有這樣一個屬性:
android:isolatedProcess ,這個可以在AndroidManifest.xml 中進行設定。設定true意味著,服務會在一個特殊的程序下執行,
這個程序與系統其他程序分開且沒有自己的許可權。與其通訊的唯一途徑是通過服務的API(binding and starting)
再看一段啟動Service的程式碼:
private final boolean bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean whileRestarting) {
//如果該Service服務已經建立,再次呼叫startService時,只調用該Service的onStartCommand來執行該Service
if (r.app != null && r.app.thread != null) {
//啟動Service
sendServiceArgsLocked(r, false);
return true;
}
if (!whileRestarting && r.restartDelay > 0) {
// If waiting for a restart, then do nothing.
return true;
}
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
// 將當前啟動的Service從服務重啟列表mRestartingServices中移除
mRestartingServices.remove(r);
// Service is now being launched, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "+ r.packageName + ": " + e);
}
//判斷此Service是否在獨立的程序中啟動
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
//得到在XML中設定該Service執行的程序名稱
final String appName = r.processName;
ProcessRecord app;
//當前Service執行在應用程式程序,並非獨立程序
if (!isolated) {
//根據程序名稱及UID從ActivityManagerService的成員變數mProcessNames中查詢程序對應的描述符ProcessRecord
app = getProcessRecordLocked(appName, r.appInfo.uid);
if (DEBUG_MU)
Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName);
//在現有的程序中啟動Service
realStartServiceLocked(r, app);
return true;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null) {
//啟動應用程式程序
if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated)) == null) {
Slog.w(TAG, "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad");
//強制退出Service
bringDownServiceLocked(r, true);
return false;
}
if (isolated) {
r.isolatedProc = app;
}
}
//當ActivityManagerService服務還為準備好時,mPendingServices用於儲存客戶程序請求啟動的Servcie
//儲存當前請求啟動的Service
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
return true;
}
這就基本說明了isolated屬性的含義。
憑證資訊,作為替代,Android定義了從名稱到獨特識別符號的Android ID(AID)對映表。初始的對映表中定義了一些特權使用者和一些系統關
鍵使用者。並且保留了一段AID範圍,用於提供給原生應用作為UID。
下面是從原始碼中擷取的預定義的系統特權使用者和使用者組:(system/core/include/private/android_filesystem_config.h)
/* This is the master Users and Groups config for the platform.
* DO NOT EVER RENUMBER
*/
#define AID_ROOT 0 /* traditional unix root user */
#define AID_SYSTEM 1000 /* system server */
#define AID_RADIO 1001 /* telephony subsystem, RIL */
#define AID_BLUETOOTH 1002 /* bluetooth subsystem */
#define AID_GRAPHICS 1003 /* graphics devices */
#define AID_INPUT 1004 /* input devices */
#define AID_AUDIO 1005 /* audio devices */
#define AID_CAMERA 1006 /* camera devices */
#define AID_LOG 1007 /* log devices */
#define AID_COMPASS 1008 /* compass device */
#define AID_MOUNT 1009 /* mountd socket */
#define AID_WIFI 1010 /* wifi subsystem */
#define AID_ADB 1011 /* android debug bridge (adbd) */
#define AID_INSTALL 1012 /* group for installing packages */
#define AID_MEDIA 1013 /* mediaserver process */
#define AID_DHCP 1014 /* dhcp client */
#define AID_SDCARD_RW 1015 /* external storage write access */
#define AID_VPN 1016 /* vpn system */
#define AID_KEYSTORE 1017 /* keystore subsystem */
#define AID_USB 1018 /* USB devices */
#define AID_DRM 1019 /* DRM server */
#define AID_MDNSR 1020 /* MulticastDNSResponder (service discovery) */
#define AID_GPS 1021 /* GPS daemon */
#define AID_UNUSED1 1022 /* deprecated, DO NOT USE */
#define AID_MEDIA_RW 1023 /* internal media storage write access */
#define AID_MTP 1024 /* MTP USB driver access */
#define AID_UNUSED2 1025 /* deprecated, DO NOT USE */
#define AID_DRMRPC 1026 /* group for drm rpc */
#define AID_NFC 1027 /* nfc subsystem */
#define AID_SDCARD_R 1028 /* external storage read access */
#define AID_CLAT 1029 /* clat part of nat464 */
#define AID_LOOP_RADIO 1030 /* loop radio devices */
#define AID_MEDIA_DRM 1031 /* MediaDrm plugins */
#define AID_PACKAGE_INFO 1032 /* access to installed package details */
#define AID_SDCARD_PICS 1033 /* external storage photos access */
#define AID_SDCARD_AV 1034 /* external storage audio/video access */
#define AID_SDCARD_ALL 1035 /* access all users external storage */
#define AID_SHELL 2000 /* adb and debug shell user */
#define AID_CACHE 2001 /* cache access */
#define AID_DIAG 2002 /* access to diagnostic resources */
編號3000系列只用於輔助使用者組
/* The 3000 series are intended for use as supplemental group id's only.
* They indicate special Android capabilities that the kernel is aware of. */
#define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */
#define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */
#define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */
#define AID_NET_RAW 3004 /* can create raw INET sockets */
#define AID_NET_ADMIN 3005 /* can configure interfaces and routing tables. */
#define AID_NET_BW_STATS 3006 /* read bandwidth statistics */
#define AID_NET_BW_ACCT 3007 /* change bandwidth statistics accounting */
#define AID_NET_BT_STACK 3008 /* bluetooth: access config files */
其他部分預定義的UID
#define AID_MISC 9998 /* access to misc storage */
#define AID_NOBODY 9999
#define AID_APP 10000 /* first app user */
#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
#define AID_USER 100000 /* offset for uid ranges for each user */
#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
#define AID_SHARED_GID_END 59999 /* start of gids for apps in each user to share */
在Java層的程式碼中也定義了一套系統預置的UID,他和android_filesystem_config.h中定義的值是相互對應的,也就是說,
相同的UID表示相同的含義。
/**
* Defines the UID/GID under which system code runs.
*/
public static final int SYSTEM_UID = 1000;
/**
* Defines the UID/GID under which the telephony code runs.
*/
public static final int PHONE_UID = 1001;
/**
* Defines the UID/GID for the user shell.
* @hide
*/
public static final int SHELL_UID = 2000;
/**
* Defines the UID/GID for the log group.
* @hide
*/
public static final int LOG_UID = 1007;
/**
* Defines the UID/GID for the WIFI supplicant process.
* @hide
*/
public static final int WIFI_UID = 1010;
/**
* Defines the UID/GID for the mediaserver process.
* @hide
*/
public static final int MEDIA_UID = 1013;
/**
* Defines the UID/GID for the DRM process.
* @hide
*/
public static final int DRM_UID = 1019;
/**
* Defines the UID/GID for the group that controls VPN services.
* @hide
*/
public static final int VPN_UID = 1016;
/**
* Defines the UID/GID for the NFC service process.
* @hide
*/
public static final int NFC_UID = 1027;
/**
* Defines the UID/GID for the Bluetooth service process.
* @hide
*/
public static final int BLUETOOTH_UID = 1002;
/**
* Defines the GID for the group that allows write access to the internal media storage.
* @hide
*/
public static final int MEDIA_RW_GID = 1023;
/**
* Access to installed package details
* @hide
*/
public static final int PACKAGE_INFO_GID = 1032;
/**
* Defines the start of a range of UIDs (and GIDs), going from this
* number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
* to applications.
*/
public static final int FIRST_APPLICATION_UID = 10000;
/**
* Last of application-specific UIDs starting at
* {@link #FIRST_APPLICATION_UID}.
*/
public static final int LAST_APPLICATION_UID = 19999;
/**
* First uid used for fully isolated sandboxed processes (with no permissions of their own)
* @hide
*/
public static final int FIRST_ISOLATED_UID = 99000;
/**
* Last uid used for fully isolated sandboxed processes (with no permissions of their own)
* @hide
*/
public static final int LAST_ISOLATED_UID = 99999;
/**
* First gid for applications to share resources. Used when forward-locking
* is enabled but all UserHandles need to be able to read the resources.
* @hide
*/
public static final int FIRST_SHARED_APPLICATION_GID = 50000;
/**
* Last gid for applications to share resources. Used when forward-locking
* is enabled but all UserHandles need to be able to read the resources.
* @hide
*/
public static final int LAST_SHARED_APPLICATION_GID = 59999;
解釋一下部分UID:
(1) AID_APP(Process.FIRST_APPLICATION_UID): 使用者安裝的APK的UID的起始ID,為 10000.
Process.LAST_APPLICATION_UID 使用者安裝的APK的終結ID,為19999,也就是說,Android系統上最多能安裝9999個應用,
實際情況是不是這樣呢?我們將在後續的分許中給予驗證
(2) AID_ISOLATED_START(FIRST_ISOLATED_UID): 完全隔絕的沙箱程序中UID的開始編號。
AID_ISOLATED_END(LAST_ISOLATED_UID):完全隔絕的沙箱程序中UID的結束編號。這裡稍微做一些深入的探討:
從這段程式碼可以看到,isIsolated()這個方法就是根據uid來判斷的。
/**
* Returns whether the current process is in an isolated sandbox.
* @hide
*/
public static final boolean isIsolated() {
int uid = UserHandle.getAppId(myUid());
return uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID;
}
那麼,到底isolated表示什麼含義呢?系統服務Service有這樣一個屬性:
android:isolatedProcess ,這個可以在AndroidManifest.xml 中進行設定。設定true意味著,服務會在一個特殊的程序下執行,
這個程序與系統其他程序分開且沒有自己的許可權。與其通訊的唯一途徑是通過服務的API(binding and starting)
再看一段啟動Service的程式碼:
private final boolean bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean whileRestarting) {
//如果該Service服務已經建立,再次呼叫startService時,只調用該Service的onStartCommand來執行該Service
if (r.app != null && r.app.thread != null) {
//啟動Service
sendServiceArgsLocked(r, false);
return true;
}
if (!whileRestarting && r.restartDelay > 0) {
// If waiting for a restart, then do nothing.
return true;
}
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
// 將當前啟動的Service從服務重啟列表mRestartingServices中移除
mRestartingServices.remove(r);
// Service is now being launched, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "+ r.packageName + ": " + e);
}
//判斷此Service是否在獨立的程序中啟動
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
//得到在XML中設定該Service執行的程序名稱
final String appName = r.processName;
ProcessRecord app;
//當前Service執行在應用程式程序,並非獨立程序
if (!isolated) {
//根據程序名稱及UID從ActivityManagerService的成員變數mProcessNames中查詢程序對應的描述符ProcessRecord
app = getProcessRecordLocked(appName, r.appInfo.uid);
if (DEBUG_MU)
Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName);
//在現有的程序中啟動Service
realStartServiceLocked(r, app);
return true;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null) {
//啟動應用程式程序
if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated)) == null) {
Slog.w(TAG, "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad");
//強制退出Service
bringDownServiceLocked(r, true);
return false;
}
if (isolated) {
r.isolatedProc = app;
}
}
//當ActivityManagerService服務還為準備好時,mPendingServices用於儲存客戶程序請求啟動的Servcie
//儲存當前請求啟動的Service
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
return true;
}
這就基本說明了isolated屬性的含義。