1. 程式人生 > >Android 安全機制2 沙箱機制

Android 安全機制2 沙箱機制

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屬性的含義。