Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8c3a3e9 authored by Pavel Maltsev's avatar Pavel Maltsev
Browse files

Check black-listed USB class before descriptor

Attempt to read USB descriptor of USB hub devices results in hanging
thread on getDescriptorString_native call.  Also check device
interface class/subclass as well.

Test: verified that usb host thread no longer stuch in getDescriptorString_native call on Mojave board with USB hub attached

Bug: 112657091

Change-Id: I46271dcc9c80168a650940fbde9218a54cafe8da
parent ace398c3
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.usb.descriptors.UsbDescriptor;
import com.android.server.usb.descriptors.UsbDescriptorParser;
import com.android.server.usb.descriptors.UsbDeviceDescriptor;
import com.android.server.usb.descriptors.UsbInterfaceDescriptor;
import com.android.server.usb.descriptors.report.TextReportCanvas;
import com.android.server.usb.descriptors.tree.UsbDescriptorsTree;

@@ -352,8 +353,6 @@ public class UsbHostManager {
            }
            return false;
        }
        UsbDescriptorParser parser = new UsbDescriptorParser(deviceAddress, descriptors);
        logUsbDevice(parser);

        if (isBlackListed(deviceClass, deviceSubclass)) {
            if (DEBUG) {
@@ -362,6 +361,15 @@ public class UsbHostManager {
            return false;
        }

        UsbDescriptorParser parser = new UsbDescriptorParser(deviceAddress, descriptors);
        if (deviceClass == UsbConstants.USB_CLASS_PER_INTERFACE
                && !checkUsbInterfacesBlackListed(parser)) {
            return false;
        }

        // Potentially can block as it may read data from the USB device.
        logUsbDevice(parser);

        synchronized (mLock) {
            if (mDevices.get(deviceAddress) != null) {
                Slog.w(TAG, "device already on mDevices list: " + deviceAddress);
@@ -509,6 +517,29 @@ public class UsbHostManager {
        }
    }

    private boolean checkUsbInterfacesBlackListed(UsbDescriptorParser parser) {
        // Device class needs to be obtained through the device interface.  Ignore device only
        // if ALL interfaces are black-listed.
        boolean shouldIgnoreDevice = false;
        for (UsbDescriptor descriptor: parser.getDescriptors()) {
            if (!(descriptor instanceof UsbInterfaceDescriptor)) {
                continue;
            }
            UsbInterfaceDescriptor iface = (UsbInterfaceDescriptor) descriptor;
            shouldIgnoreDevice = isBlackListed(iface.getUsbClass(), iface.getUsbSubclass());
            if (!shouldIgnoreDevice) {
                break;
            }
        }
        if (shouldIgnoreDevice) {
            if (DEBUG) {
                Slog.d(TAG, "usb interface class is black listed");
            }
            return false;
        }
        return true;
    }

    private native void monitorUsbHostBus();
    private native ParcelFileDescriptor nativeOpenDevice(String deviceAddress);
}