From 9cd80779e1f02bad2c1b98a65a23e3be35f46737 Mon Sep 17 00:00:00 2001 From: Joanne Chung Date: Fri, 7 Jul 2023 09:18:24 +0000 Subject: [PATCH] Avoid IndexOutOfBoundsException when accessing RemoteCallbackList This is not a deep copy so it's the same reference. It is possible a IndexOutOfBoundsException may happen. Bug: 29385425 Test: build. Manual, add log to check. 1. Local add code to regiser with user 10 and 11 2. Boot and try to add and remove user or run 3. Check the logs and no exception occurs Change-Id: I0d0da1cbb391e32ea0876e84960f9c61c4a89dd4 --- .../pm/PackageMonitorCallbackHelper.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java b/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java index 20d150845d015..1e3fab61d0212 100644 --- a/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java +++ b/services/core/java/com/android/server/pm/PackageMonitorCallbackHelper.java @@ -69,16 +69,24 @@ class PackageMonitorCallbackHelper { } public void onUserRemoved(int userId) { - RemoteCallbackList callbacks; + ArrayList targetUnRegisteredCallbacks = null; synchronized (mLock) { - callbacks = mCallbacks; + int registerCount = mCallbacks.getRegisteredCallbackCount(); + for (int i = 0; i < registerCount; i++) { + int registerUserId = (int) mCallbacks.getRegisteredCallbackCookie(i); + if (registerUserId == userId) { + IRemoteCallback callback = mCallbacks.getRegisteredCallbackItem(i); + if (targetUnRegisteredCallbacks == null) { + targetUnRegisteredCallbacks = new ArrayList<>(); + } + targetUnRegisteredCallbacks.add(callback); + } + } } - int registerCount = callbacks.getRegisteredCallbackCount(); - for (int i = 0; i < registerCount; i++) { - int registerUserId = (int) callbacks.getRegisteredCallbackCookie(i); - if (registerUserId == userId) { - IRemoteCallback callback = callbacks.getRegisteredCallbackItem(i); - unregisterPackageMonitorCallback(callback); + if (targetUnRegisteredCallbacks != null && targetUnRegisteredCallbacks.size() > 0) { + int count = targetUnRegisteredCallbacks.size(); + for (int i = 0; i < count; i++) { + unregisterPackageMonitorCallback(targetUnRegisteredCallbacks.get(i)); } } }