diff options
author | Emilian Peev <epeev@google.com> | 2019-11-13 15:47:42 -0800 |
---|---|---|
committer | Emilian Peev <epeev@google.com> | 2019-11-13 16:19:29 -0800 |
commit | abe984f550e6b659d1583a156eb625afac7e35dd (patch) | |
tree | 85c1d2610abebc8ab49ea1a73e03a2052a4029d8 /services/usb | |
parent | 903cd4ceed6719143cdc32e037b482c75a647937 (diff) |
Use correct calling identity during camera permission check
UVC clients need to acquire the CAMERA permission
before trying to call open. The permission check is
currently done via calls to "checkCallingPermission".
In case the calling identity gets cleared, the check
will always fail. To resolve this, use "checkPermission"
with appropriate identity arguments.
Bug: 144433314
Test: Manual using application,
CtsVerifier USB Device test
Change-Id: I5318fbb4426bec1448ecc398c86ea96500bb3189
Merged-In: I5318fbb4426bec1448ecc398c86ea96500bb3189
Diffstat (limited to 'services/usb')
4 files changed, 21 insertions, 15 deletions
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 00c75480ba80..812237489063 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -486,7 +486,7 @@ public class UsbHostManager { /* Opens the specified USB device */ public ParcelFileDescriptor openDevice(String deviceAddress, UsbUserSettingsManager settings, - String packageName, int uid) { + String packageName, int pid, int uid) { synchronized (mLock) { if (isBlackListed(deviceAddress)) { throw new SecurityException("USB device is on a restricted bus"); @@ -498,7 +498,7 @@ public class UsbHostManager { "device " + deviceAddress + " does not exist or is restricted"); } - settings.checkPermission(device, packageName, uid); + settings.checkPermission(device, packageName, pid, uid); return nativeOpenDevice(deviceAddress); } } diff --git a/services/usb/java/com/android/server/usb/UsbSerialReader.java b/services/usb/java/com/android/server/usb/UsbSerialReader.java index 8ca77f0c63dc..077d6b9bd62d 100644 --- a/services/usb/java/com/android/server/usb/UsbSerialReader.java +++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java @@ -93,7 +93,7 @@ class UsbSerialReader extends IUsbSerialReader.Stub { UserHandle.getUserId(uid)); if (mDevice instanceof UsbDevice) { - settings.checkPermission((UsbDevice) mDevice, packageName, uid); + settings.checkPermission((UsbDevice) mDevice, packageName, pid, uid); } else { settings.checkPermission((UsbAccessory) mDevice, uid); } diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 4be68b83dbcb..13275f34ee1a 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -249,6 +249,7 @@ public class UsbService extends IUsbManager.Stub { if (mHostManager != null) { if (deviceName != null) { int uid = Binder.getCallingUid(); + int pid = Binder.getCallingPid(); int user = UserHandle.getUserId(uid); long ident = clearCallingIdentity(); @@ -256,7 +257,7 @@ public class UsbService extends IUsbManager.Stub { synchronized (mLock) { if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) { fd = mHostManager.openDevice(deviceName, getSettingsForUser(user), - packageName, uid); + packageName, pid, uid); } else { Slog.w(TAG, "Cannot open " + deviceName + " for user " + user + " as user is not active."); @@ -350,11 +351,12 @@ public class UsbService extends IUsbManager.Stub { @Override public boolean hasDevicePermission(UsbDevice device, String packageName) { final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final int userId = UserHandle.getUserId(uid); final long token = Binder.clearCallingIdentity(); try { - return getSettingsForUser(userId).hasPermission(device, packageName, uid); + return getSettingsForUser(userId).hasPermission(device, packageName, pid, uid); } finally { Binder.restoreCallingIdentity(token); } @@ -376,11 +378,12 @@ public class UsbService extends IUsbManager.Stub { @Override public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) { final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); final int userId = UserHandle.getUserId(uid); final long token = Binder.clearCallingIdentity(); try { - getSettingsForUser(userId).requestPermission(device, packageName, pi, uid); + getSettingsForUser(userId).requestPermission(device, packageName, pi, pid, uid); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java index 84add88cc84c..e1bfb8a7c6d0 100644 --- a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java @@ -127,11 +127,12 @@ class UsbUserSettingsManager { * Check for camera permission of the calling process. * * @param packageName Package name of the caller. + * @param pid Linux pid of the calling process. * @param uid Linux uid of the calling process. * * @return True in case camera permission is available, False otherwise. */ - private boolean isCameraPermissionGranted(String packageName, int uid) { + private boolean isCameraPermissionGranted(String packageName, int pid, int uid) { int targetSdkVersion = android.os.Build.VERSION_CODES.P; try { ApplicationInfo aInfo = mPackageManager.getApplicationInfo(packageName, 0); @@ -147,7 +148,8 @@ class UsbUserSettingsManager { } if (targetSdkVersion >= android.os.Build.VERSION_CODES.P) { - int allowed = mUserContext.checkCallingPermission(android.Manifest.permission.CAMERA); + int allowed = mUserContext.checkPermission(android.Manifest.permission.CAMERA, pid, + uid); if (android.content.pm.PackageManager.PERMISSION_DENIED == allowed) { Slog.i(TAG, "Camera permission required for USB video class devices"); return false; @@ -157,9 +159,9 @@ class UsbUserSettingsManager { return true; } - public boolean hasPermission(UsbDevice device, String packageName, int uid) { + public boolean hasPermission(UsbDevice device, String packageName, int pid, int uid) { if (isCameraDevicePresent(device)) { - if (!isCameraPermissionGranted(packageName, uid)) { + if (!isCameraPermissionGranted(packageName, pid, uid)) { return false; } } @@ -171,8 +173,8 @@ class UsbUserSettingsManager { return mUsbPermissionManager.hasPermission(accessory, uid); } - public void checkPermission(UsbDevice device, String packageName, int uid) { - if (!hasPermission(device, packageName, uid)) { + public void checkPermission(UsbDevice device, String packageName, int pid, int uid) { + if (!hasPermission(device, packageName, pid, uid)) { throw new SecurityException("User has not given " + uid + "/" + packageName + " permission to access device " + device.getDeviceName()); } @@ -206,11 +208,12 @@ class UsbUserSettingsManager { accessory, canBeDefault, packageName, uid, mUserContext, pi); } - public void requestPermission(UsbDevice device, String packageName, PendingIntent pi, int uid) { + public void requestPermission(UsbDevice device, String packageName, PendingIntent pi, int pid, + int uid) { Intent intent = new Intent(); // respond immediately if permission has already been granted - if (hasPermission(device, packageName, uid)) { + if (hasPermission(device, packageName, pid, uid)) { intent.putExtra(UsbManager.EXTRA_DEVICE, device); intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true); try { @@ -221,7 +224,7 @@ class UsbUserSettingsManager { return; } if (isCameraDevicePresent(device)) { - if (!isCameraPermissionGranted(packageName, uid)) { + if (!isCameraPermissionGranted(packageName, pid, uid)) { intent.putExtra(UsbManager.EXTRA_DEVICE, device); intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false); try { |