前段時間,工作階段,經同事提醒遇到的一個問題:
在debug版本下shell #,不能使用kill -9 pid進行adbd進程的操作。
後來想想代碼設計的確如此:自己爲了記錄,完整進行了一下分析記錄。
在debug模式下,shell用戶是不能殺掉root用戶組的adbd的。但是爲什麼在User版本模式下可以,是因爲adbd進程在Debug版本下有用戶組降權的代碼邏輯。
我們在代碼中看一下源碼:
system/core/adb/adbd.c
static int should_drop_privileges() {
int secure = 0;
char value[PROPERTY_VALUE_MAX];
/* run adbd in secure mode if ro.secure is set and
** we are not in the emulator
*/
property_get("ro.kernel.qemu", value, "");
if (strcmp(value, "1") != 0) {
property_get("ro.secure", value, "1");
if (strcmp(value, "1") == 0) {
// don't run as root if ro.secure is set...
secure = 1;
// ... except we allow running as root in userdebug builds if the
// service.adb.root property has been set by the "adb root" command
property_get("ro.debuggable", value, "");
if (strcmp(value, "1") == 0) {
property_get("service.adb.root", value, "");
if (strcmp(value, "1") == 0) {
secure = 0;
}
}
}
}
return secure;
}
我們在代碼中看一下源碼:
adbd進程依次判斷,標誌位,決定是否進行從root降權到shell用戶的判斷
ro.kernel.qemu
ro.secure
ro.debuggable
/* don't listen on a port (default 5037) if running in secure mode */
/* don't run as root if we are running in secure mode */
if (should_drop_privileges()) {
struct __user_cap_header_struct header;
struct __user_cap_data_struct cap;
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
exit(1);
}
/* add extra groups:
** AID_ADB to access the USB driver
** AID_LOG to read system logs (adb logcat)
** AID_INPUT to diagnose input issues (getevent)
** AID_INET to diagnose network issues (netcfg, ping)
** AID_GRAPHICS to access the frame buffer
** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
** AID_SDCARD_R to allow reading from the SD card
** AID_SDCARD_RW to allow writing to the SD card
** AID_MOUNT to allow unmounting the SD card before rebooting
** AID_NET_BW_STATS to read out qtaguid statistics
*/
gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
AID_MOUNT, AID_NET_BW_STATS };
if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
exit(1);
}
/* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {
exit(1);
}
if (setuid(AID_SHELL) != 0) {
exit(1);
}
/* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
header.version = _LINUX_CAPABILITY_VERSION;
header.pid = 0;
cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
cap.inheritable = 0;
capset(&header, &cap);
D("Local port disabled\n");
</pre><div></div><pre>