diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-07-15 17:02:31 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-07-15 17:02:31 +0000 |
commit | fdac2c77ca20cda9728b286ef6292262f17b3dd0 (patch) | |
tree | 2cd898d1f1c23837b6fc793fadd60cbf6f2aaa67 | |
parent | bb86630860452db7b47416444e07f2913dfdca0a (diff) | |
parent | 5c0d08b9c01ba21b87c7d8ccbf72fb621bc19187 (diff) | |
download | base-fdac2c77ca20cda9728b286ef6292262f17b3dd0.tar.gz |
Merge cherrypicks of [18002380, 16940229, 19101007, 19139540] into sc-platform-release.android-platform-12.0.0_r11
Change-Id: I43cef16c08ee0b8a9c7364fe187234981e9bc238
7 files changed, 113 insertions, 21 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) { diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 42d77cd09689..f5674786f703 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -2957,7 +2957,7 @@ public final class InputMethodManager { @UnsupportedAppUsage public int getInputMethodWindowVisibleHeight() { try { - return mService.getInputMethodWindowVisibleHeight(); + return mService.getInputMethodWindowVisibleHeight(mClient); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index d40c064c62e6..07512135c312 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -67,7 +67,7 @@ interface IInputMethodManager { void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); // This is kept due to @UnsupportedAppUsage. // TODO(Bug 113914148): Consider removing this. - int getInputMethodWindowVisibleHeight(); + int getInputMethodWindowVisibleHeight(in IInputMethodClient client); oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible); /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */ diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 5b7f5c85c1bb..c5c11fd0a924 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -124,6 +124,7 @@ import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Printer; import android.util.Slog; +import android.util.SparseBooleanArray; import android.util.imetracing.ImeTracing; import android.util.proto.ProtoOutputStream; import android.view.IWindowManager; @@ -300,6 +301,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final InputMethodSettings mSettings; final SettingsObserver mSettingsObserver; final IWindowManager mIWindowManager; + private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid = + new SparseBooleanArray(0); final WindowManagerInternal mWindowManagerInternal; final PackageManagerInternal mPackageManagerInternal; final InputManagerInternal mInputManagerInternal; @@ -1334,6 +1337,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub clearPackageChangeState(); } + @Override + public void onUidRemoved(int uid) { + synchronized (mMethodMap) { + mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid); + } + } + private void clearPackageChangeState() { // No need to lock them because we access these fields only on getRegisteredHandler(). mChangedPackages.clear(); @@ -3061,21 +3071,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } final long ident = Binder.clearCallingIdentity(); try { - if (mCurClient == null || client == null - || mCurClient.client.asBinder() != client.asBinder()) { - // We need to check if this is the current client with - // focus in the window manager, to allow this call to - // be made before input is started in it. - final ClientState cs = mClients.get(client.asBinder()); - if (cs == null) { - throw new IllegalArgumentException( - "unknown client " + client.asBinder()); - } - if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid, - cs.selfReportedDisplayId)) { - Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client); - return false; - } + if (!canInteractWithImeLocked(uid, client, "showSoftInput")) { + return false; } if (DEBUG) Slog.v(TAG, "Client requesting input be shown"); return showCurrentInputLocked(windowToken, flags, resultReceiver, reason); @@ -3900,9 +3897,46 @@ public class InputMethodManagerService extends IInputMethodManager.Stub * @return {@link WindowManagerInternal#getInputMethodWindowVisibleHeight(int)} */ @Override - public int getInputMethodWindowVisibleHeight() { - // TODO(yukawa): Should we verify the display ID? - return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId); + @Deprecated + public int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) { + int callingUid = Binder.getCallingUid(); + return Binder.withCleanCallingIdentity(() -> { + final int curTokenDisplayId; + synchronized (mMethodMap) { + if (!canInteractWithImeLocked(callingUid, client, + "getInputMethodWindowVisibleHeight")) { + if (!mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.get(callingUid)) { + EventLog.writeEvent(0x534e4554, "204906124", callingUid, ""); + mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.put(callingUid, true); + } + return 0; + } + // This should probably use the caller's display id, but because this is unsupported + // and maintained only for compatibility, there's no point in fixing it. + curTokenDisplayId = mCurTokenDisplayId; + } + return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId); + }); + } + + private boolean canInteractWithImeLocked(int callingUid, IInputMethodClient client, + String method) { + if (mCurClient == null || client == null + || mCurClient.client.asBinder() != client.asBinder()) { + // We need to check if this is the current client with + // focus in the window manager, to allow this call to + // be made before input is started in it. + final ClientState cs = mClients.get(client.asBinder()); + if (cs == null) { + throw new IllegalArgumentException("unknown client " + client.asBinder()); + } + if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid, + cs.selfReportedDisplayId)) { + Slog.w(TAG, "Ignoring " + method + " of uid " + callingUid + ": " + client); + return false; + } + } + return true; } @Override diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index aa4fa7c6f470..68c97e1b717b 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1803,7 +1803,7 @@ public final class MultiClientInputMethodManagerService { @BinderThread @Override - public int getInputMethodWindowVisibleHeight() { + public int getInputMethodWindowVisibleHeight(IInputMethodClient client) { reportNotSupported(); return 0; } |