Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2114590c authored by yutingfang's avatar yutingfang Committed by Android Build Coastguard Worker
Browse files

Use ParceledListSlice to paginate response from getPackagesForOpsForDevice binder API

In a previous similar security bug fix ag/31434165 we imposed a
threshold on the number of attributed op entries returned for a single
package. But in this bug, the POC app created attributed op entries for
hundreds of packages which caused TransactionTooLargeException in getPackagesForOpsForDevice binder API.
So the fix is to add pagination in the binder response by using
ParceledListSlice.

Bug: 416490321
Test: Use the POC app in the bug report, verified after the fix there
was no more crashes from SystemUi and the device could boot
successfully.
Flag: EXEMPT security bug fix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2c637955ab388773c234268ceb108372eaab2200)
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:bd1eff349d514a53838df08ae097380d21c08c67
Merged-In: If4590160d1d743f58c1aed3f923d3668a8936c57
Change-Id: If4590160d1d743f58c1aed3f923d3668a8936c57
parent 67769a49
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -7860,13 +7860,13 @@ public class AppOpsManager {
        } else {
            opCodes = null;
        }
        final List<AppOpsManager.PackageOps> result;
        try {
            result = mService.getPackagesForOpsForDevice(opCodes, persistentDeviceId);
            ParceledListSlice<PackageOps> packageOps = mService.getPackagesForOpsForDevice(opCodes,
                    persistentDeviceId);
            return packageOps == null ? Collections.emptyList() : packageOps.getList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return (result != null) ? result : Collections.emptyList();
    }

    /**
@@ -7885,8 +7885,9 @@ public class AppOpsManager {
    @UnsupportedAppUsage
    public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
        try {
            return mService.getPackagesForOpsForDevice(ops,
            ParceledListSlice<PackageOps> packageOps = mService.getPackagesForOpsForDevice(ops,
                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
            return packageOps == null ? null : packageOps.getList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+1 −1
Original line number Diff line number Diff line
@@ -162,5 +162,5 @@ interface IAppOpsService {
            int attributionFlags, int attributionChainId);
    void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName,
            @nullable String attributionTag, int virtualDeviceId);
   List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId);
   ParceledListSlice<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId);
}
+7 −3
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
@@ -194,6 +195,7 @@ import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@@ -1753,11 +1755,13 @@ public class AppOpsService extends IAppOpsService.Stub {

    @Override
    public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
        return getPackagesForOpsForDevice(ops, PERSISTENT_DEVICE_ID_DEFAULT);
        ParceledListSlice<AppOpsManager.PackageOps> packageOps = getPackagesForOpsForDevice(ops,
                PERSISTENT_DEVICE_ID_DEFAULT);
        return packageOps == null ? null : packageOps.getList();
    }

    @Override
    public List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(int[] ops,
    public ParceledListSlice<AppOpsManager.PackageOps> getPackagesForOpsForDevice(int[] ops,
            @NonNull String persistentDeviceId) {
        final int callingUid = Binder.getCallingUid();
        final boolean hasAllPackageAccess = mContext.checkPermission(
@@ -1794,7 +1798,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                }
            }
        }
        return res;
        return res == null ? null : new ParceledListSlice<>(res);
    }

    @Override