您的位置:首页 > 移动开发 > Android开发

android6.0 adbd深入分析(三)adb root重启adbd流程

2016-04-13 11:14 597 查看
上篇博客中分析过adb root pc到adbd的流程,这篇博客我们再来讲下adb root是adbd重启并且获取root的流程。我们再来回顾之前的函数:

void restart_root_service(int fd, void *cookie) {
if (getuid() == 0) {//uid为0,说明已经是root了
WriteFdExactly(fd, "adbd is already running as root\n");
adb_close(fd);
} else {
char value[PROPERTY_VALUE_MAX];
property_get("ro.debuggable", value, "");
if (strcmp(value, "1") != 0) {//不是1,不允许adb root
WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
adb_close(fd);
return;
}

property_set("service.adb.root", "1");//设置该属性
WriteFdExactly(fd, "restarting adbd as root\n");
adb_close(fd);
}
}

这个函数最终是设置了service.adb.root这个属性,我们再从init.rc中看下:

on property:service.adb.root=1
write /sys/class/android_usb/android0/enable 0
restart adbd
write /sys/class/android_usb/android0/enable 1

init.rc中只是将驱动的两个节点使能关,然后开,重启了adbd,下面我们再来看adbd的主函数是如何做到root的。

int adb_main(int is_daemon, int server_port)
{
......

/* 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 */
char c_back_value[PROPERTY_VALUE_MAX];
bool b_back_root = false;
property_get("persist.sys.adb.backroot", c_back_value, "");
if(strcmp(c_back_value, "1") == 0) {
b_back_root = true;
}
bool b_lr_root = false;
property_get("lc.adb.rrrr", c_back_value, "");
if(strcmp(c_back_value, "1") == 0) {
b_lr_root = true;
}
if (should_drop_privileges() && !b_back_root && !b_lr_root) {//如果是不是root的话,直接是降级,将adbd的uid设置shell
drop_capabilities_bounding_set_if_needed();

/* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {
exit(1);
}
if (setuid(AID_SHELL) != 0) {//设置uid为shell
exit(1);
}

D("Local port disabled\n");
} else {//如果是root的话就是默认的root也就是uid为0
if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) {
// b/12587913: fix setcon to allow const pointers
if (setcon((char *)root_seclabel) < 0) {
exit(1);
}
}
std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
if (install_listener(local_name, "*smartsocket*", NULL, 0)) {
exit(1);
}
}

adbd的root,是默认的,如果是没有root,再降级为shell。这中间我们主要看下should_drop_privileges这个判断是否需要降级为shell的函数:

static bool should_drop_privileges() {
#if defined(ALLOW_ADBD_ROOT)//adbd是否允许adb root
char value[PROPERTY_VALUE_MAX];

// The emulator is never secure, so don't drop privileges there.
// TODO: this seems like a bug --- shouldn't the emulator behave like a device?
property_get("ro.kernel.qemu", value, "");
if (strcmp(value, "1") == 0) {
return false;
}

// The properties that affect `adb root` and `adb unroot` are ro.secure and
// ro.debuggable. In this context the names don't make the expected behavior
// particularly obvious.
//
// ro.debuggable:
//   Allowed to become root, but not necessarily the default. Set to 1 on
//   eng and userdebug builds.
//
// ro.secure:
//   Drop privileges by default. Set to 1 on userdebug and user builds.
property_get("ro.secure", value, "1");
bool ro_secure = (strcmp(value, "1") == 0);

property_get("ro.debuggable", value, "");
bool ro_debuggable = (strcmp(value, "1") == 0);

// Drop privileges if ro.secure is set...
bool drop = ro_secure;

property_get("service.adb.root", value, "");//主要看这个属性为1,允许adb root
bool adb_root = (strcmp(value, "1") == 0);
bool adb_unroot = (strcmp(value, "0") == 0);

// ...except "adb root" lets you keep privileges in a debuggable build.
if (ro_debuggable && adb_root) {//service.adb.root和ro.debuggable都为1可以adb root
drop = false;
}

// ...and "adb unroot" lets you explicitly drop privileges.
if (adb_unroot) {
drop = true;
}

return drop;
#else
return true; // "adb root" not allowed, always drop privileges.
#endif /* ALLOW_ADBD_ROOT */
}

也就是service.adb.root和ro.debuggable都为1可以adb root,should_drop_privileges函数返回false,就不会讲adbd降级为shell,就是root了。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  adbd