From 8b682ad08a8e55b3ce2cf58f3aff6d3464ab668b Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Tue, 1 Feb 2011 15:53:11 -0500 Subject: [PATCH] UsbService: Blacklist HID boot subclass devices (keyboards and mice) Change-Id: I80558c6205e041ad730c7815aba97cb80132e820 Signed-off-by: Mike Lockwood --- api/current.xml | 13 ++++++- core/java/android/hardware/UsbConstants.java | 5 ++- .../java/com/android/server/UsbService.java | 35 ++++++++++++------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/api/current.xml b/api/current.xml index bf5fb5adaa4bc..c1df12fc905a6 100644 --- a/api/current.xml +++ b/api/current.xml @@ -94397,6 +94397,17 @@ visibility="public" > + + - + diff --git a/core/java/android/hardware/UsbConstants.java b/core/java/android/hardware/UsbConstants.java index 29a335cdbed8d..4c8c4d4db9dcf 100644 --- a/core/java/android/hardware/UsbConstants.java +++ b/core/java/android/hardware/UsbConstants.java @@ -41,6 +41,7 @@ public final class UsbConstants { public static final int USB_ENDPOINT_XFER_BULK = 2; public static final int USB_ENDPOINT_XFER_INT = 3; + // USB classes public static final int USB_CLASS_PER_INTERFACE = 0; public static final int USB_CLASS_AUDIO = 1; public static final int USB_CLASS_COMM = 2; @@ -58,6 +59,8 @@ public final class UsbConstants { public static final int USB_CLASS_MISC = 0xef; public static final int USB_CLASS_APP_SPEC = 0xfe; public static final int USB_CLASS_VENDOR_SPEC = 0xff; - public static final int USB_SUBCLASS_VENDOR_SPEC = 0xff; + // USB subclasses + public static final int USB_INTERFACE_SUBCLASS_BOOT = 1; // for HID class + public static final int USB_SUBCLASS_VENDOR_SPEC = 0xff; } \ No newline at end of file diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java index 45b0fcfe68219..460fd4d5eb7cf 100644 --- a/services/java/com/android/server/UsbService.java +++ b/services/java/com/android/server/UsbService.java @@ -213,6 +213,19 @@ class UsbService extends IUsbManager.Stub { return false; } + private boolean isBlackListed(int clazz, int subClass, int protocol) { + // blacklist hubs + if (clazz == UsbConstants.USB_CLASS_HUB) return true; + + // blacklist HID boot devices (mouse and keyboard) + if (clazz == UsbConstants.USB_CLASS_HID && + subClass == UsbConstants.USB_INTERFACE_SUBCLASS_BOOT) { + return true; + } + + return false; + } + // called from JNI in monitorUsbHostBus() private void usbDeviceAdded(String deviceName, int vendorID, int productID, int deviceClass, int deviceSubclass, int deviceProtocol, @@ -223,12 +236,8 @@ class UsbService extends IUsbManager.Stub { and interval for each endpoint */ int[] endpointValues) { - // ignore hubs - if (deviceClass == UsbConstants.USB_CLASS_HUB) { - return; - } - - if (isBlackListed(deviceName)) { + if (isBlackListed(deviceName) || + isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) { return; } @@ -243,7 +252,6 @@ class UsbService extends IUsbManager.Stub { try { // repackage interfaceValues as an array of UsbInterface int intf, endp, ival = 0, eval = 0; - boolean hasGoodInterface = false; for (intf = 0; intf < numInterfaces; intf++) { int interfaceId = interfaceValues[ival++]; int interfaceClass = interfaceValues[ival++]; @@ -261,16 +269,13 @@ class UsbService extends IUsbManager.Stub { maxPacketSize, interval); } - if (interfaceClass != UsbConstants.USB_CLASS_HUB) { - hasGoodInterface = true; + // don't allow if any interfaces are blacklisted + if (isBlackListed(interfaceClass, interfaceSubclass, interfaceProtocol)) { + return; } interfaces[intf] = new UsbInterface(interfaceId, interfaceClass, interfaceSubclass, interfaceProtocol, endpoints); } - - if (!hasGoodInterface) { - return; - } } catch (Exception e) { // beware of index out of bound exceptions, which might happen if // a device does not set bNumEndpoints correctly @@ -352,6 +357,10 @@ class UsbService extends IUsbManager.Stub { throw new SecurityException("USB device is on a restricted bus"); } mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null); + if (mDevices.get(deviceName) == null) { + // if it is not in mDevices, it either does not exist or is blacklisted + throw new IllegalArgumentException("device " + deviceName + " does not exist or is restricted"); + } return nativeOpenDevice(deviceName); }