diff options
3 files changed, 58 insertions, 0 deletions
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index dce242c9d87c..b785d35d7446 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -20,6 +20,7 @@ import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; +import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION; @@ -905,6 +906,13 @@ public class ParsingPackageUtils { ); } + if (ParsedPermissionUtils.declareDuplicatePermission(pkg)) { + return input.error( + INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, + "Declare duplicate permissions with different protection levels or group." + ); + } + convertNewPermissions(pkg); convertSplitPermissions(pkg); diff --git a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java index 8afa70ec6364..9b465947bce2 100644 --- a/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java +++ b/core/java/android/content/pm/parsing/component/ParsedPermissionUtils.java @@ -25,6 +25,8 @@ import android.content.pm.parsing.result.ParseResult; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; +import android.util.ArrayMap; +import android.util.EventLog; import android.util.Slog; import com.android.internal.R; @@ -32,6 +34,8 @@ import com.android.internal.R; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.util.List; +import java.util.Objects; /** @hide */ public class ParsedPermissionUtils { @@ -233,4 +237,49 @@ public class ParsedPermissionUtils { return ComponentParseUtils.parseAllMetaData(pkg, res, parser, tag, permissionGroup, input); } + + /** + * Determines if a duplicate permission is malformed .i.e. defines different protection level + * or group + */ + private static boolean isMalformedDuplicate(ParsedPermission p1, ParsedPermission 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.isTree() || p2.isTree()) { + return false; + } + + if (p1.getProtectionLevel() != p2.getProtectionLevel()) { + return true; + } + if (!Objects.equals(p1.getGroup(), p2.getGroup())) { + return true; + } + + return false; + } + + /** + * @return {@code true} if the package declares malformed duplicate permissions. + * + */ + public static boolean declareDuplicatePermission(@NonNull ParsingPackage pkg) { + final List<ParsedPermission> permissions = pkg.getPermissions(); + final int size = permissions.size(); + if (size > 0) { + final ArrayMap<String, ParsedPermission> checkDuplicatePerm = new ArrayMap<>(size); + for (int i = 0; i < size; i++) { + final ParsedPermission parsedPermission = permissions.get(i); + final String name = parsedPermission.getName(); + final ParsedPermission perm = checkDuplicatePerm.get(name); + if (isMalformedDuplicate(parsedPermission, perm)) { + // Fix for b/213323615 + EventLog.writeEvent(0x534e4554, "213323615"); + return true; + } + checkDuplicatePerm.put(name, parsedPermission); + } + } + return false; + } } diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index e06e7b6be90a..d0a77a031c99 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -474,6 +474,7 @@ public final class Parcel { */ public final void recycle() { if (DEBUG_RECYCLE) mStack = null; + mClassCookies = null; freeBuffer(); if (mOwnsNativeParcelObject) { |