diff options
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 52 | ||||
-rw-r--r-- | core/java/android/os/Parcel.java | 1 | ||||
-rw-r--r-- | services/core/java/com/android/server/inputmethod/InputMethodManagerService.java | 6 |
3 files changed, 57 insertions, 2 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b3776787cc2b..f9bc36495bbf 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -89,6 +89,7 @@ import android.util.AttributeSet; import android.util.Base64; import android.util.ByteStringUtils; import android.util.DisplayMetrics; +import android.util.EventLog; import android.util.Log; import android.util.PackageUtils; import android.util.Pair; @@ -132,6 +133,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -2501,6 +2503,12 @@ public class PackageParser { } } + if (declareDuplicatePermission(pkg)) { + outError[0] = "Found duplicate permission with a different attribute value."; + mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; + return null; + } + if (supportsSmallScreens < 0 || (supportsSmallScreens > 0 && pkg.applicationInfo.targetSdkVersion >= android.os.Build.VERSION_CODES.DONUT)) { @@ -2540,6 +2548,50 @@ public class PackageParser { return pkg; } + /** + * @return {@code true} if the package declares malformed duplicate permissions. + */ + public static boolean declareDuplicatePermission(@NonNull Package pkg) { + final List<Permission> permissions = pkg.permissions; + final int size = permissions.size(); + if (size > 0) { + final ArrayMap<String, Permission> checkDuplicatePerm = new ArrayMap<>(size); + for (int i = 0; i < size; i++) { + final Permission permissionDefinition = permissions.get(i); + final String name = permissionDefinition.info.name; + final Permission perm = checkDuplicatePerm.get(name); + if (isMalformedDuplicate(permissionDefinition, perm)) { + // Fix for b/213323615 + EventLog.writeEvent(0x534e4554, "213323615"); + return true; + } + checkDuplicatePerm.put(name, permissionDefinition); + } + } + return false; + } + + /** + * Determines if a duplicate permission is malformed .i.e. defines different protection level + * or group. + */ + private static boolean isMalformedDuplicate(Permission p1, Permission p2) { + // Since a permission tree is also added as a permission with normal protection + // level, we need to skip if the parsedPermission is a permission tree. + if (p1 == null || p2 == null || p1.tree || p2.tree) { + return false; + } + + if (p1.info.getProtection() != p2.info.getProtection()) { + return true; + } + if (!Objects.equals(p1.info.group, p2.info.group)) { + return true; + } + + return false; + } + private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) { if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) { diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index fe2e948bfcd9..bb68f9516a55 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -416,6 +416,7 @@ public final class Parcel { */ public final void recycle() { if (DEBUG_RECYCLE) mStack = null; + mClassCookies = null; freeBuffer(); final Parcel[] pool; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 63302705b36f..0b19d762a826 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1484,7 +1484,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub Intent intent = new Intent(ACTION_SHOW_INPUT_METHOD_PICKER) .setPackage(mContext.getPackageName()); - mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0); + mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, + PendingIntent.FLAG_IMMUTABLE); mShowOngoingImeSwitcherForPhones = false; @@ -2176,7 +2177,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.input_method_binding_label); mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( - mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0)); + mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), + PendingIntent.FLAG_IMMUTABLE)); if (bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) { mLastBindTime = SystemClock.uptimeMillis(); |