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

Commit 103bff31 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android Git Automerger
Browse files

am 5474b0f8: am 39792d22: Fix bugs with granting permissions through onNewIntent().

Merge commit '5474b0f8'

* commit '5474b0f8':
  Fix bugs with granting permissions through onNewIntent().
parents 7802b205 5474b0f8
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -389,15 +389,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
        if (permission != null) {
            pw.println(prefix + "permission=" + permission);
        }
        pw.println(prefix + "uid=" + uid + " taskAffinity=" + taskAffinity);
        if (theme != 0) {
            pw.println(prefix + "theme=0x" + Integer.toHexString(theme));
        }
        pw.println(prefix + "flags=0x" + Integer.toHexString(flags)
                + " processName=" + processName);
        pw.println(prefix + "processName=" + processName);
        pw.println(prefix + "taskAffinity=" + taskAffinity);
        pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
                + " theme=0x" + Integer.toHexString(theme));
        pw.println(prefix + "sourceDir=" + sourceDir);
        if (!sourceDir.equals(publicSourceDir)) {
            pw.println(prefix + "publicSourceDir=" + publicSourceDir);
        }
        if (resourceDirs != null) {
            pw.println(prefix + "resourceDirs=" + resourceDirs);
        }
        pw.println(prefix + "dataDir=" + dataDir);
        if (sharedLibraryFiles != null) {
            pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
+92 −49
Original line number Diff line number Diff line
@@ -4100,16 +4100,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
    }

    void grantUriPermissionLocked(int callingUid,
            String targetPkg, Uri uri, int modeFlags, ActivityRecord activity) {
    /**
     * Check if the targetPkg can be granted permission to access uri by
     * the callingUid using the given modeFlags.  Throws a security exception
     * if callingUid is not allowed to do this.  Returns the uid of the target
     * if the URI permission grant should be performed; returns -1 if it is not
     * needed (for example targetPkg already has permission to access the URI).
     */
    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
            Uri uri, int modeFlags) {
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        if (modeFlags == 0) {
            return;
            return -1;
        }

        if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
                "Requested grant " + targetPkg + " permission to " + uri);
                "Checking grant " + targetPkg + " permission to " + uri);
        
        final IPackageManager pm = AppGlobals.getPackageManager();

@@ -4117,7 +4124,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
            if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
                    "Can't grant URI permission for non-content URI: " + uri);
            return;
            return -1;
        }

        String name = uri.getAuthority();
@@ -4134,7 +4141,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
        if (pi == null) {
            Slog.w(TAG, "No content provider found for: " + name);
            return;
            return -1;
        }

        int targetUid;
@@ -4143,10 +4150,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            if (targetUid < 0) {
                if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
                        "Can't grant URI permission no uid for: " + targetPkg);
                return;
                return -1;
            }
        } catch (RemoteException ex) {
            return;
            return -1;
        }

        // First...  does the target actually need this permission?
@@ -4154,7 +4161,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            // No need to grant the target this permission.
            if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
                    "Target " + targetPkg + " already has full permission to " + uri);
            return;
            return -1;
        }

        // Second...  is the provider allowing granting of URI permissions?
@@ -4191,12 +4198,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            }
        }

        // Okay!  So here we are: the caller has the assumed permission
        return targetUid;
    }

    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
            Uri uri, int modeFlags, UriPermissionOwner owner) {
        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        if (modeFlags == 0) {
            return;
        }

        // So here we are: the caller has the assumed permission
        // to the uri, and the target doesn't.  Let's now give this to
        // the target.

        if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
                "Granting " + targetPkg + " permission to " + uri);
                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
        
        HashMap<Uri, UriPermission> targetUris
                = mGrantedUriPermissions.get(targetUid);
