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

Commit d5ba868b authored by Amith Yamasani's avatar Amith Yamasani Committed by Android (Google) Code Review
Browse files

Merge "Fix singleUser attribute"

parents d8e295b0 4b9d79c3
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -2174,7 +2174,6 @@ public class PackageParser {
        }

        final int innerDepth = parser.getDepth();

        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
@@ -2548,14 +2547,14 @@ public class PackageParser {
                    com.android.internal.R.styleable.AndroidManifestActivity_singleUser,
                    false)) {
                a.info.flags |= ActivityInfo.FLAG_SINGLE_USER;
                if (a.info.exported) {
                if (a.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                    Slog.w(TAG, "Activity exported request ignored due to singleUser: "
                            + a.className + " at " + mArchiveSourcePath + " "
                            + parser.getPositionDescription());
                    a.info.exported = false;
                }
                    setExported = true;
                }
            }
            if (sa.getBoolean(
                    com.android.internal.R.styleable.AndroidManifestActivity_primaryUserOnly,
                    false)) {
@@ -2907,7 +2906,7 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestProvider_singleUser,
                false)) {
            p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
            if (p.info.exported) {
            if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                Slog.w(TAG, "Provider exported request ignored due to singleUser: "
                        + p.className + " at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
@@ -3181,14 +3180,14 @@ public class PackageParser {
                com.android.internal.R.styleable.AndroidManifestService_singleUser,
                false)) {
            s.info.flags |= ServiceInfo.FLAG_SINGLE_USER;
            if (s.info.exported) {
            if (s.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                Slog.w(TAG, "Service exported request ignored due to singleUser: "
                        + s.className + " at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
                s.info.exported = false;
            }
                setExported = true;
            }
        }

        sa.recycle();

+2 −1
Original line number Diff line number Diff line
@@ -988,7 +988,8 @@ public final class ActiveServices {
                        sInfo.applicationInfo.packageName, sInfo.name);
                if (userId > 0) {
                    if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                            sInfo.name, sInfo.flags)) {
                            sInfo.name, sInfo.flags)
                            && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                        userId = 0;
                        smap = getServiceMap(0);
                    }
+72 −27
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.am;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -2189,7 +2190,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        mBatteryStatsService.publish(mContext);
        mUsageStatsService.publish(mContext);
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }
@@ -7737,7 +7738,7 @@ public final class ActivityManagerService extends ActivityManagerNative
     * in {@link ContentProvider}.
     */
    private final String checkContentProviderPermissionLocked(
            ProviderInfo cpi, ProcessRecord r, int userId) {
            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
@@ -7754,8 +7755,10 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
            }
        }
        if (checkUser) {
            userId = handleIncomingUser(callingPid, callingUid, userId,
                false, true, "checkContentProviderPermissionLocked", null);
                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
        }
        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
                cpi.applicationInfo.uid, cpi.exported)
                == PackageManager.PERMISSION_GRANTED) {
@@ -7890,13 +7893,34 @@ public final class ActivityManagerService extends ActivityManagerNative
                }
            }
            boolean checkCrossUser = true;
            // First check if this content provider has been published...
            cpr = mProviderMap.getProviderByName(name, userId);
            // If that didn't work, check if it exists for user 0 and then
            // verify that it's a singleton provider before using it.
            if (cpr == null && userId != UserHandle.USER_OWNER) {
                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
                if (cpr != null) {
                    cpi = cpr.info;
                    if (isSingleton(cpi.processName, cpi.applicationInfo,
                            cpi.name, cpi.flags)
                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
                        userId = UserHandle.USER_OWNER;
                        checkCrossUser = false;
                    } else {
                        cpr = null;
                        cpi = null;
                    }
                }
            }
            boolean providerRunning = cpr != null;
            if (providerRunning) {
                cpi = cpr.info;
                String msg;
                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
                        != null) {
                    throw new SecurityException(msg);
                }
@@ -7976,15 +8000,21 @@ public final class ActivityManagerService extends ActivityManagerNative
                if (cpi == null) {
                    return null;
                }
                // If the provider is a singleton AND
                // (it's a call within the same user || the provider is a
                // privileged app)
                // Then allow connecting to the singleton provider
                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
                        cpi.name, cpi.flags); 
                        cpi.name, cpi.flags)
                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
                if (singleton) {
                    userId = 0;
                    userId = UserHandle.USER_OWNER;
                }
                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
                String msg;
                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
                        != null) {
                    throw new SecurityException(msg);
                }
