1. 程式人生 > >Android新增使用者組及自定義App許可權

Android新增使用者組及自定義App許可權

Android:4.4.4

一、應用場景

在Android裝置上,現在我們外接了一個USB轉串列埠的裝置,裝置節點是/dev/ttyUSB0:

# ls -l /dev/ttyUSB0
crw-rw---- 1 root root 188, 0 /dev/ttyUSB0

資訊顯示:該裝置的使用者及其所屬組別都是root,root的持有者對該裝置具有讀寫許可權。但是,我們的App是被排除在root之外的,總之無法讀寫該裝置。
一個解決方案是:賦予others以讀寫許可權。但是這樣,任何其他第三方應用都可以訪問我們的裝置,安全性一絲不剩。
另一個解決方案就是:改變/dev/ttyUSB0所屬的使用者組:
crw-rw---- 1 root selfgroup 188, 0 /dev/ttyUSB0

哪個App想使用該裝置,就把它加入到selfgroup 組中。由於許可權分發權在我們手中,安全性就得到了保障。

二、新增自定義使用者組

接下來就是怎麼新增我們自己的使用者組。
在Android中,每一個使用者組都有一個唯一的ID號,定義在檔案:

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 */

仿照其新增自己的ID號(不允許重複)、並賦予它一個字串的名字(後文用到):

/** 第1步 */
#define AID_SELF_GROUP    8011
/** 第2步 */
static const struct android_id_info android_ids[] = {
    { "root",          AID_ROOT, },
    {省略 .......................},
    /** 自定義組名 */
    {{ "selfgroup", AID_SELF_GROUP, },},
}

然後在Android原始碼/device目錄下板級.rc檔案中:

編譯boot.img並燒錄,重啟後檢視節點組別已經變成自定義的“selfgroup”。

三、為自定義組別新增許可權管理

裝置中App要訪問我們的裝置,需要加入“selfgroup”組中。所以我們需要提供許可權資訊給App,使得App:

<uses-permission android:name="android.permission.SELFGROUP" />
即可加入到“selfgroup”組中。
這需要做兩步。

1、組控制權限的實現:

Android原始碼/frameworks/base/data/etc/platform.xml
<permission name="android.permission.SELFGROUP" >
	<group gid="selfgroup" />
</permission>

2、組控制權限的宣告:

Android原始碼/frameworks/base/core/res/AndroidManifest.xml
<permission android:name="android.permission.SELFGROUP"
	android:permissionGroup="android.permission-group.SELFGROUP"
	android:protectionLevel="dangerous"
	android:label="@string/permlab_sys_selfgroup"
	android:description="@string/permdesc_sys_selfgroup" />

自此,許可權定義完成。

另,如何判斷App申請組許可權成功與否
Android原始碼/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative {
	static final String TAG = "ActivityManager";
	private final void startProcessLocked(ProcessRecord app,
		String hostingType, String hostingNameStr) {
		int uid = app.uid;
		int[] gids = null;
		StringBuilder buf = mStringBuilder;
		buf.setLength(0);
		buf.append("Start proc ");
		buf.append(app.processName);
		buf.append(" for ");
		buf.append(hostingType);
		if (hostingNameStr != null) {
			buf.append(" ");
			buf.append(hostingNameStr);
		}
		buf.append(": pid=");
		buf.append(startResult.pid);
		buf.append(" uid=");
		buf.append(uid);
		buf.append(" gids={");
		if (gids != null) {
			for (int gi=0; gi<gids.length; gi++) {
				if (gi != 0) buf.append(", ");
				buf.append(gids[gi]);
			}
		}
		buf.append("}");
		Slog.i(TAG, buf.toString());
	}
}

即:當啟動App的時候,ActityManagerService會把該App的Uid、Gid等資訊輸出到控制檯,我們通過log檢視“gids=”欄位是否含有我們自定義的組ID號“8011”即可。

比如啟動微信Log:

I/ActivityManager(  977): Start proc com.tencent.mm for activity com.tencent.mm/.ui.LauncherUI: pid=11060 uid=10258 gids={50258, 3003, 1028, 1015, 1023, 3002, 3001}