diff options
author | Sergey Volnov <volnov@google.com> | 2021-07-24 00:38:10 +0100 |
---|---|---|
committer | Sergey Volnov <volnov@google.com> | 2021-07-27 12:38:31 +0100 |
commit | eacb8c8aeeef5f77f965e6d0a8b572f620fdfe43 (patch) | |
tree | dc8486a8585483b0b597e693e81f9fce4424e0d3 | |
parent | 6ad35a74d8ac665eeb6c6f73eef3e62498de9611 (diff) |
Fix content capture not being usable from hotword detector.
Bug: 194534612
Test: local repro
Change-Id: I58e5c68ea486b4da2f82b9d89440f86a8d507727
3 files changed, 52 insertions, 6 deletions
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 25ea12b1c341..8a42ddfdc19d 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -70,6 +70,7 @@ import android.provider.Settings; import android.service.contentcapture.ActivityEvent.ActivityEventType; import android.service.contentcapture.IDataShareCallback; import android.service.contentcapture.IDataShareReadAdapter; +import android.service.voice.VoiceInteractionManagerInternal; import android.util.ArraySet; import android.util.LocalLog; import android.util.Pair; @@ -302,6 +303,37 @@ public final class ContentCaptureManagerService extends || super.isDisabledLocked(userId); } + @Override + protected void assertCalledByPackageOwner(@NonNull String packageName) { + try { + super.assertCalledByPackageOwner(packageName); + } catch (SecurityException e) { + final int callingUid = Binder.getCallingUid(); + + VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity + hotwordDetectionServiceIdentity = + LocalServices.getService(VoiceInteractionManagerInternal.class) + .getHotwordDetectionServiceIdentity(); + + if (callingUid != hotwordDetectionServiceIdentity.getIsolatedUid()) { + super.assertCalledByPackageOwner(packageName); + return; + } + + final String[] packages = + getContext() + .getPackageManager() + .getPackagesForUid(hotwordDetectionServiceIdentity.getOwnerUid()); + if (packages != null) { + for (String candidate : packages) { + if (packageName.equals(candidate)) return; // Found it + } + } + + throw e; + } + } + private boolean isDisabledBySettingsLocked(@UserIdInt int userId) { return mDisabledBySettings != null && mDisabledBySettings.get(userId); } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 225a8d48114b..904def0af2cf 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -57,6 +57,7 @@ import android.service.contentcapture.FlushMetrics; import android.service.contentcapture.IContentCaptureServiceCallback; import android.service.contentcapture.IDataShareCallback; import android.service.contentcapture.SnapshotData; +import android.service.voice.VoiceInteractionManagerInternal; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; @@ -415,12 +416,25 @@ final class ContentCapturePerUserService } if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class) .hasRunningActivity(callingUid, packageName)) { - final String[] packages = pm.getPackagesForUid(callingUid); - final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; - Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid - + ") passed package (" + packageName + ") owned by UID " + packageUid); - throw new SecurityException("Invalid package: " + packageName); + VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity + hotwordDetectionServiceIdentity = + LocalServices.getService(VoiceInteractionManagerInternal.class) + .getHotwordDetectionServiceIdentity(); + + boolean isHotwordDetectionServiceCall = + hotwordDetectionServiceIdentity != null + && callingUid == hotwordDetectionServiceIdentity.getIsolatedUid() + && packageUid == hotwordDetectionServiceIdentity.getOwnerUid(); + + if (!isHotwordDetectionServiceCall) { + final String[] packages = pm.getPackagesForUid(callingUid); + final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; + Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid + + ") passed package (" + packageName + ") owned by UID " + packageUid); + + throw new SecurityException("Invalid package: " + packageName); + } } } diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 016c5ed36f5f..14616754e160 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -744,7 +744,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * * @throws SecurityException when it's not... */ - protected final void assertCalledByPackageOwner(@NonNull String packageName) { + protected void assertCalledByPackageOwner(@NonNull String packageName) { Objects.requireNonNull(packageName); final int uid = Binder.getCallingUid(); final String[] packages = getContext().getPackageManager().getPackagesForUid(uid); |