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)
{
......

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





你可能感兴趣的:(android,adb)