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

Commit 938089f3 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Initial splitting of calculation and grants.

In upcoming changes, we'll need to shift the calculation of needed
permission grants to occur before we acquire any AM/WM locks; we'll
continue to use that calculated list when actually granting.

This change also reduces the surface area of how callers in the
system server interact with Uri permissions to reduce the risk of
accidental misuse.

This is a no-op refactoring.

Bug: 115619667
Test: atest FrameworksServicesTests:com.android.server.uri
Test: atest CtsAppSecurityHostTestCases:android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert
Change-Id: Ied529156205903f9b02b4265963fdf59f7dd7f92
parent 7912eb5e
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.telephony.TelephonyManager;
import android.util.Slog;

import com.android.internal.telephony.IMms;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;

import java.util.List;
@@ -512,9 +513,11 @@ public class MmsServiceBroker extends SystemService {

            long token = Binder.clearCallingIdentity();
            try {
                LocalServices.getService(UriGrantsManagerInternal.class)
                        .grantUriPermissionFromIntent(callingUid, PHONE_PACKAGE_NAME,
                                grantIntent, UserHandle.USER_SYSTEM);
                final UriGrantsManagerInternal ugm = LocalServices
                        .getService(UriGrantsManagerInternal.class);
                final NeededUriGrants needed = ugm.checkGrantUriPermissionFromIntent(
                        grantIntent, callingUid, PHONE_PACKAGE_NAME, UserHandle.USER_SYSTEM);
                ugm.grantUriPermissionUncheckedFromIntent(needed, null);

                // Grant permission for the carrier app.
                Intent intent = new Intent(action);
@@ -524,9 +527,10 @@ public class MmsServiceBroker extends SystemService {
                        .getCarrierPackageNamesForIntentAndPhone(
                                intent, getPhoneIdFromSubId(subId));
                if (carrierPackages != null && carrierPackages.size() == 1) {
                    LocalServices.getService(UriGrantsManagerInternal.class)
                            .grantUriPermissionFromIntent(callingUid, carrierPackages.get(0),
                                    grantIntent, UserHandle.USER_SYSTEM);
                    final NeededUriGrants carrierNeeded = ugm.checkGrantUriPermissionFromIntent(
                            grantIntent, callingUid, carrierPackages.get(0),
                            UserHandle.USER_SYSTEM);
                    ugm.grantUriPermissionUncheckedFromIntent(carrierNeeded, null);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
+1 −1
Original line number Diff line number Diff line
@@ -590,7 +590,7 @@ public final class ActiveServices {
        }

        NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent(
                callingUid, r.packageName, service, service.getFlags(), null, r.userId);
                service, callingUid, r.packageName, r.userId);

        // If permissions need a review before any of the app components can run,
        // we do not start the service and launch a review activity if the calling app
+8 −5
Original line number Diff line number Diff line
@@ -365,6 +365,7 @@ import com.android.server.job.JobSchedulerInternal;
import com.android.server.pm.Installer;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.uri.GrantUri;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.utils.PriorityDump;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -6511,17 +6512,19 @@ public class ActivityManagerService extends IActivityManager.Stub
            if (targetPkg == null) {
                throw new IllegalArgumentException("null target");
            }
            if (grantUri == null) {
                throw new IllegalArgumentException("null uri");
            }
            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
            mUgmInternal.grantUriPermission(r.uid, targetPkg, grantUri, modeFlags, null,
                    UserHandle.getUserId(r.uid));
            final Intent intent = new Intent();
            intent.setData(uri);
            intent.setFlags(modeFlags);
            final NeededUriGrants needed = mUgmInternal.checkGrantUriPermissionFromIntent(intent,
                    r.uid, targetPkg, UserHandle.getUserId(r.uid));
            mUgmInternal.grantUriPermissionUncheckedFromIntent(needed, null);
        }
    }
+19 −12
Original line number Diff line number Diff line
@@ -31,28 +31,35 @@ import java.io.PrintWriter;
public interface UriGrantsManagerInternal {
    void onSystemReady();
    void removeUriPermissionIfNeeded(UriPermission perm);
    void grantUriPermission(int callingUid, String targetPkg, GrantUri grantUri,
            final int modeFlags, UriPermissionOwner owner, int targetUserId);

    void revokeUriPermission(String targetPackage, int callingUid,
            GrantUri grantUri, final int modeFlags);

    boolean checkUriPermission(GrantUri grantUri, int uid, final int modeFlags);
    int checkGrantUriPermission(int callingUid, String targetPkg, GrantUri grantUri,
            final int modeFlags, int lastTargetUid);
    int checkGrantUriPermission(
            int callingUid, String targetPkg, Uri uri, int modeFlags, int userId);
    NeededUriGrants checkGrantUriPermissionFromIntent(int callingUid,
            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId);

    /**
     * Grant Uri permissions from one app to another. This method only extends
     * permission grants if {@code callingUid} has permission to them.
     * Calculate the set of permission grants that would be needed to extend
     * access for the given {@link Intent} to the given target package.
     *
     * @throws SecurityException if the caller doesn't have permission to the
     *             {@link Intent} data, or if the underlying provider doesn't
     *             allow permissions to be granted.
     */
    NeededUriGrants checkGrantUriPermissionFromIntent(Intent intent, int callingUid,
            String targetPkg, int targetUserId);

    /**
     * Extend a previously calculated set of permissions grants to the given
     * owner. All security checks will have already been performed as part of
     * calculating {@link NeededUriGrants}.
     */
    void grantUriPermissionFromIntent(int callingUid,
            String targetPkg, Intent intent, int targetUserId);
    void grantUriPermissionFromIntent(int callingUid,
            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId);
    void grantUriPermissionUncheckedFromIntent(
            NeededUriGrants needed, UriPermissionOwner owner);

    IBinder newUriPermissionOwner(String name);

    /**
     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
     * given package.
+4 −50
Original line number Diff line number Diff line
@@ -635,17 +635,6 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
        return needed;
    }

    void grantUriPermissionFromIntent(int callingUid,
            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
        NeededUriGrants needed = checkGrantUriPermissionFromIntent(callingUid, targetPkg,
                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
        if (needed == null) {
            return;
        }

        grantUriPermissionUncheckedFromIntent(needed, owner);
    }

    void readGrantedUriPermissions() {
        if (DEBUG) Slog.v(TAG, "readGrantedUriPermissions()");

@@ -1325,15 +1314,6 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
            }
        }

        @Override
        public void grantUriPermission(int callingUid, String targetPkg, GrantUri grantUri,
                int modeFlags, UriPermissionOwner owner, int targetUserId) {
            synchronized (mLock) {
                UriGrantsManagerService.this.grantUriPermission(
                        callingUid, targetPkg, grantUri, modeFlags, owner, targetUserId);
            }
        }

        @Override
        public void revokeUriPermission(String targetPackage, int callingUid, GrantUri grantUri,
                int modeFlags) {
@@ -1350,15 +1330,6 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
            }
        }

        @Override
        public int checkGrantUriPermission(int callingUid, String targetPkg, GrantUri uri,
                int modeFlags, int userId) {
            synchronized (mLock) {
                return UriGrantsManagerService.this.checkGrantUriPermission(
                        callingUid, targetPkg, uri, modeFlags, userId);
            }
        }

        @Override
        public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, int modeFlags,
                int userId) {
@@ -1370,29 +1341,12 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
        }

        @Override
        public NeededUriGrants checkGrantUriPermissionFromIntent(int callingUid, String targetPkg,
                Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
        public NeededUriGrants checkGrantUriPermissionFromIntent(Intent intent, int callingUid,
                String targetPkg, int targetUserId) {
            synchronized (mLock) {
                final int mode = (intent != null) ? intent.getFlags() : 0;
                return UriGrantsManagerService.this.checkGrantUriPermissionFromIntent(
                        callingUid, targetPkg, intent, mode, needed, targetUserId);
            }
        }

        @Override
        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
                int targetUserId) {
            synchronized (mLock) {
                UriGrantsManagerService.this.grantUriPermissionFromIntent(
                        callingUid, targetPkg, intent, null, targetUserId);
            }
        }

        @Override
        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
                UriPermissionOwner owner, int targetUserId) {
            synchronized (mLock) {
                UriGrantsManagerService.this.grantUriPermissionFromIntent(
                        callingUid, targetPkg, intent, owner, targetUserId);
                        callingUid, targetPkg, intent, mode, null, targetUserId);
            }
        }

Loading