diff options
author | 2023-07-17 12:01:18 +0000 | |
---|---|---|
committer | 2023-07-17 14:19:35 +0000 | |
commit | df127e12b95a6c499b6fe1c4876eb54b90cd6327 (patch) | |
tree | 7b86fbba2b2ed8ef6cbb69c65f7fa486de1c8e74 | |
parent | d2b36a15deb2178f302407bee63504582234ee0e (diff) |
Resolve custom printer icon boundary exploit.
Because Settings grants the INTERACT_ACROSS_USERS_FULL permission, an exploit is possible where the third party print plugin service can pass other's User Icon URI. This CL provides a lightweight solution for parsing the image URI to detect profile exploitation.
Bug: 281525042
Test: Build and flash the code. Try to reproduce the issue with
mentioned steps in the bug
Change-Id: Iaaa6fe2a627a265c4d1d7b843a033a132e1fe2ce
Merged-In: Iaaa6fe2a627a265c4d1d7b843a033a132e1fe2ce
-rw-r--r-- | services/print/java/com/android/server/print/PrintManagerService.java | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java index 35b9bc3b1e06..4a8d73d23904 100644 --- a/services/print/java/com/android/server/print/PrintManagerService.java +++ b/services/print/java/com/android/server/print/PrintManagerService.java @@ -254,12 +254,45 @@ public final class PrintManagerService extends SystemService { } final long identity = Binder.clearCallingIdentity(); try { - return userState.getCustomPrinterIcon(printerId); + Icon icon = userState.getCustomPrinterIcon(printerId); + return validateIconUserBoundary(icon); } finally { Binder.restoreCallingIdentity(identity); } } + /** + * Validates the custom printer icon to see if it's not in the calling user space. + * If the condition is not met, return null. Otherwise, return the original icon. + * + * @param icon + * @return icon (validated) + */ + private Icon validateIconUserBoundary(Icon icon) { + // Refer to Icon#getUriString for context. The URI string is invalid for icons of + // incompatible types. + if (icon != null && (icon.getType() == Icon.TYPE_URI + || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) { + String encodedUser = icon.getUri().getEncodedUserInfo(); + + // If there is no encoded user, the URI is calling into the calling user space + if (encodedUser != null) { + int userId = Integer.parseInt(encodedUser); + // resolve encoded user + final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId); + + synchronized (mLock) { + // Only the current group members can get the printer icons. + if (resolveCallingProfileParentLocked(resolvedUserId) + != getCurrentUserId()) { + return null; + } + } + } + } + return icon; + } + @Override public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) { if (printJobId == null) { |