@@ -4212,39 +4230,65 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }

        perm.modeFlags |= modeFlags;
        if (activity == null) {
        if (owner == null) {
            perm.globalModeFlags |= modeFlags;
        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
            perm.readActivities.add(activity);
            if (activity.readUriPermissions == null) {
                activity.readUriPermissions = new HashSet<UriPermission>();
            }
            activity.readUriPermissions.add(perm);
            perm.readOwners.add(owner);
            owner.addReadPermission(perm);
        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
            perm.writeActivities.add(activity);
            if (activity.writeUriPermissions == null) {
                activity.writeUriPermissions = new HashSet<UriPermission>();
            perm.writeOwners.add(owner);
            owner.addWritePermission(perm);
        }
            activity.writeUriPermissions.add(perm);
    }

    void grantUriPermissionLocked(int callingUid,
            String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
        if (targetUid < 0) {
            return;
        }

    void grantUriPermissionFromIntentLocked(int callingUid,
            String targetPkg, Intent intent, ActivityRecord activity) {
        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
    }

    /**
     * Like checkGrantUriPermissionLocked, but takes an Intent.
     */
    int checkGrantUriPermissionFromIntentLocked(int callingUid,
            String targetPkg, Intent intent) {
        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
                "Grant URI perm to " + (intent != null ? intent.getData() : null)
                "Checking URI perm to " + (intent != null ? intent.getData() : null)
                + " from " + intent + "; flags=0x"
                + Integer.toHexString(intent != null ? intent.getFlags() : 0));

        if (intent == null) {
            return;
            return -1;
        }
        Uri data = intent.getData();
        if (data == null) {
            return -1;
        }
        return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
                intent.getFlags());
    }

    /**
     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
     */
    void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
            String targetPkg, Intent intent, UriPermissionOwner owner) {
        grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
                intent.getFlags(), owner);
    }

    void grantUriPermissionFromIntentLocked(int callingUid,
            String targetPkg, Intent intent, UriPermissionOwner owner) {
        int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
        if (targetUid < 0) {
            return;
        }
        grantUriPermissionLocked(callingUid, targetPkg, data,
                intent.getFlags(), activity);

        grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
    }

    public void grantUriPermission(IApplicationThread caller, String targetPkg,
@@ -8215,18 +8259,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            return;
        }

        int i = 0;
        while (i < N) {
        while (r.pendingStarts.size() > 0) {
            try {
                ServiceRecord.StartItem si = r.pendingStarts.get(i);
                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to service: "
                        + r.name + " " + r.intent + " args=" + si.intent);
                if (si.intent == null && N > 1) {
                if (si.intent == null) {
                    // If somehow we got a dummy start at the front, then
                    // just drop it here.
                    i++;
                    continue;
                }
                si.deliveredTime = SystemClock.uptimeMillis();
                r.deliveredStarts.add(si);
                si.deliveryCount++;
                if (si.targetPermissionUid >= 0) {
                    grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
                            r.packageName, si.intent, si);
                }
                bumpServiceExecutingLocked(r);
                if (!oomAdjusted) {
                    oomAdjusted = true;
@@ -8240,10 +8289,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    flags |= Service.START_FLAG_REDELIVERY;
                }
                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
                si.deliveredTime = SystemClock.uptimeMillis();
                r.deliveredStarts.add(si);
                si.deliveryCount++;
                i++;
            } catch (RemoteException e) {
                // Remote process gone...  we'll let the normal cleanup take
                // care of this.
@@ -8253,14 +8298,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                break;
            }
        }
        if (i == N) {
            r.pendingStarts.clear();
        } else {
            while (i > 0) {
                i--;
                r.pendingStarts.remove(i);
            }
        }
    }

    private final boolean requestServiceBindingLocked(ServiceRecord r,
@@ -8343,7 +8380,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            if (r.lastStartId < 1) {
                r.lastStartId = 1;
            }
            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
            r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1));
        }
        
        sendServiceArgsLocked(r, true);
