android6.0 adbd深入分析(五)adbd处理adb root的一个bug

在之前博客中我们分析了很多adbd的代码,也分析了adb root的代码流程,这篇博客我们说下adb root的一个bug。


一、问题

我们先来回顾下adbd处理adb root的代码:

void restart_root_service(int fd, void *cookie) {
    if (getuid() == 0) {
        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) {
            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);
    }
}

初看没啥问题,我们再来结合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

adb root后adbd会往service.adb.root写1,然后init会根据这个属性,把上面init.rc中的两个节点先写0,再写1。什么意思呢,就是usb驱动,使能开关先关掉,再开。而这中间还要重启adbd。

正常的话,我们之前也分析过了,adbd重启后,发现property:service.adb.root=1,于是就不会给adbd降级为shell,还是为root。

但是如何有问题的话,首先adbd写这个属性,先把usb驱动的使能开关关了,试问这个时候adbd往adb驱动写的数据只有到一半怎么办?这个时候很有可能和pc的通信就有问题。

结合实际,在我们的手机上没有问题,但是类似"restarting adbd as root“的字眼经常在pc的cmd命令上显示不出来,就是因为usb使能关太早了,导致adbd还没发送完数据。

最近调试adb root就直接驱动那边出问题。


二、解决方法

归根到底就是一个时序的问题,解决方案可以在驱动关闭usb使能的时候,延时一段时间,就可以解决了。

但是归根到底还是google的一个bug,可以在adbd中等数据完全通信完了再去写service.adb.root为1,这样这个问题也就完全解决了,而不用去做规避。




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