天天看点

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

上篇博客中分析过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)

{

......

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();

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

}

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