@@ -8363,6 +8400,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        if (N > 0) {
            for (int i=N-1; i>=0; i--) {
                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
                si.removeUriPermissionsLocked();
                if (si.intent == null) {
                    // We'll generate this again if needed.
                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
@@ -8602,7 +8640,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        r.foregroundNoti = null;
        
        // Clear start entries.
        r.deliveredStarts.clear();
        r.clearDeliveredStartsLocked();
        r.pendingStarts.clear();
        
        if (r.app != null) {
@@ -8662,6 +8700,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                        ? res.permission : "private to package");
            }
            ServiceRecord r = res.record;
            int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
                    callingUid, r.packageName, service);
            if (unscheduleServiceRestartLocked(r)) {
                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: "
                        + r.shortName);
@@ -8672,7 +8712,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            if (r.lastStartId < 1) {
                r.lastStartId = 1;
            }
            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
            r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
                    service, targetPermissionUid));
            r.lastActivity = SystemClock.uptimeMillis();
            synchronized (r.stats.getBatteryStats()) {
                r.stats.startRunningLocked();
@@ -8797,7 +8838,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
                    if (si != null) {
                        while (r.deliveredStarts.size() > 0) {
                            if (r.deliveredStarts.remove(0) == si) {
                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
                            cur.removeUriPermissionsLocked();
                            if (cur == si) {
                                break;
                            }
                        }
+49 −9
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.EventLog;
import android.util.Log;
@@ -43,7 +44,7 @@ import java.util.HashSet;
/**
 * An entry in the history stack, representing an activity.
 */
class ActivityRecord extends IApplicationToken.Stub {
class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwner {
    final ActivityManagerService service; // owner
    final ActivityStack stack; // owner
    final ActivityInfo info; // all about me
@@ -340,16 +341,22 @@ class ActivityRecord extends IApplicationToken.Stub {
     * Deliver a new Intent to an existing activity, so that its onNewIntent()
     * method will be called at the proper time.
     */
    final void deliverNewIntentLocked(Intent intent) {
    final void deliverNewIntentLocked(int callingUid, Intent intent) {
        boolean sent = false;
        if (state == ActivityState.RESUMED
                && app != null && app.thread != null) {
            try {
                ArrayList<Intent> ar = new ArrayList<Intent>();
                ar.add(new Intent(intent));
                intent = new Intent(intent);
                ar.add(intent);
                service.grantUriPermissionFromIntentLocked(callingUid, packageName,
                        intent, this);
                app.thread.scheduleNewIntent(ar, this);
                sent = true;
            } catch (Exception e) {
            } catch (RemoteException e) {
                Slog.w(ActivityManagerService.TAG,
                        "Exception thrown sending new intent to " + this, e);
            } catch (NullPointerException e) {
                Slog.w(ActivityManagerService.TAG,
                        "Exception thrown sending new intent to " + this, e);
            }
@@ -362,23 +369,25 @@ class ActivityRecord extends IApplicationToken.Stub {
    void removeUriPermissionsLocked() {
        if (readUriPermissions != null) {
            for (UriPermission perm : readUriPermissions) {
                perm.readActivities.remove(this);
                if (perm.readActivities.size() == 0 && (perm.globalModeFlags
                perm.readOwners.remove(this);
                if (perm.readOwners.size() == 0 && (perm.globalModeFlags
                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
                    service.removeUriPermissionIfNeededLocked(perm);
                }
            }
            readUriPermissions = null;
        }
        if (writeUriPermissions != null) {
            for (UriPermission perm : writeUriPermissions) {
                perm.writeActivities.remove(this);
                if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
                perm.writeOwners.remove(this);
                if (perm.writeOwners.size() == 0 && (perm.globalModeFlags
                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
                    service.removeUriPermissionIfNeededLocked(perm);
                }
            }
            writeUriPermissions = null;
        }
    }

@@ -569,6 +578,37 @@ class ActivityRecord extends IApplicationToken.Stub {
                state == ActivityState.RESUMED;
     }
    
    @Override
    public void addReadPermission(UriPermission perm) {
        if (readUriPermissions == null) {
            readUriPermissions = new HashSet<UriPermission>();
        }
        readUriPermissions.add(perm);
    }

    @Override
    public void addWritePermission(UriPermission perm) {
        if (writeUriPermissions == null) {
            writeUriPermissions = new HashSet<UriPermission>();
        }
        writeUriPermissions.add(perm);
    }

    @Override
    public void removeReadPermission(UriPermission perm) {
        readUriPermissions.remove(perm);
        if (readUriPermissions.size() == 0) {
            readUriPermissions = null;
        }
    }

    @Override
    public void removeWritePermission(UriPermission perm) {
        writeUriPermissions.remove(perm);
        if (writeUriPermissions.size() == 0) {
            writeUriPermissions = null;
        }
    }
    
    public String toString() {
        if (stringName != null) {
+16 −15
Original line number Diff line number Diff line
@@ -2033,16 +2033,6 @@ public class ActivityStack {
            }
        }

        if (grantedUriPermissions != null && callingUid > 0) {
            for (int i=0; i<grantedUriPermissions.length; i++) {
                mService.grantUriPermissionLocked(callingUid, r.packageName,
                        grantedUriPermissions[i], grantedMode, r);
            }
        }

        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
                intent, r);

        if (sourceRecord == null) {
            // This activity is not being started from another...  in this
            // case we -always- start a new task.
@@ -2150,7 +2140,7 @@ public class ActivityStack {
                                top.task.setIntent(r.intent, r.info);
                            }
                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                            top.deliverNewIntentLocked(r.intent);
                            top.deliverNewIntentLocked(callingUid, r.intent);
                        } else {
                            // A special case: we need to
                            // start the activity because it is not currently
@@ -2175,7 +2165,7 @@ public class ActivityStack {
                            if (taskTop.frontOfTask) {
                                taskTop.task.setIntent(r.intent, r.info);
                            }
                            taskTop.deliverNewIntentLocked(r.intent);
                            taskTop.deliverNewIntentLocked(callingUid, r.intent);
                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
                            // In this case we are launching the root activity
                            // of the task, but with a different intent.  We
@@ -2243,7 +2233,7 @@ public class ActivityStack {
                                // is the case, so this is it!
                                return START_RETURN_INTENT_TO_CALLER;
                            }
                            top.deliverNewIntentLocked(r.intent);
                            top.deliverNewIntentLocked(callingUid, r.intent);
                            return START_DELIVERED_TO_TOP;
                        }
                    }
@@ -2288,7 +2278,7 @@ public class ActivityStack {
                        sourceRecord.task.taskId, r, launchFlags, true);
                if (top != null) {
                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                    top.deliverNewIntentLocked(r.intent);
                    top.deliverNewIntentLocked(callingUid, r.intent);
                    // For paranoia, make sure we have correctly
                    // resumed the top activity.
                    if (doResume) {
@@ -2305,7 +2295,7 @@ public class ActivityStack {
                if (where >= 0) {
                    ActivityRecord top = moveActivityToFrontLocked(where);
                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
                    top.deliverNewIntentLocked(r.intent);
                    top.deliverNewIntentLocked(callingUid, r.intent);
                    if (doResume) {
                        resumeTopActivityLocked(null);
                    }
@@ -2333,6 +2323,17 @@ public class ActivityStack {
            if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                    + " in new guessed " + r.task);
        }

        if (grantedUriPermissions != null && callingUid > 0) {
            for (int i=0; i<grantedUriPermissions.length; i++) {
                mService.grantUriPermissionLocked(callingUid, r.packageName,
                        grantedUriPermissions[i], grantedMode, r);
            }
        }

        mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
                intent, r);

        if (newTask) {
            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
        }
+37 −31

File changed.

Preview size limit exceeded, changes collapsed.

Loading