diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-21 19:25:37 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-21 19:25:37 +0000 |
commit | 4302e839a68598283027c28316c5d79130366584 (patch) | |
tree | ea4f8950e75747330c00450c35b5f815355af17d | |
parent | 65ff5247cb85e2bd1fb7f65228542fe8266f6d9e (diff) | |
parent | 7c5d78637acbc2823b72aace459c822713efa635 (diff) | |
download | base-4302e839a68598283027c28316c5d79130366584.tar.gz |
Merge cherrypicks of [3775466, 3774310, 3774548, 3774358, 3774359, 3774360, 3774361, 3774362, 3774363, 3775784, 3775785, 3775786, 3775787, 3775788, 3775789, 3774751, 3774549, 3774202, 3774203, 3774752] into oc-m2-release
Change-Id: I62374d40a9c7c61d6ce6df145547c3ba8536d2c8
14 files changed, 326 insertions, 40 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 2c04f8ff9548..8dc558ccf755 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -5872,6 +5872,16 @@ public class Activity extends ContextThemeWrapper } /** + * Temporary method on O-MR1 only. + * + * @hide + */ + @Override + public ComponentName getComponentNameForAutofill() { + return mComponent; + } + + /** * Retrieve a {@link SharedPreferences} object for accessing preferences * that are private to this activity. This simply calls the underlying * {@link #getSharedPreferences(String, int)} method by passing in this activity's diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 9383626360dc..bf715c35d9b7 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -2058,6 +2058,16 @@ public class AssistStructure implements Parcelable { return mActivityComponent; } + /** + * Called by Autofill server when app forged a different value. + * + * @hide + */ + public void setActivityComponent(ComponentName componentName) { + ensureData(); + mActivityComponent = componentName; + } + /** @hide */ public int getFlags() { return mFlags; diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java new file mode 100644 index 000000000000..9f5c877e7081 --- /dev/null +++ b/core/java/android/content/PermissionChecker.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.app.AppOpsManager; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Process; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class provides permission check APIs that verify both the + * permission and the associated app op for this permission if + * such is defined. + * <p> + * In the new permission model permissions with protection level + * dangerous are runtime permissions. For apps targeting {@link android.os.Build.VERSION_CODES#M} + * and above the user may not grant such permissions or revoke + * them at any time. For apps targeting API lower than {@link android.os.Build.VERSION_CODES#M} + * these permissions are always granted as such apps do not expect + * permission revocations and would crash. Therefore, when the + * user disables a permission for a legacy app in the UI the + * platform disables the APIs guarded by this permission making + * them a no-op which is doing nothing or returning an empty + * result or default error. + * </p> + * <p> + * It is important that when you perform an operation on behalf of + * another app you use these APIs to check for permissions as the + * app may be a legacy app that does not participate in the new + * permission model for which the user had disabled the "permission" + * which is achieved by disallowing the corresponding app op. + * </p> + * + * @hide + */ +public final class PermissionChecker { + /** Permission result: The permission is granted. */ + public static final int PERMISSION_GRANTED = PackageManager.PERMISSION_GRANTED; + + /** Permission result: The permission is denied. */ + public static final int PERMISSION_DENIED = PackageManager.PERMISSION_DENIED; + + /** Permission result: The permission is denied because the app op is not allowed. */ + public static final int PERMISSION_DENIED_APP_OP = PackageManager.PERMISSION_DENIED - 1; + + /** @hide */ + @IntDef({PERMISSION_GRANTED, + PERMISSION_DENIED, + PERMISSION_DENIED_APP_OP}) + @Retention(RetentionPolicy.SOURCE) + public @interface PermissionResult {} + + private PermissionChecker() { + /* do nothing */ + } + + /** + * Checks whether a given package in a UID and PID has a given permission + * and whether the app op that corresponds to this permission is allowed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @param pid The process id for which to check. + * @param uid The uid for which to check. + * @param packageName The package name for which to check. If null the + * the first package for the calling UID will be used. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + */ + @PermissionResult + public static int checkPermission(@NonNull Context context, @NonNull String permission, + int pid, int uid, @Nullable String packageName) { + if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) { + return PERMISSION_DENIED; + } + + AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class); + String op = appOpsManager.permissionToOp(permission); + if (op == null) { + return PERMISSION_GRANTED; + } + + if (packageName == null) { + String[] packageNames = context.getPackageManager().getPackagesForUid(uid); + if (packageNames == null || packageNames.length <= 0) { + return PERMISSION_DENIED; + } + packageName = packageNames[0]; + } + + if (appOpsManager.noteProxyOpNoThrow(op, packageName) + != AppOpsManager.MODE_ALLOWED) { + return PERMISSION_DENIED_APP_OP; + } + + return PERMISSION_GRANTED; + } + + /** + * Checks whether your app has a given permission and whether the app op + * that corresponds to this permission is allowed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + */ + @PermissionResult + public static int checkSelfPermission(@NonNull Context context, + @NonNull String permission) { + return checkPermission(context, permission, Process.myPid(), + Process.myUid(), context.getPackageName()); + } + + /** + * Checks whether the IPC you are handling has a given permission and whether + * the app op that corresponds to this permission is allowed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @param packageName The package name making the IPC. If null the + * the first package for the calling UID will be used. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + */ + @PermissionResult + public static int checkCallingPermission(@NonNull Context context, + @NonNull String permission, @Nullable String packageName) { + if (Binder.getCallingPid() == Process.myPid()) { + return PERMISSION_DENIED; + } + return checkPermission(context, permission, Binder.getCallingPid(), + Binder.getCallingUid(), packageName); + } + + /** + * Checks whether the IPC you are handling or your app has a given permission + * and whether the app op that corresponds to this permission is allowed. + * + * @param context Context for accessing resources. + * @param permission The permission to check. + * @return The permission check result which is either {@link #PERMISSION_GRANTED} + * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}. + */ + @PermissionResult + public static int checkCallingOrSelfPermission(@NonNull Context context, + @NonNull String permission) { + String packageName = (Binder.getCallingPid() == Process.myPid()) + ? context.getPackageName() : null; + return checkPermission(context, permission, Binder.getCallingPid(), + Binder.getCallingUid(), packageName); + } +} diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java index 674f809ef0f5..70dfef574ca5 100644 --- a/core/java/android/speech/RecognitionService.java +++ b/core/java/android/speech/RecognitionService.java @@ -20,7 +20,7 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.Service; import android.content.Intent; -import android.content.pm.PackageManager; +import android.content.PermissionChecker; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -174,8 +174,8 @@ public abstract class RecognitionService extends Service { */ private boolean checkPermissions(IRecognitionListener listener) { if (DBG) Log.d(TAG, "checkPermissions"); - if (RecognitionService.this.checkCallingOrSelfPermission(android.Manifest.permission. - RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) { + if (PermissionChecker.checkCallingOrSelfPermission(this, + android.Manifest.permission.RECORD_AUDIO) == PermissionChecker.PERMISSION_GRANTED) { return true; } try { diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 4fb2a99af575..fb9534b2e52e 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -24,6 +24,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentSender; @@ -44,6 +45,7 @@ import android.view.View; import com.android.internal.annotations.GuardedBy; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.util.Preconditions; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -384,13 +386,20 @@ public final class AutofillManager { * Runs the specified action on the UI thread. */ void runOnUiThread(Runnable action); + + /** + * Gets the complete component name of this client. + * + * <p>Temporary method on O-MR1 only. + */ + ComponentName getComponentNameForAutofill(); } /** * @hide */ public AutofillManager(Context context, IAutoFillManager service) { - mContext = context; + mContext = Preconditions.checkNotNull(context, "context cannot be null"); mService = service; } @@ -940,6 +949,10 @@ public final class AutofillManager { return mContext.getAutofillClient(); } + private ComponentName getComponentNameFromContext(AutofillClient client) { + return client == null ? null : client.getComponentNameForAutofill(); + } + /** @hide */ public void onAuthenticationResult(int authenticationId, Intent data) { if (!hasAutofillFeature()) { @@ -990,13 +1003,18 @@ public final class AutofillManager { return; } try { + final AutofillClient client = getClientLocked(); + final ComponentName componentName = getComponentNameFromContext(client); + if (componentName == null) { + Log.w(TAG, "startSessionLocked(): context is not activity: " + mContext); + return; + } mSessionId = mService.startSession(mContext.getActivityToken(), mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(), - mCallback != null, flags, mContext.getOpPackageName()); + mCallback != null, flags, componentName); if (mSessionId != NO_SESSION) { mState = STATE_ACTIVE; } - final AutofillClient client = getClientLocked(); if (client != null) { client.autofillCallbackResetableStateAvailable(); } @@ -1050,14 +1068,19 @@ public final class AutofillManager { try { if (restartIfNecessary) { + final AutofillClient client = getClientLocked(); + final ComponentName componentName = getComponentNameFromContext(client); + if (componentName == null) { + Log.w(TAG, "startSessionLocked(): context is not activity: " + mContext); + return; + } final int newId = mService.updateOrRestartSession(mContext.getActivityToken(), mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(), - mCallback != null, flags, mContext.getOpPackageName(), mSessionId, action); + mCallback != null, flags, componentName, mSessionId, action); if (newId != mSessionId) { if (sDebug) Log.d(TAG, "Session restarted: " + mSessionId + "=>" + newId); mSessionId = newId; mState = (mSessionId == NO_SESSION) ? STATE_UNKNOWN : STATE_ACTIVE; - final AutofillClient client = getClientLocked(); if (client != null) { client.autofillCallbackResetableStateAvailable(); } diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl index 6bd9bec368c8..9329c4dcff6a 100644 --- a/core/java/android/view/autofill/IAutoFillManager.aidl +++ b/core/java/android/view/autofill/IAutoFillManager.aidl @@ -16,6 +16,7 @@ package android.view.autofill; +import android.content.ComponentName; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; @@ -34,14 +35,15 @@ interface IAutoFillManager { int addClient(in IAutoFillManagerClient client, int userId); int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags, - String packageName); + in ComponentName componentName); FillEventHistory getFillEventHistory(); boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback); void updateSession(int sessionId, in AutofillId id, in Rect bounds, in AutofillValue value, int action, int flags, int userId); int updateOrRestartSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, - boolean hasCallback, int flags, String packageName, int sessionId, int action); + boolean hasCallback, int flags, in ComponentName componentName, int sessionId, + int action); void finishSession(int sessionId, int userId); void cancelSession(int sessionId, int userId); void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId); diff --git a/core/java/com/android/internal/app/procstats/SparseMappingTable.java b/core/java/com/android/internal/app/procstats/SparseMappingTable.java index 956ce99c0ad8..91b205479988 100644 --- a/core/java/com/android/internal/app/procstats/SparseMappingTable.java +++ b/core/java/com/android/internal/app/procstats/SparseMappingTable.java @@ -18,6 +18,7 @@ package com.android.internal.app.procstats; import android.os.Build; import android.os.Parcel; +import android.util.EventLog; import android.util.Slog; import libcore.util.EmptyArray; @@ -529,6 +530,12 @@ public class SparseMappingTable { readCompactedLongArray(in, array, size); mLongs.add(array); } + // Verify that last array's length is consistent with writeToParcel + if (N > 0 && mLongs.get(N - 1).length != mNextIndex) { + EventLog.writeEvent(0x534e4554, "73252178", -1, ""); + throw new IllegalStateException("Expected array of length " + mNextIndex + " but was " + + mLongs.get(N - 1).length); + } } /** diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index d5b6def97426..df1ed7d392b2 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -31,6 +31,7 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.MathUtils; +import android.view.AbsSavedState; import android.view.FocusFinder; import android.view.Gravity; import android.view.KeyEvent; @@ -1198,15 +1199,11 @@ public class ViewPager extends ViewGroup { * state, in which case it should implement a subclass of this which * contains that state. */ - public static class SavedState extends BaseSavedState { + public static class SavedState extends AbsSavedState { int position; Parcelable adapterState; ClassLoader loader; - public SavedState(Parcel source) { - super(source); - } - public SavedState(Parcelable superState) { super(superState); } @@ -1225,10 +1222,15 @@ public class ViewPager extends ViewGroup { + " position=" + position + "}"; } - public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { + public static final Creator<SavedState> CREATOR = new ClassLoaderCreator<SavedState>() { + @Override + public SavedState createFromParcel(Parcel in, ClassLoader loader) { + return new SavedState(in, loader); + } + @Override public SavedState createFromParcel(Parcel in) { - return new SavedState(in); + return new SavedState(in, null); } @Override public SavedState[] newArray(int size) { @@ -1237,7 +1239,7 @@ public class ViewPager extends ViewGroup { }; SavedState(Parcel in, ClassLoader loader) { - super(in); + super(in, loader); if (loader == null) { loader = getClass().getClassLoader(); } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index a27515c0266d..3cadff242e03 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -4006,6 +4006,19 @@ message MetricsEvent { // OS: O FIELD_NOTIFICATION_GROUP_SUMMARY = 947; + // An app attempted to forge a different component name in the AssisStructure that would be + // passed to the autofill service. + // OS: O (security patch) + // Package: Real package of the app being autofilled + // Tag FIELD_AUTOFILL_SERVICE: Package of the autofill service that processed the request + // TAG FIELD_AUTOFILL_FORGED_COMPONENT_NAME: Component name being forged + AUTOFILL_FORGED_COMPONENT_ATTEMPT = 948; + + // FIELD - The component that an app tried tro forged. + // Type: string + // OS: O (security patch) + FIELD_AUTOFILL_FORGED_COMPONENT_NAME = 949; + // ---- End O Constants, all O constants go above this line ---- // OPEN: Settings > System > Languages & input > Advanced > Lift to open camera diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index 1f4161ac54d4..ffc778a8ee40 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -533,25 +533,26 @@ public final class AutofillManagerService extends SystemService { @Override public int startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, - String packageName) { + ComponentName componentName) { activityToken = Preconditions.checkNotNull(activityToken, "activityToken"); appCallback = Preconditions.checkNotNull(appCallback, "appCallback"); autofillId = Preconditions.checkNotNull(autofillId, "autoFillId"); - packageName = Preconditions.checkNotNull(packageName, "packageName"); + componentName = Preconditions.checkNotNull(componentName, "componentName"); + final String packageName = Preconditions.checkNotNull(componentName.getPackageName()); Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId"); try { mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, userId); } catch (PackageManager.NameNotFoundException e) { - throw new IllegalArgumentException(packageName + " is not a valid package", e); + throw new IllegalArgumentException(componentName + " is not a valid package", e); } synchronized (mLock) { final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); return service.startSessionLocked(activityToken, getCallingUid(), appCallback, - autofillId, bounds, value, hasCallback, flags, packageName); + autofillId, bounds, value, hasCallback, flags, componentName); } } @@ -603,7 +604,8 @@ public final class AutofillManagerService extends SystemService { @Override public int updateOrRestartSession(IBinder activityToken, IBinder appCallback, AutofillId autoFillId, Rect bounds, AutofillValue value, int userId, - boolean hasCallback, int flags, String packageName, int sessionId, int action) { + boolean hasCallback, int flags, ComponentName componentName, int sessionId, + int action) { boolean restart = false; synchronized (mLock) { final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); @@ -614,7 +616,7 @@ public final class AutofillManagerService extends SystemService { } if (restart) { return startSession(activityToken, appCallback, autoFillId, bounds, value, userId, - hasCallback, flags, packageName); + hasCallback, flags, componentName); } // Nothing changed... diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 3a3b5707fc6f..a17c3ca92e5d 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -32,6 +32,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -43,6 +44,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.service.autofill.AutofillService; @@ -279,7 +281,7 @@ final class AutofillManagerServiceImpl { int startSessionLocked(@NonNull IBinder activityToken, int uid, @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId, @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback, - int flags, @NonNull String packageName) { + int flags, @NonNull ComponentName componentName) { if (!isEnabled()) { return 0; } @@ -289,7 +291,7 @@ final class AutofillManagerServiceImpl { pruneAbandonedSessionsLocked(); final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken, - hasCallback, packageName); + hasCallback, componentName); if (newSession == null) { return NO_SESSION; } @@ -386,7 +388,8 @@ final class AutofillManagerServiceImpl { } private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid, - @NonNull IBinder appCallbackToken, boolean hasCallback, @NonNull String packageName) { + @NonNull IBinder appCallbackToken, boolean hasCallback, + @NonNull ComponentName componentName) { // use random ids so that one app cannot know that another app creates sessions int sessionId; int tries = 0; @@ -400,15 +403,44 @@ final class AutofillManagerServiceImpl { sessionId = sRandom.nextInt(); } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0); + assertCallerLocked(componentName); + final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock, sessionId, uid, activityToken, appCallbackToken, hasCallback, - mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), packageName); + mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), componentName); mSessions.put(newSession.id, newSession); return newSession; } /** + * Asserts the component is owned by the caller. + */ + private void assertCallerLocked(@NonNull ComponentName componentName) { + final PackageManager pm = mContext.getPackageManager(); + final int callingUid = Binder.getCallingUid(); + final int packageUid; + try { + packageUid = pm.getPackageUidAsUser(componentName.getPackageName(), + UserHandle.getCallingUserId()); + } catch (NameNotFoundException e) { + throw new SecurityException("Could not verify UID for " + componentName); + } + if (callingUid != packageUid) { + final String[] packages = pm.getPackagesForUid(callingUid); + final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; + Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid + + ") passed component (" + componentName + ") owned by UID " + packageUid); + mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT) + .setPackageName(callingPackage) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName()) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME, + componentName == null ? "null" : componentName.flattenToShortString())); + throw new SecurityException("Invalid component: " + componentName); + } + } + + /** * Restores a session after an activity was temporarily destroyed. * * @param sessionId The id of the session to restore diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index de2950dd5985..1f0e51c694aa 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -126,8 +126,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @GuardedBy("mLock") @NonNull private IBinder mActivityToken; - /** Package name of the app that is auto-filled */ - @NonNull private final String mPackageName; + /** Component that's being auto-filled */ + @NonNull private final ComponentName mComponentName; @GuardedBy("mLock") private final ArrayMap<AutofillId, ViewState> mViewStates = new ArrayMap<>(); @@ -227,6 +227,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState structure.ensureData(); // Sanitize structure before it's sent to service. + final ComponentName componentNameFromApp = structure.getActivityComponent(); + if (!mComponentName.equals(componentNameFromApp)) { + Slog.w(TAG, "Activity " + mComponentName + " forged different component on " + + "AssistStructure: " + componentNameFromApp); + structure.setActivityComponent(mComponentName); + mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT) + .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME, + componentNameFromApp == null ? "null" + : componentNameFromApp.flattenToShortString())); + } structure.sanitizeForParceling(true); // Flags used to start the session. @@ -415,7 +425,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId, @NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken, @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory, - @NonNull ComponentName componentName, @NonNull String packageName) { + @NonNull ComponentName serviceComponentName, @NonNull ComponentName appComponentName) { id = sessionId; this.uid = uid; mStartTime = SystemClock.elapsedRealtime(); @@ -423,11 +433,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mLock = lock; mUi = ui; mHandlerCaller = handlerCaller; - mRemoteFillService = new RemoteFillService(context, componentName, userId, this); + mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this); mActivityToken = activityToken; mHasCallback = hasCallback; mUiLatencyHistory = uiLatencyHistory; - mPackageName = packageName; + mComponentName = appComponentName; mClient = IAutoFillManagerClient.Stub.asInterface(client); writeLog(MetricsEvent.AUTOFILL_SESSION_STARTED); @@ -1008,8 +1018,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState final IAutoFillManagerClient client = getClient(); mPendingSaveUi = new PendingUi(mActivityToken, id, client); getUiForShowing().showSaveUi(mService.getServiceLabel(), mService.getServiceIcon(), - mService.getServicePackageName(), saveInfo, valueFinder, mPackageName, this, - mPendingSaveUi); + mService.getServicePackageName(), saveInfo, valueFinder, + mComponentName.getPackageName(), this, mPendingSaveUi); if (client != null) { try { client.setSaveUiState(id, true); @@ -1365,7 +1375,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } getUiForShowing().showFillUi(filledId, response, filterText, - mService.getServicePackageName(), mPackageName, this); + mService.getServicePackageName(), mComponentName.getPackageName(), this); synchronized (mLock) { if (mUiShownTime == 0) { @@ -1690,14 +1700,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @Override public String toString() { - return "Session: [id=" + id + ", pkg=" + mPackageName + "]"; + return "Session: [id=" + id + ", pkg=" + mComponentName.getPackageName() + "]"; } void dumpLocked(String prefix, PrintWriter pw) { final String prefix2 = prefix + " "; pw.print(prefix); pw.print("id: "); pw.println(id); pw.print(prefix); pw.print("uid: "); pw.println(uid); - pw.print(prefix); pw.print("mPackagename: "); pw.println(mPackageName); + pw.print(prefix); pw.print("mComponentName: "); pw.println(mComponentName); pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken); pw.print(prefix); pw.print("mStartTime: "); pw.println(mStartTime); pw.print(prefix); pw.print("Time to show UI: "); @@ -1920,7 +1930,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState } private LogMaker newLogMaker(int category, String servicePackageName) { - return Helper.newLogMaker(category, mPackageName, servicePackageName); + return Helper.newLogMaker(category, mComponentName.getPackageName(), servicePackageName); } private void writeLog(int category) { diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 1854e2b740f4..66d01c7885c9 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1777,6 +1777,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges) throws ServiceSpecificException { + mContext.enforceCallingOrSelfPermission(NETWORK_STACK, TAG); + try { mNetdService.networkRejectNonSecureVpn(add, uidRanges); } catch (ServiceSpecificException e) { diff --git a/telephony/java/com/android/internal/telephony/DcParamObject.java b/telephony/java/com/android/internal/telephony/DcParamObject.java index 139939cbd0c1..fc6b61061134 100644 --- a/telephony/java/com/android/internal/telephony/DcParamObject.java +++ b/telephony/java/com/android/internal/telephony/DcParamObject.java @@ -36,7 +36,7 @@ public class DcParamObject implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(mSubId); + dest.writeInt(mSubId); } private void readFromParcel(Parcel in) { |