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

Commit 5771ad7b authored by Svet Ganov's avatar Svet Ganov
Browse files

RemoteViews service not unbound.

We are checking whether an app can access an app widget
based on the calling uid and the package name. The package
is mostly to make sure that hosts in different apps do
not accidentally interfere whereas the security is enforced
by the uid.

When remote views adapter binds and unbinds to a remote
views serivce it was passing the package of the context we
create to load resources for the widget instead the package
of the host. Now it is passing the host package and also
we are checking if the caller of bind remove serivce API
is in uid that has the host package - this makes it
consistent with elsewhere.

bug:17226052

Change-Id: I2b0b6669e3dc027037b7481c2871cedabd642433
parent 63859536
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.annotation.Nullable;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Binder;
import android.os.Bundle;
@@ -155,7 +154,7 @@ public class AppWidgetHost {
        int[] updatedIds;
        ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
        try {
            updatedIds = sService.startListening(mCallbacks, mContext.getPackageName(), mHostId,
            updatedIds = sService.startListening(mCallbacks, mContext.getOpPackageName(), mHostId,
                    updatedViews);
        }
        catch (RemoteException e) {
@@ -174,7 +173,7 @@ public class AppWidgetHost {
     */
    public void stopListening() {
        try {
            sService.stopListening(mContext.getPackageName(), mHostId);
            sService.stopListening(mContext.getOpPackageName(), mHostId);
        }
        catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
@@ -192,7 +191,7 @@ public class AppWidgetHost {
     */
    public int allocateAppWidgetId() {
        try {
            return sService.allocateAppWidgetId(mContext.getPackageName(), mHostId);
            return sService.allocateAppWidgetId(mContext.getOpPackageName(), mHostId);
        }
        catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
@@ -222,7 +221,7 @@ public class AppWidgetHost {
            int appWidgetId, int intentFlags, int requestCode, @Nullable Bundle options) {
        try {
            IntentSender intentSender = sService.createAppWidgetConfigIntentSender(
                    mContext.getPackageName(), appWidgetId, intentFlags);
                    mContext.getOpPackageName(), appWidgetId, intentFlags);
            if (intentSender != null) {
                activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0,
                        options);
@@ -246,7 +245,7 @@ public class AppWidgetHost {
            if (sService == null) {
                bindService();
            }
            return sService.getAppWidgetIdsForHost(mContext.getPackageName(), mHostId);
            return sService.getAppWidgetIdsForHost(mContext.getOpPackageName(), mHostId);
        } catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
        }
@@ -263,7 +262,7 @@ public class AppWidgetHost {
        synchronized (mViews) {
            mViews.remove(appWidgetId);
            try {
                sService.deleteAppWidgetId(mContext.getPackageName(), appWidgetId);
                sService.deleteAppWidgetId(mContext.getOpPackageName(), appWidgetId);
            }
            catch (RemoteException e) {
                throw new RuntimeException("system server dead?", e);
@@ -281,7 +280,7 @@ public class AppWidgetHost {
     */
    public void deleteHost() {
        try {
            sService.deleteHost(mContext.getPackageName(), mHostId);
            sService.deleteHost(mContext.getOpPackageName(), mHostId);
        }
        catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
@@ -319,7 +318,7 @@ public class AppWidgetHost {
        }
        RemoteViews views;
        try {
            views = sService.getAppWidgetViews(mContext.getPackageName(), appWidgetId);
            views = sService.getAppWidgetViews(mContext.getOpPackageName(), appWidgetId);
        } catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
        }
+1 −1
Original line number Diff line number Diff line
@@ -441,7 +441,7 @@ public class AppWidgetManager {
     * @hide
     */
    public AppWidgetManager(Context context, IAppWidgetService service) {
        mPackageName = context.getPackageName();
        mPackageName = context.getOpPackageName();
        mService = service;
        mDisplayMetrics = context.getResources().getDisplayMetrics();
    }
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
                    RemoteViewsAdapter adapter;
                    final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
                    if ((adapter = mAdapter.get()) != null) {
                        mgr.bindRemoteViewsService(context.getPackageName(), appWidgetId,
                        mgr.bindRemoteViewsService(context.getOpPackageName(), appWidgetId,
                                intent, asBinder());
                    } else {
                        Slog.w(TAG, "bind: adapter was null");
+7 −20
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.appwidget;

import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
@@ -177,6 +178,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    private final IPackageManager mPackageManager;
    private final AlarmManager mAlarmManager;
    private final UserManager mUserManager;
    private final AppOpsManager mAppOpsManager;

    private final SecurityPolicy mSecurityPolicy;

@@ -195,6 +197,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        mPackageManager = AppGlobals.getPackageManager();
        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mSaveStateHandler = BackgroundThread.getHandler();
        mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
        mBackupRestoreController = new BackupRestoreController();
@@ -890,6 +893,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            Slog.i(TAG, "bindRemoteViewsService() " + userId);
        }

        // Make sure the package runs under the caller uid.
        mSecurityPolicy.enforceCallFromPackage(callingPackage);

        synchronized (mLock) {
            ensureGroupStateLoadedLocked(userId);

@@ -3039,26 +3045,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        }

        public void enforceCallFromPackage(String packageName) {
            if (!isCallFromPackage(packageName)) {
                throw new SecurityException("Package " + packageName
                        + " not running under user " + UserHandle.getCallingUserId());
            }
        }

        public boolean isCallFromPackage(String packageName) {
            // System and root call all from anywhere they want.
            final int callingUid = Binder.getCallingUid();
            if (callingUid == Process.SYSTEM_UID || callingUid == 0 /* root */) {
                return true;
            }
            // Check if the package is present for the given profile.
            final int packageUid = getUidForPackage(packageName,
                    UserHandle.getUserId(callingUid));
            if (packageUid < 0) {
                return false;
            }
            // Check if the call for a package is coming from that package.
            return UserHandle.isSameApp(callingUid, packageUid);
            mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName);
        }

        public boolean hasCallerBindPermissionOrBindWhiteListedLocked(String packageName) {