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
This commit is contained in:
kumarashishg
2023-07-17 12:01:18 +00:00
committed by Ashish Kumar Gupta
parent d3e895e052
commit 7cfc47271c

View File

@@ -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) {