修訂 | b1040ba906b22d6ca0ae1dc5f90d68bfba07a50f (tree) |
---|---|
時間 | 2021-02-14 22:44:44 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge remote-tracking branch 'lineage/cm-14.1' into cm-14.1-x86
@@ -1959,7 +1959,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM | ||
1959 | 1959 | int initialPid = data.readInt(); |
1960 | 1960 | String packageName = data.readString(); |
1961 | 1961 | String message = data.readString(); |
1962 | - crashApplication(uid, initialPid, packageName, message); | |
1962 | + crashApplication(uid, initialPid, packageName, message, | |
1963 | + false /*force*/); | |
1963 | 1964 | reply.writeNoException(); |
1964 | 1965 | return true; |
1965 | 1966 | } |
@@ -5523,7 +5524,7 @@ class ActivityManagerProxy implements IActivityManager | ||
5523 | 5524 | } |
5524 | 5525 | |
5525 | 5526 | public void crashApplication(int uid, int initialPid, String packageName, |
5526 | - String message) throws RemoteException { | |
5527 | + String message, boolean force) throws RemoteException { | |
5527 | 5528 | Parcel data = Parcel.obtain(); |
5528 | 5529 | Parcel reply = Parcel.obtain(); |
5529 | 5530 | data.writeInterfaceToken(IActivityManager.descriptor); |
@@ -428,7 +428,7 @@ public interface IActivityManager extends IInterface { | ||
428 | 428 | public boolean isTopOfTask(IBinder token) throws RemoteException; |
429 | 429 | |
430 | 430 | public void crashApplication(int uid, int initialPid, String packageName, |
431 | - String message) throws RemoteException; | |
431 | + String message, boolean force) throws RemoteException; | |
432 | 432 | |
433 | 433 | public String getProviderMimeType(Uri uri, int userId) throws RemoteException; |
434 | 434 |
@@ -154,7 +154,7 @@ public class Notification implements Parcelable | ||
154 | 154 | * <p> |
155 | 155 | * Avoids spamming the system with overly large strings such as full e-mails. |
156 | 156 | */ |
157 | - private static final int MAX_CHARSEQUENCE_LENGTH = 5 * 1024; | |
157 | + private static final int MAX_CHARSEQUENCE_LENGTH = 1024; | |
158 | 158 | |
159 | 159 | /** |
160 | 160 | * Maximum entries of reply text that are accepted by Builder and friends. |
@@ -4973,7 +4973,7 @@ public class Notification implements Parcelable | ||
4973 | 4973 | * consistent during re-posts of the notification. |
4974 | 4974 | */ |
4975 | 4975 | public Message(CharSequence text, long timestamp, CharSequence sender){ |
4976 | - mText = text; | |
4976 | + mText = safeCharSequence(text); | |
4977 | 4977 | mTimestamp = timestamp; |
4978 | 4978 | mSender = sender; |
4979 | 4979 | } |
@@ -5055,7 +5055,7 @@ public class Notification implements Parcelable | ||
5055 | 5055 | } |
5056 | 5056 | bundle.putLong(KEY_TIMESTAMP, mTimestamp); |
5057 | 5057 | if (mSender != null) { |
5058 | - bundle.putCharSequence(KEY_SENDER, mSender); | |
5058 | + bundle.putCharSequence(KEY_SENDER, safeCharSequence(mSender)); | |
5059 | 5059 | } |
5060 | 5060 | if (mDataMimeType != null) { |
5061 | 5061 | bundle.putString(KEY_DATA_MIME_TYPE, mDataMimeType); |
@@ -24,6 +24,7 @@ import android.icu.util.ULocale; | ||
24 | 24 | |
25 | 25 | import com.android.internal.annotations.GuardedBy; |
26 | 26 | |
27 | +import java.util.ArrayList; | |
27 | 28 | import java.util.Arrays; |
28 | 29 | import java.util.Collection; |
29 | 30 | import java.util.HashSet; |
@@ -150,18 +151,18 @@ public final class LocaleList implements Parcelable { | ||
150 | 151 | /** |
151 | 152 | * Creates a new {@link LocaleList}. |
152 | 153 | * |
154 | + * If two or more same locales are passed, the repeated locales will be dropped. | |
153 | 155 | * <p>For empty lists of {@link Locale} items it is better to use {@link #getEmptyLocaleList()}, |
154 | 156 | * which returns a pre-constructed empty list.</p> |
155 | 157 | * |
156 | 158 | * @throws NullPointerException if any of the input locales is <code>null</code>. |
157 | - * @throws IllegalArgumentException if any of the input locales repeat. | |
158 | 159 | */ |
159 | 160 | public LocaleList(@NonNull Locale... list) { |
160 | 161 | if (list.length == 0) { |
161 | 162 | mList = sEmptyList; |
162 | 163 | mStringRepresentation = ""; |
163 | 164 | } else { |
164 | - final Locale[] localeList = new Locale[list.length]; | |
165 | + final ArrayList<Locale> localeList = new ArrayList<>(); | |
165 | 166 | final HashSet<Locale> seenLocales = new HashSet<Locale>(); |
166 | 167 | final StringBuilder sb = new StringBuilder(); |
167 | 168 | for (int i = 0; i < list.length; i++) { |
@@ -169,10 +170,10 @@ public final class LocaleList implements Parcelable { | ||
169 | 170 | if (l == null) { |
170 | 171 | throw new NullPointerException("list[" + i + "] is null"); |
171 | 172 | } else if (seenLocales.contains(l)) { |
172 | - throw new IllegalArgumentException("list[" + i + "] is a repetition"); | |
173 | + // Dropping duplicated locale entries. | |
173 | 174 | } else { |
174 | 175 | final Locale localeClone = (Locale) l.clone(); |
175 | - localeList[i] = localeClone; | |
176 | + localeList.add(localeClone); | |
176 | 177 | sb.append(localeClone.toLanguageTag()); |
177 | 178 | if (i < list.length - 1) { |
178 | 179 | sb.append(','); |
@@ -180,7 +181,7 @@ public final class LocaleList implements Parcelable { | ||
180 | 181 | seenLocales.add(localeClone); |
181 | 182 | } |
182 | 183 | } |
183 | - mList = localeList; | |
184 | + mList = localeList.toArray(new Locale[localeList.size()]); | |
184 | 185 | mStringRepresentation = sb.toString(); |
185 | 186 | } |
186 | 187 | } |
@@ -581,7 +581,16 @@ public class ImageWallpaper extends WallpaperService { | ||
581 | 581 | |
582 | 582 | final FloatBuffer triangleVertices = createMesh(left, top, right, bottom); |
583 | 583 | |
584 | - final int texture = loadTexture(mBackground); | |
584 | + int texture = 0; | |
585 | + try { | |
586 | + texture = loadTexture(mBackground); | |
587 | + } catch (IllegalArgumentException e) { | |
588 | + mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
589 | + mEgl.eglDestroySurface(mEglDisplay, mEglSurface); | |
590 | + mEgl.eglDestroyContext(mEglDisplay, mEglContext); | |
591 | + mEgl.eglTerminate(mEglDisplay); | |
592 | + return false; | |
593 | + } | |
585 | 594 | final int program = buildProgram(sSimpleVS, sSimpleFS); |
586 | 595 | |
587 | 596 | final int attribPosition = glGetAttribLocation(program, "position"); |
@@ -618,6 +618,15 @@ public final class ActiveServices { | ||
618 | 618 | } |
619 | 619 | } |
620 | 620 | |
621 | + void killMisbehavingService(ServiceRecord r, | |
622 | + int appUid, int appPid, String localPackageName) { | |
623 | + synchronized (mAm) { | |
624 | + stopServiceLocked(r); | |
625 | + mAm.crashApplication(appUid, appPid, localPackageName, | |
626 | + "Bad notification for startForeground", true /*force*/); | |
627 | + } | |
628 | + } | |
629 | + | |
621 | 630 | IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { |
622 | 631 | ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage, |
623 | 632 | Binder.getCallingPid(), Binder.getCallingUid(), |
@@ -4306,8 +4306,17 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
4306 | 4306 | return procState; |
4307 | 4307 | } |
4308 | 4308 | |
4309 | + private boolean isCallerShell() { | |
4310 | + final int callingUid = Binder.getCallingUid(); | |
4311 | + return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID; | |
4312 | + } | |
4313 | + | |
4309 | 4314 | @Override |
4310 | 4315 | public boolean setProcessMemoryTrimLevel(String process, int userId, int level) { |
4316 | + if (!isCallerShell()) { | |
4317 | + EventLog.writeEvent(0x534e4554, 160390416, Binder.getCallingUid(), ""); | |
4318 | + throw new SecurityException("Only shell can call it"); | |
4319 | + } | |
4311 | 4320 | synchronized (this) { |
4312 | 4321 | final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); |
4313 | 4322 | if (app == null) { |
@@ -5122,7 +5131,7 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
5122 | 5131 | |
5123 | 5132 | @Override |
5124 | 5133 | public void crashApplication(int uid, int initialPid, String packageName, |
5125 | - String message) { | |
5134 | + String message, boolean force) { | |
5126 | 5135 | if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) |
5127 | 5136 | != PackageManager.PERMISSION_GRANTED) { |
5128 | 5137 | String msg = "Permission Denial: crashApplication() from pid=" |
@@ -5134,7 +5143,8 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
5134 | 5143 | } |
5135 | 5144 | |
5136 | 5145 | synchronized(this) { |
5137 | - mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message); | |
5146 | + mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, | |
5147 | + message, force); | |
5138 | 5148 | } |
5139 | 5149 | } |
5140 | 5150 |
@@ -6639,7 +6649,7 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
6639 | 6649 | } |
6640 | 6650 | } |
6641 | 6651 | |
6642 | - private final boolean attachApplicationLocked(IApplicationThread thread, | |
6652 | + private boolean attachApplicationLocked(@NonNull IApplicationThread thread, | |
6643 | 6653 | int pid) { |
6644 | 6654 | |
6645 | 6655 | // Find the application record that is being attached... either via |
@@ -6887,6 +6897,9 @@ public final class ActivityManagerService extends ActivityManagerNative | ||
6887 | 6897 | |
6888 | 6898 | @Override |
6889 | 6899 | public final void attachApplication(IApplicationThread thread) { |
6900 | + if (thread == null) { | |
6901 | + throw new SecurityException("Invalid application interface"); | |
6902 | + } | |
6890 | 6903 | synchronized (this) { |
6891 | 6904 | int callingPid = Binder.getCallingPid(); |
6892 | 6905 | final long origId = Binder.clearCallingIdentity(); |
@@ -1531,6 +1531,10 @@ final class ActivityRecord { | ||
1531 | 1531 | } |
1532 | 1532 | } |
1533 | 1533 | |
1534 | + int getUid() { | |
1535 | + return info.applicationInfo.uid; | |
1536 | + } | |
1537 | + | |
1534 | 1538 | @Override |
1535 | 1539 | public String toString() { |
1536 | 1540 | if (stringName != null) { |
@@ -3738,6 +3738,11 @@ final class ActivityStack { | ||
3738 | 3738 | |
3739 | 3739 | final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, |
3740 | 3740 | Intent resultData) { |
3741 | + if (srec.app == null || srec.app.thread == null) { | |
3742 | + // Nothing to do if the caller is not attached, because this method should be called | |
3743 | + // from an alive activity. | |
3744 | + return false; | |
3745 | + } | |
3741 | 3746 | final TaskRecord task = srec.task; |
3742 | 3747 | final ArrayList<ActivityRecord> activities = task.mActivities; |
3743 | 3748 | final int start = activities.indexOf(srec); |
@@ -1026,6 +1026,8 @@ class ActivityStarter { | ||
1026 | 1026 | } else { |
1027 | 1027 | callingPid = callingUid = -1; |
1028 | 1028 | } |
1029 | + boolean forceNewTask = false; | |
1030 | + final int filterCallingUid = callingUid >= 0 ? callingUid : realCallingUid; | |
1029 | 1031 | final long origId = Binder.clearCallingIdentity(); |
1030 | 1032 | try { |
1031 | 1033 | synchronized (mService) { |
@@ -1045,6 +1047,9 @@ class ActivityStarter { | ||
1045 | 1047 | |
1046 | 1048 | // Don't modify the client's object! |
1047 | 1049 | intent = new Intent(intent); |
1050 | + if (forceNewTask) { | |
1051 | + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
1052 | + } | |
1048 | 1053 | |
1049 | 1054 | // Collect information about the target of the Intent. |
1050 | 1055 | ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0, |
@@ -1070,7 +1075,17 @@ class ActivityStarter { | ||
1070 | 1075 | return res; |
1071 | 1076 | } |
1072 | 1077 | |
1073 | - resultTo = outActivity[0] != null ? outActivity[0].appToken : null; | |
1078 | + final ActivityRecord started = outActivity[0]; | |
1079 | + if (started != null && started.getUid() == filterCallingUid) { | |
1080 | + // Only the started activity which has the same uid as the source caller can | |
1081 | + // be the caller of next activity. | |
1082 | + resultTo = started.appToken; | |
1083 | + forceNewTask = false; | |
1084 | + } else { | |
1085 | + // Different apps not adjacent to the caller are forced to be new task. | |
1086 | + resultTo = null; | |
1087 | + forceNewTask = true; | |
1088 | + } | |
1074 | 1089 | } |
1075 | 1090 | } |
1076 | 1091 | } finally { |
@@ -242,25 +242,29 @@ class AppErrors { | ||
242 | 242 | } |
243 | 243 | |
244 | 244 | void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { |
245 | - app.crashing = false; | |
246 | - app.crashingReport = null; | |
247 | - app.notResponding = false; | |
248 | - app.notRespondingReport = null; | |
249 | 245 | if (app.anrDialog == fromDialog) { |
250 | 246 | app.anrDialog = null; |
251 | 247 | } |
252 | 248 | if (app.waitDialog == fromDialog) { |
253 | 249 | app.waitDialog = null; |
254 | 250 | } |
251 | + killAppImmediateLocked(app, "user-terminated", "user request after error"); | |
252 | + } | |
253 | + | |
254 | + private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) { | |
255 | + app.crashing = false; | |
256 | + app.crashingReport = null; | |
257 | + app.notResponding = false; | |
258 | + app.notRespondingReport = null; | |
255 | 259 | if (app.pid > 0 && app.pid != MY_PID) { |
256 | - handleAppCrashLocked(app, "user-terminated" /*reason*/, | |
260 | + handleAppCrashLocked(app, reason, | |
257 | 261 | null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); |
258 | - app.kill("user request after error", true); | |
262 | + app.kill(killReason, true); | |
259 | 263 | } |
260 | 264 | } |
261 | 265 | |
262 | 266 | void scheduleAppCrashLocked(int uid, int initialPid, String packageName, |
263 | - String message) { | |
267 | + String message, boolean force) { | |
264 | 268 | ProcessRecord proc = null; |
265 | 269 | |
266 | 270 | // Figure out which process to kill. We don't trust that initialPid |
@@ -291,6 +295,18 @@ class AppErrors { | ||
291 | 295 | } |
292 | 296 | |
293 | 297 | proc.scheduleCrash(message); |
298 | + if (force) { | |
299 | + // If the app is responsive, the scheduled crash will happen as expected | |
300 | + // and then the delayed summary kill will be a no-op. | |
301 | + final ProcessRecord p = proc; | |
302 | + mService.mHandler.postDelayed( | |
303 | + () -> { | |
304 | + synchronized (mService) { | |
305 | + killAppImmediateLocked(p, "forced", "killed for invalid state"); | |
306 | + } | |
307 | + }, | |
308 | + 5000L); | |
309 | + } | |
294 | 310 | } |
295 | 311 | |
296 | 312 | /** |
@@ -448,6 +448,7 @@ final class ServiceRecord extends Binder { | ||
448 | 448 | final String localPackageName = packageName; |
449 | 449 | final int localForegroundId = foregroundId; |
450 | 450 | final Notification _foregroundNoti = foregroundNoti; |
451 | + final ServiceRecord record = this; | |
451 | 452 | ams.mHandler.post(new Runnable() { |
452 | 453 | public void run() { |
453 | 454 | NotificationManagerInternal nm = LocalServices.getService( |
@@ -532,10 +533,8 @@ final class ServiceRecord extends Binder { | ||
532 | 533 | Slog.w(TAG, "Error showing notification for service", e); |
533 | 534 | // If it gave us a garbage notification, it doesn't |
534 | 535 | // get to be foreground. |
535 | - ams.setServiceForeground(name, ServiceRecord.this, | |
536 | - 0, null, 0); | |
537 | - ams.crashApplication(appUid, appPid, localPackageName, | |
538 | - "Bad notification for startForeground: " + e); | |
536 | + ams.mServices.killMisbehavingService(record, | |
537 | + appUid, appPid, localPackageName); | |
539 | 538 | } |
540 | 539 | } |
541 | 540 | }); |
@@ -639,7 +639,7 @@ public class NotificationManagerService extends SystemService { | ||
639 | 639 | try { |
640 | 640 | ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg, |
641 | 641 | "Bad notification posted from package " + pkg |
642 | - + ": " + message); | |
642 | + + ": " + message, true /*force*/); | |
643 | 643 | } catch (RemoteException e) { |
644 | 644 | } finally { |
645 | 645 | Binder.restoreCallingIdentity(ident); |
@@ -107,6 +107,7 @@ import android.app.ActivityManager; | ||
107 | 107 | import android.app.ActivityManagerNative; |
108 | 108 | import android.app.AlarmManager; |
109 | 109 | import android.app.AppOpsManager; |
110 | +import android.app.BroadcastOptions; | |
110 | 111 | import android.app.IActivityManager; |
111 | 112 | import android.app.ResourcesManager; |
112 | 113 | import android.app.admin.IDevicePolicyManager; |
@@ -862,6 +863,10 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
862 | 863 | verificationIntent.setComponent(mIntentFilterVerifierComponent); |
863 | 864 | verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); |
864 | 865 | |
866 | + final long whitelistTimeout = getVerificationTimeout(); | |
867 | + final BroadcastOptions options = BroadcastOptions.makeBasic(); | |
868 | + options.setTemporaryAppWhitelistDuration(whitelistTimeout); | |
869 | + | |
865 | 870 | UserHandle user = new UserHandle(userId); |
866 | 871 | mContext.sendBroadcastAsUser(verificationIntent, user); |
867 | 872 | if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, |
@@ -901,9 +906,6 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
901 | 906 | + verificationId + " packageName:" + packageName); |
902 | 907 | return; |
903 | 908 | } |
904 | - if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, | |
905 | - "Updating IntentFilterVerificationInfo for package " + packageName | |
906 | - +" verificationId:" + verificationId); | |
907 | 909 | |
908 | 910 | synchronized (mPackages) { |
909 | 911 | if (verified) { |
@@ -921,19 +923,51 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
921 | 923 | int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; |
922 | 924 | boolean needUpdate = false; |
923 | 925 | |
924 | - // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have | |
925 | - // already been set by the User thru the Disambiguation dialog | |
926 | + // In a success case, we promote from undefined or ASK to ALWAYS. This | |
927 | + // supports a flow where the app fails validation but then ships an updated | |
928 | + // APK that passes, and therefore deserves to be in ALWAYS. | |
929 | + // | |
930 | + // If validation failed, the undefined state winds up in the basic ASK behavior, | |
931 | + // but apps that previously passed and became ALWAYS are *demoted* out of | |
932 | + // that state, since they would not deserve the ALWAYS behavior in case of a | |
933 | + // clean install. | |
926 | 934 | switch (userStatus) { |
935 | + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: | |
936 | + if (!verified) { | |
937 | + // Don't demote if sysconfig says 'always' | |
938 | + SystemConfig systemConfig = SystemConfig.getInstance(); | |
939 | + ArraySet<String> packages = systemConfig.getLinkedApps(); | |
940 | + if (!packages.contains(packageName)) { | |
941 | + // updatedStatus is already UNDEFINED | |
942 | + needUpdate = true; | |
943 | + | |
944 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
945 | + Slog.d(TAG, "Formerly validated but now failing; demoting"); | |
946 | + } | |
947 | + } else { | |
948 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
949 | + Slog.d(TAG, "Updating bundled package " + packageName | |
950 | + + " failed autoVerify, but sysconfig supersedes"); | |
951 | + } | |
952 | + // leave needUpdate == false here intentionally | |
953 | + } | |
954 | + } | |
955 | + break; | |
956 | + | |
927 | 957 | case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: |
958 | + // Stay in 'undefined' on verification failure | |
928 | 959 | if (verified) { |
929 | 960 | updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; |
930 | - } else { | |
931 | - updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; | |
932 | 961 | } |
933 | 962 | needUpdate = true; |
963 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
964 | + Slog.d(TAG, "Applying update; old=" + userStatus | |
965 | + + " new=" + updatedStatus); | |
966 | + } | |
934 | 967 | break; |
935 | 968 | |
936 | 969 | case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: |
970 | + // Keep in 'ask' on failure | |
937 | 971 | if (verified) { |
938 | 972 | updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; |
939 | 973 | needUpdate = true; |
@@ -949,6 +983,8 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
949 | 983 | packageName, updatedStatus, userId); |
950 | 984 | scheduleWritePackageRestrictionsLocked(userId); |
951 | 985 | } |
986 | + } else { | |
987 | + Slog.i(TAG, "autoVerify ignored when installing for all users"); | |
952 | 988 | } |
953 | 989 | } |
954 | 990 | } |
@@ -12593,20 +12629,26 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
12593 | 12629 | |
12594 | 12630 | // Verify: if target already has an installer package, it must |
12595 | 12631 | // be signed with the same cert as the caller. |
12596 | - if (targetPackageSetting.installerPackageName != null) { | |
12597 | - PackageSetting setting = mSettings.mPackages.get( | |
12598 | - targetPackageSetting.installerPackageName); | |
12599 | - // If the currently set package isn't valid, then it's always | |
12600 | - // okay to change it. | |
12601 | - if (setting != null) { | |
12602 | - if (compareSignatures(callerSignature, | |
12603 | - setting.signatures.mSignatures) | |
12604 | - != PackageManager.SIGNATURE_MATCH) { | |
12605 | - throw new SecurityException( | |
12606 | - "Caller does not have same cert as old installer package " | |
12607 | - + targetPackageSetting.installerPackageName); | |
12608 | - } | |
12632 | + String targetInstallerPackageName = | |
12633 | + targetPackageSetting.installerPackageName; | |
12634 | + PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null : | |
12635 | + mSettings.mPackages.get(targetInstallerPackageName); | |
12636 | + | |
12637 | + if (targetInstallerPkgSetting != null) { | |
12638 | + if (compareSignatures(callerSignature, | |
12639 | + targetInstallerPkgSetting.signatures.mSignatures) | |
12640 | + != PackageManager.SIGNATURE_MATCH) { | |
12641 | + throw new SecurityException( | |
12642 | + "Caller does not have same cert as old installer package " | |
12643 | + + targetInstallerPackageName); | |
12609 | 12644 | } |
12645 | + } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES) | |
12646 | + != PackageManager.PERMISSION_GRANTED) { | |
12647 | + // This is probably an attempt to exploit vulnerability b/150857253 of taking | |
12648 | + // privileged installer permissions when the installer has been uninstalled or | |
12649 | + // was never set. | |
12650 | + EventLog.writeEvent(0x534e4554, "150857253", Binder.getCallingUid(), ""); | |
12651 | + return; | |
12610 | 12652 | } |
12611 | 12653 | |
12612 | 12654 | // Okay! |
@@ -15566,14 +15608,17 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
15566 | 15608 | final String packageName = pkg.packageName; |
15567 | 15609 | |
15568 | 15610 | boolean handlesWebUris = false; |
15569 | - final boolean alreadyVerified; | |
15611 | + ArraySet<String> domains = new ArraySet<>(); | |
15612 | + final boolean previouslyVerified; | |
15613 | + boolean hostSetExpanded = false; | |
15614 | + boolean needToRunVerify = false; | |
15570 | 15615 | synchronized (mPackages) { |
15571 | 15616 | // If this is a new install and we see that we've already run verification for this |
15572 | 15617 | // package, we have nothing to do: it means the state was restored from backup. |
15573 | - final IntentFilterVerificationInfo ivi = | |
15618 | + IntentFilterVerificationInfo ivi = | |
15574 | 15619 | mSettings.getIntentFilterVerificationLPr(packageName); |
15575 | - alreadyVerified = (ivi != null); | |
15576 | - if (!replacing && alreadyVerified) { | |
15620 | + previouslyVerified = (ivi != null); | |
15621 | + if (!replacing && previouslyVerified) { | |
15577 | 15622 | if (DEBUG_DOMAIN_VERIFICATION) { |
15578 | 15623 | Slog.i(TAG, "Package " + packageName + " already verified: status=" |
15579 | 15624 | + ivi.getStatusString()); |
@@ -15581,73 +15626,108 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
15581 | 15626 | return; |
15582 | 15627 | } |
15583 | 15628 | |
15629 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
15630 | + Slog.i(TAG, " Previous verified hosts: " | |
15631 | + + (ivi == null ? "[none]" : ivi.getDomainsString())); | |
15632 | + } | |
15633 | + | |
15584 | 15634 | // If any filters need to be verified, then all need to be. In addition, we need to |
15585 | 15635 | // know whether an updating app has any web navigation intent filters, to re- |
15586 | 15636 | // examine handling policy even if not re-verifying. |
15587 | - boolean needToVerify = false; | |
15637 | + final boolean needsVerification = needsNetworkVerificationLPr(packageName); | |
15588 | 15638 | for (PackageParser.Activity a : pkg.activities) { |
15589 | 15639 | for (ActivityIntentInfo filter : a.intents) { |
15590 | 15640 | if (filter.handlesWebUris(true)) { |
15591 | 15641 | handlesWebUris = true; |
15592 | 15642 | } |
15593 | - if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { | |
15643 | + if (needsVerification && filter.needsVerification()) { | |
15594 | 15644 | if (DEBUG_DOMAIN_VERIFICATION) { |
15595 | - Slog.d(TAG, "Intent filter needs verification, so processing all filters"); | |
15645 | + Slog.d(TAG, "autoVerify requested, processing all filters"); | |
15596 | 15646 | } |
15597 | - needToVerify = true; | |
15647 | + needToRunVerify = true; | |
15598 | 15648 | // It's safe to break out here because filter.needsVerification() |
15599 | - // can only be true if filter.handlesWebUris(true) returns true, so | |
15649 | + // can only be true if filter.handlesWebUris(true) returned true, so | |
15600 | 15650 | // we've already noted that. |
15601 | 15651 | break; |
15602 | 15652 | } |
15603 | 15653 | } |
15604 | 15654 | } |
15605 | 15655 | |
15606 | - // Note whether this app publishes any web navigation handling support at all, | |
15607 | - // and whether there are any web-nav filters that fit the profile for running | |
15608 | - // a verification pass now. | |
15609 | - if (needToVerify) { | |
15656 | + // Compare the new set of recognized hosts if the app is either requesting | |
15657 | + // autoVerify or has previously used autoVerify but no longer does. | |
15658 | + if (needToRunVerify || previouslyVerified) { | |
15610 | 15659 | final int verificationId = mIntentFilterVerificationToken++; |
15611 | 15660 | for (PackageParser.Activity a : pkg.activities) { |
15612 | 15661 | for (ActivityIntentInfo filter : a.intents) { |
15613 | - if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { | |
15662 | + // Run verification against hosts mentioned in any web-nav intent filter, | |
15663 | + // even if the filter matches non-web schemes as well | |
15664 | + if (filter.handlesWebUris(false /*onlyWebSchemes*/)) { | |
15614 | 15665 | if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, |
15615 | 15666 | "Verification needed for IntentFilter:" + filter.toString()); |
15616 | 15667 | mIntentFilterVerifier.addOneIntentFilterVerification( |
15617 | 15668 | verifierUid, userId, verificationId, filter, packageName); |
15669 | + domains.addAll(filter.getHostsList()); | |
15618 | 15670 | count++; |
15619 | 15671 | } |
15620 | 15672 | } |
15621 | 15673 | } |
15622 | 15674 | } |
15675 | + | |
15676 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
15677 | + Slog.i(TAG, " Update published hosts: " + domains.toString()); | |
15678 | + } | |
15679 | + | |
15680 | + // If we've previously verified this same host set (or a subset), we can trust that | |
15681 | + // a current ALWAYS policy is still applicable. If this is the case, we're done. | |
15682 | + // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing | |
15683 | + // hosts in their intent filters, then pushed a new apk that removed them and now | |
15684 | + // passes.) | |
15685 | + // | |
15686 | + // Cases: | |
15687 | + // + still autoVerify (needToRunVerify): | |
15688 | + // - preserve current state if all of: unexpanded, in always | |
15689 | + // - otherwise rerun as usual (fall through) | |
15690 | + // + no longer autoVerify (alreadyVerified && !needToRunVerify) | |
15691 | + // - wipe verification history always | |
15692 | + // - preserve current state if all of: unexpanded, in always | |
15693 | + hostSetExpanded = !previouslyVerified | |
15694 | + || (ivi != null && !ivi.getDomains().containsAll(domains)); | |
15695 | + final int currentPolicy = | |
15696 | + mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); | |
15697 | + final boolean keepCurState = !hostSetExpanded | |
15698 | + && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; | |
15699 | + | |
15700 | + if (needToRunVerify && keepCurState) { | |
15701 | + if (DEBUG_DOMAIN_VERIFICATION) { | |
15702 | + Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify"); | |
15703 | + } | |
15704 | + ArrayList<String> domainsList = new ArrayList<String>(); | |
15705 | + domainsList.addAll(domains); | |
15706 | + ivi.setDomains(domainsList); | |
15707 | + scheduleWriteSettingsLocked(); | |
15708 | + return; | |
15709 | + } else if (previouslyVerified && !needToRunVerify) { | |
15710 | + // Prior autoVerify state but not requesting it now. Clear autoVerify history, | |
15711 | + // and preserve the always policy iff the host set is not expanding. | |
15712 | + clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState); | |
15713 | + return; | |
15714 | + } | |
15623 | 15715 | } |
15624 | 15716 | |
15625 | - if (count > 0) { | |
15626 | - // count > 0 means that we're running a full verification pass | |
15717 | + if (needToRunVerify && count > 0) { | |
15718 | + // app requested autoVerify and has at least one matching intent filter | |
15627 | 15719 | if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count |
15628 | 15720 | + " IntentFilter verification" + (count > 1 ? "s" : "") |
15629 | 15721 | + " for userId:" + userId); |
15630 | 15722 | mIntentFilterVerifier.startVerifications(userId); |
15631 | - } else if (alreadyVerified && handlesWebUris) { | |
15632 | - // App used autoVerify in the past, no longer does, but still handles web | |
15633 | - // navigation starts. | |
15634 | - if (DEBUG_DOMAIN_VERIFICATION) { | |
15635 | - Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy"); | |
15636 | - } | |
15637 | - synchronized (mPackages) { | |
15638 | - clearIntentFilterVerificationsLPw(packageName, userId); | |
15639 | - } | |
15640 | 15723 | } else { |
15641 | 15724 | if (DEBUG_DOMAIN_VERIFICATION) { |
15642 | - Slog.d(TAG, "No web filters or no prior verify policy for " + packageName); | |
15725 | + Slog.d(TAG, "No web filters or no new host policy for " + packageName); | |
15643 | 15726 | } |
15644 | 15727 | } |
15645 | 15728 | } |
15646 | 15729 | |
15647 | - private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { | |
15648 | - final ComponentName cn = filter.activity.getComponentName(); | |
15649 | - final String packageName = cn.getPackageName(); | |
15650 | - | |
15730 | + private boolean needsNetworkVerificationLPr(String packageName) { | |
15651 | 15731 | IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( |
15652 | 15732 | packageName); |
15653 | 15733 | if (ivi == null) { |
@@ -15656,6 +15736,7 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
15656 | 15736 | int status = ivi.getStatus(); |
15657 | 15737 | switch (status) { |
15658 | 15738 | case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: |
15739 | + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: | |
15659 | 15740 | case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: |
15660 | 15741 | return true; |
15661 | 15742 |
@@ -16161,7 +16242,7 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
16161 | 16242 | synchronized (mPackages) { |
16162 | 16243 | if (deletedPs != null) { |
16163 | 16244 | if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { |
16164 | - clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); | |
16245 | + clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true); | |
16165 | 16246 | clearDefaultBrowserIfNeeded(packageName); |
16166 | 16247 | if (outInfo != null) { |
16167 | 16248 | mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); |
@@ -17396,12 +17477,13 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
17396 | 17477 | final int packageCount = mPackages.size(); |
17397 | 17478 | for (int i = 0; i < packageCount; i++) { |
17398 | 17479 | PackageParser.Package pkg = mPackages.valueAt(i); |
17399 | - clearIntentFilterVerificationsLPw(pkg.packageName, userId); | |
17480 | + clearIntentFilterVerificationsLPw(pkg.packageName, userId, true); | |
17400 | 17481 | } |
17401 | 17482 | } |
17402 | 17483 | |
17403 | 17484 | /** This method takes a specific user id as well as UserHandle.USER_ALL. */ |
17404 | - void clearIntentFilterVerificationsLPw(String packageName, int userId) { | |
17485 | + void clearIntentFilterVerificationsLPw(String packageName, int userId, | |
17486 | + boolean alsoResetStatus) { | |
17405 | 17487 | if (userId == UserHandle.USER_ALL) { |
17406 | 17488 | if (mSettings.removeIntentFilterVerificationLPw(packageName, |
17407 | 17489 | sUserManager.getUserIds())) { |
@@ -17410,7 +17492,8 @@ public class PackageManagerService extends IPackageManager.Stub { | ||
17410 | 17492 | } |
17411 | 17493 | } |
17412 | 17494 | } else { |
17413 | - if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { | |
17495 | + if (mSettings.removeIntentFilterVerificationLPw(packageName, userId, | |
17496 | + alsoResetStatus)) { | |
17414 | 17497 | scheduleWritePackageRestrictionsLocked(userId); |
17415 | 17498 | } |
17416 | 17499 | } |
@@ -1322,7 +1322,8 @@ final class Settings { | ||
1322 | 1322 | return result; |
1323 | 1323 | } |
1324 | 1324 | |
1325 | - boolean removeIntentFilterVerificationLPw(String packageName, int userId) { | |
1325 | + boolean removeIntentFilterVerificationLPw(String packageName, int userId, | |
1326 | + boolean alsoResetStatus) { | |
1326 | 1327 | PackageSetting ps = mPackages.get(packageName); |
1327 | 1328 | if (ps == null) { |
1328 | 1329 | if (DEBUG_DOMAIN_VERIFICATION) { |
@@ -1330,7 +1331,9 @@ final class Settings { | ||
1330 | 1331 | } |
1331 | 1332 | return false; |
1332 | 1333 | } |
1333 | - ps.clearDomainVerificationStatusForUser(userId); | |
1334 | + if (alsoResetStatus) { | |
1335 | + ps.clearDomainVerificationStatusForUser(userId); | |
1336 | + } | |
1334 | 1337 | ps.setIntentFilterVerificationInfo(null); |
1335 | 1338 | return true; |
1336 | 1339 | } |
@@ -1338,7 +1341,7 @@ final class Settings { | ||
1338 | 1341 | boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) { |
1339 | 1342 | boolean result = false; |
1340 | 1343 | for (int userId : userIds) { |
1341 | - result |= removeIntentFilterVerificationLPw(packageName, userId); | |
1344 | + result |= removeIntentFilterVerificationLPw(packageName, userId, true); | |
1342 | 1345 | } |
1343 | 1346 | return result; |
1344 | 1347 | } |
@@ -1747,7 +1747,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { | ||
1747 | 1747 | mContext, 0, |
1748 | 1748 | Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), |
1749 | 1749 | mContext.getText(com.android.internal.R.string.chooser_wallpaper)), |
1750 | - 0, null, new UserHandle(serviceUserId))); | |
1750 | + PendingIntent.FLAG_IMMUTABLE, null, new UserHandle(serviceUserId))); | |
1751 | 1751 | if (!mContext.bindServiceAsUser(intent, newConn, |
1752 | 1752 | Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI |
1753 | 1753 | | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, |