@@ -10563,8 +10593,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        // assume our apps are happy - lazy create the list
        List<ActivityManager.ProcessErrorStateInfo> errList = null;
        final boolean allUsers = ActivityManager.checkUidPermission(
                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
        int userId = UserHandle.getUserId(Binder.getCallingUid());
@@ -10653,8 +10682,7 @@ public final class ActivityManagerService extends ActivityManagerNative
        enforceNotIsolatedCaller("getRunningAppProcesses");
        // Lazy instantiation of list
        List<ActivityManager.RunningAppProcessInfo> runList = null;
        final boolean allUsers = ActivityManager.checkUidPermission(
                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
        int userId = UserHandle.getUserId(Binder.getCallingUid());
        synchronized (this) {
@@ -13094,8 +13122,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                if ((requireFull || checkComponentPermission(
                        android.Manifest.permission.INTERACT_ACROSS_USERS,
                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
                        && checkComponentPermission(
                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
                                callingPid, callingUid, -1, true)
                                != PackageManager.PERMISSION_GRANTED) {
                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
@@ -13115,7 +13142,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                        builder.append(" but is calling from user ");
                        builder.append(UserHandle.getUserId(callingUid));
                        builder.append("; this requires ");
                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
                        builder.append(INTERACT_ACROSS_USERS_FULL);
                        if (!requireFull) {
                            builder.append(" or ");
                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
@@ -13145,6 +13172,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
            String className, int flags) {
        boolean result = false;
        // For apps that don't have pre-defined UIDs, check for permission
        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
                if (ActivityManager.checkUidPermission(
@@ -13157,12 +13185,14 @@ public final class ActivityManagerService extends ActivityManagerNative
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
                // Permission passed
                result = true;
            }
        } else if (componentProcessName == aInfo.packageName) {
            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
        } else if ("system".equals(componentProcessName)) {
            result = true;
        } else {
            // App with pre-defined UID, check if it's a persistent app
            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
        }
        if (DEBUG_MU) {
            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
@@ -13171,6 +13201,21 @@ public final class ActivityManagerService extends ActivityManagerNative
        return result;
    }
    /**
     * Checks to see if the caller is in the same app as the singleton
     * component, or the component is in a special app. It allows special apps
     * to export singleton components but prevents exporting singleton
     * components for regular apps.
     */
    boolean isValidSingletonCall(int callingUid, int componentUid) {
        int componentAppId = UserHandle.getAppId(componentUid);
        return UserHandle.isSameApp(callingUid, componentUid)
                || componentAppId == Process.SYSTEM_UID
                || componentAppId == Process.PHONE_UID
                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
                        == PackageManager.PERMISSION_GRANTED;
    }
    public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType,
            IServiceConnection connection, int flags, int userId) {
@@ -13717,8 +13762,8 @@ public final class ActivityManagerService extends ActivityManagerNative
         */
        int callingAppId = UserHandle.getAppId(callingUid);
        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
            callingUid == 0) {
                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
                || callingUid == 0) {
            // Always okay.
        } else if (callerApp == null || !callerApp.persistent) {
            try {
@@ -16528,12 +16573,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    }
    private boolean startUser(final int userId, boolean foreground) {
        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: switchUser() from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid()
                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
                    + " requires " + INTERACT_ACROSS_USERS_FULL;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
@@ -16899,12 +16944,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    @Override
    public int stopUser(final int userId, final IStopUserCallback callback) {
        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: switchUser() from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid()
                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
                    + " requires " + INTERACT_ACROSS_USERS_FULL;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
@@ -17042,7 +17087,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    public UserInfo getCurrentUser() {
        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
                != PackageManager.PERMISSION_GRANTED) && (
                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                != PackageManager.PERMISSION_GRANTED)) {
            String msg = "Permission Denial: getCurrentUser() from pid="
                    + Binder.getCallingPid()
@@ -17128,12 +17173,12 @@ public final class ActivityManagerService extends ActivityManagerNative
    @Override
    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid()
                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
                    + " requires " + INTERACT_ACROSS_USERS_FULL;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
+5 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.ComponentName;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
@@ -858,7 +859,10 @@ public final class BroadcastQueue {
            r.state = BroadcastRecord.APP_RECEIVE;
            String targetProcess = info.activityInfo.processName;
            r.curComponent = component;
            if (r.callingUid != Process.SYSTEM_UID && isSingleton) {
            final int receiverUid = info.activityInfo.applicationInfo.uid;
            // If it's a singleton, it needs to be the same app or a special app
            if (r.callingUid != Process.SYSTEM_UID && isSingleton
                    && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
                info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
            }
            r.curReceiver = info.activityInfo;
+1 −1
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ public final class ContentService extends IContentService.Stub {
        // Notify for any user other than the caller's own requires permission.
        final int callingUserHandle = UserHandle.getCallingUserId();
        if (userHandle != callingUserHandle) {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
            mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS,
                    "no permission to notify other users");
        }