From aa0667068fd5cb2c6e3f945f5be6c6d637c4224c Mon Sep 17 00:00:00 2001 From: "Alam, Sahibex" Date: Fri, 19 Jul 2024 12:17:58 +0530 Subject: [PATCH 1/2] ASB-Aug 2024 Security Patches integration Integrating Google Android Security Bulletin Patches Test done: STS r29 TCs Passed. Tracked-On: OAM-122527 Signed-off-by: Alam, Sahibex --- ...4-Update-security_patch_level-string.patch | 2 +- ...ipient-cookie-ownership-dif.bulletin.patch | 163 +++++++++++++++ ...r-Disabling-B-frame-support.bulletin.patch | 41 ++++ ...for-non-dynamic-permissions.bulletin.patch | 34 ++++ ...-dynamic-permission-removal.bulletin.patch | 40 ++++ ...g-BAL-bypass-via-bound-serv.bulletin.patch | 115 +++++++++++ ...aspect-ratio-change-request.bulletin.patch | 136 +++++++++++++ ...-while-setup-is-in-progress.bulletin.patch | 68 +++++++ ...flow-in-BinaryXmlSerializer.bulletin.patch | 137 +++++++++++++ ...99_0288-Hide-SAW-subwindows.bulletin.patch | 41 ++++ ...ack-of-DeathMonitor-cookies.bulletin.patch | 188 ++++++++++++++++++ ...er-overflow-in-sdp_utils-cc.bulletin.patch | 63 ++++++ 12 files changed, 1027 insertions(+), 1 deletion(-) create mode 100644 aosp_diff/base_aaos/frameworks/av/40_0040-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/av/41_0041-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0282-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0283-Fix-security-vulnerability-of-non-dynamic-permission-removal.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0284-RESTRICT-AUTOMERGE-Backport-preventing-BAL-bypass-via-bound-serv.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0285-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0286-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0287-Add-the-protection-to-avoid-data-overflow-in-BinaryXmlSerializer.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0288-Hide-SAW-subwindows.bulletin.patch create mode 100644 aosp_diff/base_aaos/hardware/interfaces/13_0013-Keep-track-of-DeathMonitor-cookies.bulletin.patch create mode 100644 aosp_diff/base_aaos/system/bt/59_0059-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch diff --git a/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch b/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch index f37222dd12..76a6936892 100644 --- a/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch +++ b/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch @@ -20,7 +20,7 @@ index 0daae6bdcb..d14bd65167 100644 # It must match one of the Android Security Patch Level strings of the Public Security Bulletins. # If there is no $PLATFORM_SECURITY_PATCH set, keep it empty. - PLATFORM_SECURITY_PATCH := 2022-06-05 -+ PLATFORM_SECURITY_PATCH := 2024-07-01 ++ PLATFORM_SECURITY_PATCH := 2024-08-01 endif .KATI_READONLY := PLATFORM_SECURITY_PATCH diff --git a/aosp_diff/base_aaos/frameworks/av/40_0040-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch b/aosp_diff/base_aaos/frameworks/av/40_0040-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch new file mode 100644 index 0000000000..9cd696ee8c --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/av/40_0040-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch @@ -0,0 +1,163 @@ +From 07df1d8dd95fb6af803f6f44905f2d473bdf7efa Mon Sep 17 00:00:00 2001 +From: Devin Moore +Date: Fri, 23 Feb 2024 19:19:38 +0000 +Subject: [PATCH] libmediatranscoding: handle death recipient cookie ownership + differently + +The ownership of the death recipient cookie is now limited to the +TranscodingResourcePolicy object and the binderDied callback. +They both must be able to delete the cookie object and they both must be +aware of it already being deleted. + +In all cases, the TranscodingResourcePolicy object that needs to be +unregistered will outlive the cookie and the death recipient. + +Calling unlinkToDeath is unneccessary because the last strong ref to the +binder that was linked to death is removed in the unregisterSelf method +which will unlink the binder and death recipient. + +Test: atest CtsMediaTranscodingTestCases MediaSampleReaderNDKTests +Test: adb shell kill -9 `pid media.resource_observer` +Test: delete mResourcePolicy.get() to force destructor after linkToDeath +Bug: 319210610 +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0c674f5ff68daa64b90e1a234061ba9bebe6173c) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0213a7d62ea5545b954145cc53e2bd65ed5dc609) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:686987b9613678fe6540079e85e0d94519551738) +Merged-In: I8e6ba40fe3da30bf8753e7a16ad5c8cd5dfda40b +Change-Id: I8e6ba40fe3da30bf8753e7a16ad5c8cd5dfda40b +--- + .../TranscodingResourcePolicy.cpp | 58 +++++++++++++++++-- + .../include/media/TranscodingResourcePolicy.h | 4 ++ + 2 files changed, 57 insertions(+), 5 deletions(-) + +diff --git a/media/libmediatranscoding/TranscodingResourcePolicy.cpp b/media/libmediatranscoding/TranscodingResourcePolicy.cpp +index af53f64671..1b91362463 100644 +--- a/media/libmediatranscoding/TranscodingResourcePolicy.cpp ++++ b/media/libmediatranscoding/TranscodingResourcePolicy.cpp +@@ -24,6 +24,8 @@ + #include + #include + ++#include ++ + namespace android { + + using Status = ::ndk::ScopedAStatus; +@@ -66,11 +68,31 @@ struct TranscodingResourcePolicy::ResourceObserver : public BnResourceObserver { + TranscodingResourcePolicy* mOwner; + }; + ++// cookie used for death recipients. The TranscodingResourcePolicy ++// that this cookie is associated with must outlive this cookie. It is ++// either deleted by binderDied, or in unregisterSelf which is also called ++// in the destructor of TranscodingResourcePolicy ++class TranscodingResourcePolicyCookie { ++public: ++ TranscodingResourcePolicyCookie(TranscodingResourcePolicy* policy) : mPolicy(policy) {} ++ TranscodingResourcePolicyCookie() = delete; ++ TranscodingResourcePolicy* mPolicy; ++}; ++ ++static std::map> sCookies; ++static uintptr_t sCookieKeyCounter; ++static std::mutex sCookiesMutex; ++ + // static + void TranscodingResourcePolicy::BinderDiedCallback(void* cookie) { +- TranscodingResourcePolicy* owner = reinterpret_cast(cookie); +- if (owner != nullptr) { +- owner->unregisterSelf(); ++ std::lock_guard guard(sCookiesMutex); ++ if (auto it = sCookies.find(reinterpret_cast(cookie)); it != sCookies.end()) { ++ ALOGI("BinderDiedCallback unregistering TranscodingResourcePolicy"); ++ auto policy = reinterpret_cast(it->second->mPolicy); ++ if (policy) { ++ policy->unregisterSelf(); ++ } ++ sCookies.erase(it); + } + // TODO(chz): retry to connecting to IResourceObserverService after failure. + // Also need to have back-up logic if IResourceObserverService is offline for +@@ -88,6 +110,24 @@ TranscodingResourcePolicy::TranscodingResourcePolicy() + } + + TranscodingResourcePolicy::~TranscodingResourcePolicy() { ++ { ++ std::lock_guard guard(sCookiesMutex); ++ ++ // delete all of the cookies associated with this TranscodingResourcePolicy ++ // instance since they are holding pointers to this object that will no ++ // longer be valid. ++ for (auto it = sCookies.begin(); it != sCookies.end();) { ++ const uintptr_t key = it->first; ++ std::lock_guard guard(mCookieKeysLock); ++ if (mCookieKeys.find(key) != mCookieKeys.end()) { ++ // No longer need to track this cookie ++ mCookieKeys.erase(key); ++ it = sCookies.erase(it); ++ } else { ++ it++; ++ } ++ } ++ } + unregisterSelf(); + } + +@@ -123,7 +163,16 @@ void TranscodingResourcePolicy::registerSelf() { + return; + } + +- AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast(this)); ++ std::unique_ptr cookie = ++ std::make_unique(this); ++ uintptr_t cookieKey = sCookieKeyCounter++; ++ sCookies.emplace(cookieKey, std::move(cookie)); ++ { ++ std::lock_guard guard(mCookieKeysLock); ++ mCookieKeys.insert(cookieKey); ++ } ++ ++ AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast(cookieKey)); + + ALOGD("@@@ registered observer"); + mRegistered = true; +@@ -141,7 +190,6 @@ void TranscodingResourcePolicy::unregisterSelf() { + ::ndk::SpAIBinder binder = mService->asBinder(); + if (binder.get() != nullptr) { + Status status = mService->unregisterObserver(mObserver); +- AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast(this)); + } + + mService = nullptr; +diff --git a/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h b/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h +index ee232e7551..4d762b5832 100644 +--- a/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h ++++ b/media/libmediatranscoding/include/media/TranscodingResourcePolicy.h +@@ -22,6 +22,7 @@ + #include + + #include ++#include + namespace aidl { + namespace android { + namespace media { +@@ -48,6 +49,8 @@ private: + bool mRegistered GUARDED_BY(mRegisteredLock); + std::shared_ptr mService GUARDED_BY(mRegisteredLock); + std::shared_ptr mObserver; ++ mutable std::mutex mCookieKeysLock; ++ std::set mCookieKeys; + + mutable std::mutex mCallbackLock; + std::weak_ptr mResourcePolicyCallback +@@ -59,6 +62,7 @@ private: + static void BinderDiedCallback(void* cookie); + + void registerSelf(); ++ // must delete the associated TranscodingResourcePolicyCookie any time this is called + void unregisterSelf(); + void onResourceAvailable(pid_t pid); + }; // class TranscodingUidPolicy +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/av/41_0041-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch b/aosp_diff/base_aaos/frameworks/av/41_0041-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch new file mode 100644 index 0000000000..97f768340e --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/av/41_0041-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch @@ -0,0 +1,41 @@ +From 73d11ac20f91aff263e45555a85643884d656714 Mon Sep 17 00:00:00 2001 +From: Rakesh Kumar +Date: Thu, 30 May 2024 11:17:48 +0000 +Subject: [PATCH] StagefrightRecoder: Disabling B-frame support + +Disabling b-frame support from stagefright recorder in case of +audio source as mic and video source is surface use case only +because screen recorder with microphone doesn't play in sync +if b-frame is enabled. +If the audio source selected is INTERNAL (i.e. device) or +MIC_AND_INTERNAL with screen recorder then b frame is supported. + +Bug: 288549440 +Test: manually check screen recording with audio from mic has audio/video in synch +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:af685c66bab17b71fe1624f76b5d55628f79e6fa) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:da3407f7688f35eb2dce79f1405feeb182241a3c) +Merged-In: I4098655eb9687fb633085333bc140634441566e6 +Change-Id: I4098655eb9687fb633085333bc140634441566e6 +--- + media/libmediaplayerservice/StagefrightRecorder.cpp | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp +index bffd7b3243..209b1f8036 100644 +--- a/media/libmediaplayerservice/StagefrightRecorder.cpp ++++ b/media/libmediaplayerservice/StagefrightRecorder.cpp +@@ -2070,6 +2070,11 @@ status_t StagefrightRecorder::setupVideoEncoder( + + if (tsLayers > 1) { + uint32_t bLayers = std::min(2u, tsLayers - 1); // use up-to 2 B-layers ++ // TODO(b/341121900): Remove this once B frames are handled correctly in screen recorder ++ // use case in case of mic only ++ if (mAudioSource == AUDIO_SOURCE_MIC && mVideoSource == VIDEO_SOURCE_SURFACE) { ++ bLayers = 0; ++ } + uint32_t pLayers = tsLayers - bLayers; + format->setString( + "ts-schema", AStringPrintf("android.generic.%u+%u", pLayers, bLayers)); +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0282-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0282-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch new file mode 100644 index 0000000000..89dbd1c913 --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0282-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch @@ -0,0 +1,34 @@ +From 57ba37a9fc7f118d97d2e4ac7efc5a41d04f2501 Mon Sep 17 00:00:00 2001 +From: Yi-an Chen +Date: Tue, 20 Feb 2024 04:34:57 +0000 +Subject: [PATCH] Fix error handling for non-dynamic permissions + +We only allow removing dynamic permissions. When removePermission() is +called for a non-dynamic permission, in addition to logging it, we +should also return early to avoid the removePermission() call. + +Test: manual +Bug: 321555066 +Fixes: 321711213 +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2b5d63b64b2b8208ccc4f62eac3d8962f981dbf8) +Merged-In: I7336f2fc78804f26e4b2a329870ecdea776595d8 +Change-Id: I7336f2fc78804f26e4b2a329870ecdea776595d8 +--- + .../android/server/pm/permission/PermissionManagerService.java | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +index dd8b96eab3d7..31babe0418b8 100644 +--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java ++++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +@@ -691,6 +691,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + // TODO: switch this back to SecurityException + Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " + + permName); ++ return; + } + mRegistry.removePermission(permName); + } +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0283-Fix-security-vulnerability-of-non-dynamic-permission-removal.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0283-Fix-security-vulnerability-of-non-dynamic-permission-removal.bulletin.patch new file mode 100644 index 0000000000..d601a6f42c --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0283-Fix-security-vulnerability-of-non-dynamic-permission-removal.bulletin.patch @@ -0,0 +1,40 @@ +From 58a0ab5bc7abaa174187a1548982fd74ff18f00d Mon Sep 17 00:00:00 2001 +From: Yi-an Chen +Date: Tue, 23 Apr 2024 21:53:02 +0000 +Subject: [PATCH] Fix security vulnerability of non-dynamic permission removal + +The original removePermission() code in PermissionManagerService +missed a logical negation operator when handling non-dynamic +permissions, causing both +testPermissionPermission_nonDynamicPermission_permissionUnchanged and +testRemovePermission_dynamicPermission_permissionRemoved tests in +DynamicPermissionsTest to fail. + +The corresponding test DynamicPermissionsTest is also updated in the +other CL: ag/27073864 + +Bug: 321711213 +Test: DynamicPermissionsTest on sc-dev and tm-dev locally +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:35d77a77feef62dc108f6478cb9228cc6044f70d) +Merged-In: Id573b75cdcfce3a1df5731ffb00c4228c513e686 +Change-Id: Id573b75cdcfce3a1df5731ffb00c4228c513e686 +--- + .../android/server/pm/permission/PermissionManagerService.java | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +index 31babe0418b8..93f9e1c2295c 100644 +--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java ++++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +@@ -687,7 +687,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { + if (bp == null) { + return; + } +- if (bp.isDynamic()) { ++ if (!bp.isDynamic()) { + // TODO: switch this back to SecurityException + Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " + + permName); +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0284-RESTRICT-AUTOMERGE-Backport-preventing-BAL-bypass-via-bound-serv.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0284-RESTRICT-AUTOMERGE-Backport-preventing-BAL-bypass-via-bound-serv.bulletin.patch new file mode 100644 index 0000000000..ac6b027ae3 --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0284-RESTRICT-AUTOMERGE-Backport-preventing-BAL-bypass-via-bound-serv.bulletin.patch @@ -0,0 +1,115 @@ +From 338e0ac6ac7014f251a4dbdf12c9e058a9df9367 Mon Sep 17 00:00:00 2001 +From: Nan Wu +Date: Tue, 30 Apr 2024 17:20:29 +0000 +Subject: [PATCH] RESTRICT AUTOMERGE Backport preventing BAL bypass via bound + service + +Apply similar fix for WallpaperService to TextToSpeech Service, +Job Service, Print Service, Sync Service and MediaRoute2Provider Service + +Bug: 232798473, 232798676, 336490997 +Test: Manual test. BackgroundActivityLaunchTest +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8fdf4a345e140eba9b4e736d24ab95c67c55a247) +Merged-In: Ib113e45aa18296b4475b90d6dcec5dd5664f4c80 +Change-Id: Ib113e45aa18296b4475b90d6dcec5dd5664f4c80 +--- + .../java/com/android/server/job/JobServiceContext.java | 6 ++++-- + core/java/android/speech/tts/TextToSpeech.java | 3 ++- + .../core/java/com/android/server/content/SyncManager.java | 3 ++- + .../server/media/MediaRoute2ProviderServiceProxy.java | 3 ++- + .../java/com/android/server/print/RemotePrintService.java | 3 ++- + .../texttospeech/TextToSpeechManagerPerUserService.java | 2 +- + 6 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +index 90baa8e54220..8a7c365be130 100644 +--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java ++++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java +@@ -291,11 +291,13 @@ public final class JobServiceContext implements ServiceConnection { + bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND + | Context.BIND_ALMOST_PERCEPTIBLE + | Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS +- | Context.BIND_NOT_APP_COMPONENT_USAGE; ++ | Context.BIND_NOT_APP_COMPONENT_USAGE ++ | Context.BIND_DENY_ACTIVITY_STARTS; + } else { + bindFlags = Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND + | Context.BIND_NOT_PERCEPTIBLE +- | Context.BIND_NOT_APP_COMPONENT_USAGE; ++ | Context.BIND_NOT_APP_COMPONENT_USAGE ++ | Context.BIND_DENY_ACTIVITY_STARTS; + } + binding = mContext.bindServiceAsUser(intent, this, bindFlags, + UserHandle.of(job.getUserId())); +diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java +index 7e8622a0e694..2e162b685ac9 100644 +--- a/core/java/android/speech/tts/TextToSpeech.java ++++ b/core/java/android/speech/tts/TextToSpeech.java +@@ -2379,7 +2379,8 @@ public class TextToSpeech { + boolean connect(String engine) { + Intent intent = new Intent(Engine.INTENT_ACTION_TTS_SERVICE); + intent.setPackage(engine); +- return mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); ++ return mContext.bindService(intent, this, ++ Context.BIND_AUTO_CREATE | Context.BIND_DENY_ACTIVITY_STARTS); + } + + @Override +diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java +index 53c13c7a1268..58652f1e16f7 100644 +--- a/services/core/java/com/android/server/content/SyncManager.java ++++ b/services/core/java/com/android/server/content/SyncManager.java +@@ -221,7 +221,8 @@ public class SyncManager { + + /** Flags used when connecting to a sync adapter service */ + private static final int SYNC_ADAPTER_CONNECTION_FLAGS = Context.BIND_AUTO_CREATE +- | Context.BIND_NOT_FOREGROUND | Context.BIND_ALLOW_OOM_MANAGEMENT; ++ | Context.BIND_NOT_FOREGROUND | Context.BIND_ALLOW_OOM_MANAGEMENT ++ | Context.BIND_DENY_ACTIVITY_STARTS; + + /** Singleton instance. */ + @GuardedBy("SyncManager.class") +diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java +index 21f61ca3978a..30d374e5e59f 100644 +--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java ++++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java +@@ -238,7 +238,8 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider + service.setComponent(mComponentName); + try { + mBound = mContext.bindServiceAsUser(service, this, +- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, ++ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE ++ | Context.BIND_DENY_ACTIVITY_STARTS, + new UserHandle(mUserId)); + if (!mBound && DEBUG) { + Slog.d(TAG, this + ": Bind failed"); +diff --git a/services/print/java/com/android/server/print/RemotePrintService.java b/services/print/java/com/android/server/print/RemotePrintService.java +index 502cd2c60f4a..702ddbb9f912 100644 +--- a/services/print/java/com/android/server/print/RemotePrintService.java ++++ b/services/print/java/com/android/server/print/RemotePrintService.java +@@ -572,7 +572,8 @@ final class RemotePrintService implements DeathRecipient { + + boolean wasBound = mContext.bindServiceAsUser(mIntent, mServiceConnection, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE +- | Context.BIND_INCLUDE_CAPABILITIES | Context.BIND_ALLOW_INSTANT, ++ | Context.BIND_INCLUDE_CAPABILITIES | Context.BIND_ALLOW_INSTANT ++ | Context.BIND_DENY_ACTIVITY_STARTS, + new UserHandle(mUserId)); + + if (!wasBound) { +diff --git a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java +index 55cbc7261e64..c87d6be49405 100644 +--- a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java ++++ b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java +@@ -95,7 +95,7 @@ final class TextToSpeechManagerPerUserService extends + ITextToSpeechSessionCallback callback) { + super(context, + new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE).setPackage(engine), +- Context.BIND_AUTO_CREATE, ++ Context.BIND_AUTO_CREATE | Context.BIND_DENY_ACTIVITY_STARTS, + userId, + ITextToSpeechService.Stub::asInterface); + mEngine = engine; +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0285-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0285-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch new file mode 100644 index 0000000000..ee9e283f7f --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0285-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch @@ -0,0 +1,136 @@ +From 781ce614bc86cbb26cbc0aeb53320eb4c2d5199d Mon Sep 17 00:00:00 2001 +From: Hongwei Wang +Date: Tue, 1 Aug 2023 16:00:31 -0700 +Subject: [PATCH] Rate limiting PiP aspect ratio change request + +Using CountQuotaTrack to limit how frequent an app can request aspect +ratio change via PictureInPictureParams, which could result flood of PiP +resizing requests and freeze the PiP window. + +Note that CountQuotaTrack is initialized out of the WM lock to avoid +dead lock with the AM one. + +Bug: 283103220 +Test: Manually, using the POC app +Test: Manually, switching YT PiP video functions at a regular rate +Test: atest WindowOrganizerTests ActivityThreadTest +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c3f4dd070cfc7f20581779abd83620fc8769fbd4) +Merged-In: Icb7dd17bbf7df573a9bb28f3dc56e90e78384f4f +Change-Id: Icb7dd17bbf7df573a9bb28f3dc56e90e78384f4f +--- + .../server/wm/ActivityClientController.java | 39 +++++++++++++++++++ + .../server/wm/WindowOrganizerTests.java | 6 +++ + 2 files changed, 45 insertions(+) + +diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java +index ee72fc8622a5..b847d2530abb 100644 +--- a/services/core/java/com/android/server/wm/ActivityClientController.java ++++ b/services/core/java/com/android/server/wm/ActivityClientController.java +@@ -78,6 +78,7 @@ import android.view.RemoteAnimationDefinition; + import android.window.SizeConfigurationBuckets; + import android.window.TransitionInfo; + ++import com.android.internal.annotations.VisibleForTesting; + import com.android.internal.app.AssistUtils; + import com.android.internal.policy.IKeyguardDismissCallback; + import com.android.internal.protolog.common.ProtoLog; +@@ -85,6 +86,9 @@ import com.android.server.LocalServices; + import com.android.server.Watchdog; + import com.android.server.pm.parsing.pkg.AndroidPackage; + import com.android.server.uri.NeededUriGrants; ++import com.android.server.utils.quota.Categorizer; ++import com.android.server.utils.quota.Category; ++import com.android.server.utils.quota.CountQuotaTracker; + import com.android.server.vr.VrManagerInternal; + + /** +@@ -100,6 +104,13 @@ class ActivityClientController extends IActivityClientController.Stub { + private final ActivityTaskSupervisor mTaskSupervisor; + private final Context mContext; + ++ // Prevent malicious app abusing the Activity#setPictureInPictureParams API ++ @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker; ++ // Limit to 60 times / minute ++ private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60; ++ // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS ++ private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000; ++ + /** Wrapper around VoiceInteractionServiceManager. */ + private AssistUtils mAssistUtils; + +@@ -719,6 +730,7 @@ class ActivityClientController extends IActivityClientController.Stub { + public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) { + final long origId = Binder.clearCallingIdentity(); + try { ++ ensureSetPipAspectRatioQuotaTracker(); + synchronized (mGlobalLock) { + final ActivityRecord r = ensureValidPictureInPictureActivityParams( + "enterPictureInPictureMode", token, params); +@@ -733,6 +745,7 @@ class ActivityClientController extends IActivityClientController.Stub { + public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) { + final long origId = Binder.clearCallingIdentity(); + try { ++ ensureSetPipAspectRatioQuotaTracker(); + synchronized (mGlobalLock) { + final ActivityRecord r = ensureValidPictureInPictureActivityParams( + "setPictureInPictureParams", token, params); +@@ -766,6 +779,19 @@ class ActivityClientController extends IActivityClientController.Stub { + Binder.restoreCallingIdentity(origId); + } + ++ /** ++ * Initialize the {@link #mSetPipAspectRatioQuotaTracker} if applicable, which should happen ++ * out of {@link #mGlobalLock} to avoid deadlock (AM lock is used in QuotaTrack ctor). ++ */ ++ private void ensureSetPipAspectRatioQuotaTracker() { ++ if (mSetPipAspectRatioQuotaTracker == null) { ++ mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext, ++ Categorizer.SINGLE_CATEGORIZER); ++ mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY, ++ SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS); ++ } ++ } ++ + /** + * Checks the state of the system and the activity associated with the given {@param token} to + * verify that picture-in-picture is supported for that activity. +@@ -790,6 +816,19 @@ class ActivityClientController extends IActivityClientController.Stub { + + ": Current activity does not support picture-in-picture."); + } + ++ // Rate limit how frequent an app can request aspect ratio change via ++ // Activity#setPictureInPictureParams ++ final int userId = UserHandle.getCallingUserId(); ++ if (r.pictureInPictureArgs.hasSetAspectRatio() ++ && params.hasSetAspectRatio() ++ && !r.pictureInPictureArgs.getAspectRatioRational().equals( ++ params.getAspectRatioRational()) ++ && !mSetPipAspectRatioQuotaTracker.noteEvent( ++ userId, r.packageName, "setPipAspectRatio")) { ++ throw new IllegalStateException(caller ++ + ": Too many PiP aspect ratio change requests from " + r.packageName); ++ } ++ + if (params.hasSetAspectRatio() + && !mService.mWindowManager.isValidPictureInPictureAspectRatio( + r.mDisplayContent, params.getAspectRatio())) { +diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +index 75a87ba9e04d..89ffb2b4bfc7 100644 +--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java ++++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +@@ -881,6 +881,12 @@ public class WindowOrganizerTests extends WindowTestsBase { + assertNotNull(o.mInfo); + assertNotNull(o.mInfo.pictureInPictureParams); + ++ // Bypass the quota check, which causes NPE in current test setup. ++ if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) { ++ mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker ++ .setEnabled(false); ++ } ++ + final PictureInPictureParams p2 = new PictureInPictureParams.Builder() + .setAspectRatio(new Rational(3, 4)).build(); + mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2); +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0286-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0286-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch new file mode 100644 index 0000000000..f1227ecf5c --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0286-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch @@ -0,0 +1,68 @@ +From 11a632e1591cd7a8df9ca9551296e845931cb683 Mon Sep 17 00:00:00 2001 +From: Kiran S +Date: Mon, 13 May 2024 05:49:06 +0000 +Subject: [PATCH] Restrict USB poups while setup is in progress + +Test: Cherry pick of http://ag/27094197 +Bug: 294105066 +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2ce2e54a040342373e401f9c2e70035ede4e63ad) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:68363246c210b7f8a70eafa363b77cfcc041eb2d) +Merged-In: I7d54534696fd73f3b94c5b4250142eed9341c5d8 +Change-Id: I7d54534696fd73f3b94c5b4250142eed9341c5d8 +--- + .../usb/UsbProfileGroupSettingsManager.java | 21 +++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +index f63866054064..32bb643b8763 100644 +--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java ++++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +@@ -16,6 +16,8 @@ + + package com.android.server.usb; + ++import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; ++ + import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; + + import android.annotation.NonNull; +@@ -42,6 +44,7 @@ import android.os.AsyncTask; + import android.os.Environment; + import android.os.UserHandle; + import android.os.UserManager; ++import android.provider.Settings; + import android.service.usb.UsbProfileGroupSettingsManagerProto; + import android.service.usb.UsbSettingsAccessoryPreferenceProto; + import android.service.usb.UsbSettingsDevicePreferenceProto; +@@ -908,10 +911,28 @@ class UsbProfileGroupSettingsManager { + return; + } + ++ if (shouldRestrictOverlayActivities()) { ++ return; ++ } ++ + // Start activity with registered intent + resolveActivity(intent, matches, defaultActivity, device, null); + } + ++ private boolean shouldRestrictOverlayActivities() { ++ if (Settings.Secure.getIntForUser( ++ mContext.getContentResolver(), ++ USER_SETUP_COMPLETE, ++ /* defaultValue= */ 1, ++ UserHandle.CURRENT.getIdentifier()) ++ == 0) { ++ Slog.d(TAG, "restricting usb overlay activities as setup is not complete"); ++ return true; ++ } ++ ++ return false; ++ } ++ + public void deviceAttachedForFixedHandler(UsbDevice device, ComponentName component) { + final Intent intent = createDeviceAttachedIntent(device); + +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0287-Add-the-protection-to-avoid-data-overflow-in-BinaryXmlSerializer.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0287-Add-the-protection-to-avoid-data-overflow-in-BinaryXmlSerializer.bulletin.patch new file mode 100644 index 0000000000..9a99575d43 --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0287-Add-the-protection-to-avoid-data-overflow-in-BinaryXmlSerializer.bulletin.patch @@ -0,0 +1,137 @@ +From 5b23e7cf0f7cb3e80e30502ada431fa233f666c0 Mon Sep 17 00:00:00 2001 +From: lpeter +Date: Mon, 20 May 2024 18:04:35 +0000 +Subject: [PATCH] Add the protection to avoid data overflow in + BinaryXmlSerializer.java + +Add an integer overflow check in the writeShort in these two methods: +1.BinaryXmlSerializer#attributeBytesHex +2.BinaryXmlSerializer#attributeBytesBase64 + +Bug: 307288067 +Test: atest BinaryXmlTest +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2f04963358987679cb4cbab085ec78c1b5e0ed0e) +Merged-In: I81f5ed43342d5b906f36f3733c2115232da90ac1 +Change-Id: I81f5ed43342d5b906f36f3733c2115232da90ac1 +--- + .../internal/util/BinaryXmlSerializer.java | 10 ++++ + .../src/android/util/BinaryXmlTest.java | 50 +++++++++++++++++++ + 2 files changed, 60 insertions(+) + +diff --git a/core/java/com/android/internal/util/BinaryXmlSerializer.java b/core/java/com/android/internal/util/BinaryXmlSerializer.java +index 9df4bdb157c8..6e33dada9589 100644 +--- a/core/java/com/android/internal/util/BinaryXmlSerializer.java ++++ b/core/java/com/android/internal/util/BinaryXmlSerializer.java +@@ -97,6 +97,8 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer { + */ + private static final int BUFFER_SIZE = 32_768; + ++ private static final int MAX_UNSIGNED_SHORT = 65_535; ++ + private FastDataOutput mOut; + + /** +@@ -221,6 +223,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer { + if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); + mOut.writeByte(ATTRIBUTE | TYPE_BYTES_HEX); + mOut.writeInternedUTF(name); ++ if (value.length > MAX_UNSIGNED_SHORT) { ++ throw new IOException("attributeBytesHex: input size (" + value.length ++ + ") exceeds maximum allowed size (" + MAX_UNSIGNED_SHORT + ")"); ++ } + mOut.writeShort(value.length); + mOut.write(value); + return this; +@@ -232,6 +238,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer { + if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); + mOut.writeByte(ATTRIBUTE | TYPE_BYTES_BASE64); + mOut.writeInternedUTF(name); ++ if (value.length > MAX_UNSIGNED_SHORT) { ++ throw new IOException("attributeBytesBase64: input size (" + value.length ++ + ") exceeds maximum allowed size (" + MAX_UNSIGNED_SHORT + ")"); ++ } + mOut.writeShort(value.length); + mOut.write(value); + return this; +diff --git a/core/tests/coretests/src/android/util/BinaryXmlTest.java b/core/tests/coretests/src/android/util/BinaryXmlTest.java +index fd625dce0254..b369868c0d9a 100644 +--- a/core/tests/coretests/src/android/util/BinaryXmlTest.java ++++ b/core/tests/coretests/src/android/util/BinaryXmlTest.java +@@ -24,6 +24,8 @@ import static android.util.XmlTest.doVerifyRead; + import static android.util.XmlTest.doVerifyWrite; + + import static org.junit.Assert.assertEquals; ++import static org.junit.Assert.assertThrows; ++import static org.junit.Assert.fail; + import static org.xmlpull.v1.XmlPullParser.START_TAG; + + import android.os.PersistableBundle; +@@ -38,12 +40,15 @@ import java.io.ByteArrayOutputStream; + import java.io.File; + import java.io.FileInputStream; + import java.io.FileOutputStream; ++import java.io.IOException; + import java.io.InputStream; + import java.io.OutputStream; + import java.nio.charset.StandardCharsets; + + @RunWith(AndroidJUnit4.class) + public class BinaryXmlTest { ++ private static final int MAX_UNSIGNED_SHORT = 65_535; ++ + /** + * Verify that we can write and read large numbers of interned + * {@link String} values. +@@ -167,4 +172,49 @@ public class BinaryXmlTest { + } + } + } ++ ++ @Test ++ public void testAttributeBytes_BinaryDataOverflow() throws Exception { ++ final TypedXmlSerializer out = Xml.newBinarySerializer(); ++ final ByteArrayOutputStream os = new ByteArrayOutputStream(); ++ out.setOutput(os, StandardCharsets.UTF_8.name()); ++ ++ final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT + 1]; ++ assertThrows(IOException.class, ++ () -> out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex", ++ testBytes)); ++ ++ assertThrows(IOException.class, ++ () -> out.attributeBytesBase64(/* namespace */ null, /* name */ ++ "attributeBytesBase64", testBytes)); ++ } ++ ++ @Test ++ public void testAttributeBytesHex_MaximumBinaryData() throws Exception { ++ final TypedXmlSerializer out = Xml.newBinarySerializer(); ++ final ByteArrayOutputStream os = new ByteArrayOutputStream(); ++ out.setOutput(os, StandardCharsets.UTF_8.name()); ++ ++ final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT]; ++ try { ++ out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex", testBytes); ++ } catch (Exception e) { ++ fail("testAttributeBytesHex fails with exception: " + e.toString()); ++ } ++ } ++ ++ @Test ++ public void testAttributeBytesBase64_MaximumBinaryData() throws Exception { ++ final TypedXmlSerializer out = Xml.newBinarySerializer(); ++ final ByteArrayOutputStream os = new ByteArrayOutputStream(); ++ out.setOutput(os, StandardCharsets.UTF_8.name()); ++ ++ final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT]; ++ try { ++ out.attributeBytesBase64(/* namespace */ null, /* name */ "attributeBytesBase64", ++ testBytes); ++ } catch (Exception e) { ++ fail("testAttributeBytesBase64 fails with exception: " + e.toString()); ++ } ++ } + } +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0288-Hide-SAW-subwindows.bulletin.patch b/aosp_diff/base_aaos/frameworks/base/99_0288-Hide-SAW-subwindows.bulletin.patch new file mode 100644 index 0000000000..1ce0d05b7e --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0288-Hide-SAW-subwindows.bulletin.patch @@ -0,0 +1,41 @@ +From e411339df935bf4613b019d0d82e44b0591d49ba Mon Sep 17 00:00:00 2001 +From: Linus Tufvesson +Date: Mon, 29 Apr 2024 16:32:15 +0200 +Subject: [PATCH] Hide SAW subwindows + +.. when top window is hidden through Window#setHideOverlayWindows + +Bug: 318683640 +Test: atest CtsWindowManagerDeviceWindow:HideOverlayWindowsTest +Flag: EXEMPT securityfix +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c37bc9147086f497ac7b1595083836014f524d5f) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5a2a9f4991d0c4d28d06e4a9ee73d55f22c14fec) +Merged-In: If19240f5aec2e048de80d75cbbdc00be47622d7f +Change-Id: If19240f5aec2e048de80d75cbbdc00be47622d7f +--- + services/core/java/com/android/server/wm/WindowState.java | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java +index a7fe57960df5..a4ba428143c9 100644 +--- a/services/core/java/com/android/server/wm/WindowState.java ++++ b/services/core/java/com/android/server/wm/WindowState.java +@@ -3348,12 +3348,13 @@ class WindowState extends WindowContainer implements WindowManagerP + } + + void setForceHideNonSystemOverlayWindowIfNeeded(boolean forceHide) { ++ final int baseType = getBaseType(); + if (mSession.mCanAddInternalSystemWindow +- || (!isSystemAlertWindowType(mAttrs.type) && mAttrs.type != TYPE_TOAST)) { ++ || (!isSystemAlertWindowType(baseType) && baseType != TYPE_TOAST)) { + return; + } + +- if (mAttrs.type == TYPE_APPLICATION_OVERLAY && mAttrs.isSystemApplicationOverlay() ++ if (baseType == TYPE_APPLICATION_OVERLAY && mAttrs.isSystemApplicationOverlay() + && mSession.mCanCreateSystemApplicationOverlay) { + return; + } +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/hardware/interfaces/13_0013-Keep-track-of-DeathMonitor-cookies.bulletin.patch b/aosp_diff/base_aaos/hardware/interfaces/13_0013-Keep-track-of-DeathMonitor-cookies.bulletin.patch new file mode 100644 index 0000000000..13b6ab33f3 --- /dev/null +++ b/aosp_diff/base_aaos/hardware/interfaces/13_0013-Keep-track-of-DeathMonitor-cookies.bulletin.patch @@ -0,0 +1,188 @@ +From feac66fe4d71c08669b265093f78fd436be808a4 Mon Sep 17 00:00:00 2001 +From: Devin Moore +Date: Tue, 9 Apr 2024 21:50:41 +0000 +Subject: [PATCH] Keep track of DeathMonitor cookies + +This change keeps track of the objects that the cookies points to so the +serviceDied callback knows when it can use the cookie. + +Test: atest neuralnetworks_utils_hal_aidl_test +Tets: atest NeuralNetworksTest_static +Bug: 319210610 +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:def7a3cf59fa17ba7faa9af14a24f4161bc276bd) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d6f965fab9739d35f69fd042a95e783dc1859f32) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:37c395758d0c495d2122be19e1d4dbba93342ec2) +Merged-In: I418cbc6baa19aa702d9fd2e7d8096fe1a02b7794 +Change-Id: I418cbc6baa19aa702d9fd2e7d8096fe1a02b7794 +--- + .../include/nnapi/hal/aidl/ProtectCallback.h | 11 ++++ + .../aidl/utils/src/ProtectCallback.cpp | 56 ++++++++++++++++--- + neuralnetworks/aidl/utils/test/DeviceTest.cpp | 6 +- + 3 files changed, 64 insertions(+), 9 deletions(-) + +diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h +index ab1108c18..558212d71 100644 +--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h ++++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h +@@ -37,6 +37,8 @@ namespace aidl::android::hardware::neuralnetworks::utils { + // Thread safe class + class DeathMonitor final { + public: ++ explicit DeathMonitor(uintptr_t cookieKey) : kCookieKey(cookieKey) {} ++ + static void serviceDied(void* cookie); + void serviceDied(); + // Precondition: `killable` must be non-null. +@@ -44,9 +46,18 @@ class DeathMonitor final { + // Precondition: `killable` must be non-null. + void remove(hal::utils::IProtectedCallback* killable) const; + ++ uintptr_t getCookieKey() const { return kCookieKey; } ++ ++ ~DeathMonitor(); ++ DeathMonitor(const DeathMonitor&) = delete; ++ DeathMonitor(DeathMonitor&&) noexcept = delete; ++ DeathMonitor& operator=(const DeathMonitor&) = delete; ++ DeathMonitor& operator=(DeathMonitor&&) noexcept = delete; ++ + private: + mutable std::mutex mMutex; + mutable std::vector mObjects GUARDED_BY(mMutex); ++ const uintptr_t kCookieKey; + }; + + class DeathHandler final { +diff --git a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp +index 124641cbb..b68e9755c 100644 +--- a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp ++++ b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp +@@ -26,6 +26,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -34,6 +35,16 @@ + + namespace aidl::android::hardware::neuralnetworks::utils { + ++namespace { ++ ++// Only dereference the cookie if it's valid (if it's in this set) ++// Only used with ndk ++std::mutex sCookiesMutex; ++uintptr_t sCookieKeyCounter GUARDED_BY(sCookiesMutex) = 0; ++std::map> sCookies GUARDED_BY(sCookiesMutex); ++ ++} // namespace ++ + void DeathMonitor::serviceDied() { + std::lock_guard guard(mMutex); + std::for_each(mObjects.begin(), mObjects.end(), +@@ -41,8 +52,24 @@ void DeathMonitor::serviceDied() { + } + + void DeathMonitor::serviceDied(void* cookie) { +- auto deathMonitor = static_cast(cookie); +- deathMonitor->serviceDied(); ++ std::shared_ptr monitor; ++ { ++ std::lock_guard guard(sCookiesMutex); ++ if (auto it = sCookies.find(reinterpret_cast(cookie)); it != sCookies.end()) { ++ monitor = it->second.lock(); ++ sCookies.erase(it); ++ } else { ++ LOG(INFO) ++ << "Service died, but cookie is no longer valid so there is nothing to notify."; ++ return; ++ } ++ } ++ if (monitor) { ++ LOG(INFO) << "Notifying DeathMonitor from serviceDied."; ++ monitor->serviceDied(); ++ } else { ++ LOG(INFO) << "Tried to notify DeathMonitor from serviceDied but could not promote."; ++ } + } + + void DeathMonitor::add(hal::utils::IProtectedCallback* killable) const { +@@ -58,12 +85,25 @@ void DeathMonitor::remove(hal::utils::IProtectedCallback* killable) const { + mObjects.erase(removedIter); + } + ++DeathMonitor::~DeathMonitor() { ++ // lock must be taken so object is not used in OnBinderDied" ++ std::lock_guard guard(sCookiesMutex); ++ sCookies.erase(kCookieKey); ++} ++ + nn::GeneralResult DeathHandler::create(std::shared_ptr object) { + if (object == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::DeathHandler::create must have non-null object"; + } +- auto deathMonitor = std::make_shared(); ++ ++ std::shared_ptr deathMonitor; ++ { ++ std::lock_guard guard(sCookiesMutex); ++ deathMonitor = std::make_shared(sCookieKeyCounter++); ++ sCookies[deathMonitor->getCookieKey()] = deathMonitor; ++ } ++ + auto deathRecipient = ndk::ScopedAIBinder_DeathRecipient( + AIBinder_DeathRecipient_new(DeathMonitor::serviceDied)); + +@@ -71,8 +111,9 @@ nn::GeneralResult DeathHandler::create(std::shared_ptrisRemote()) { +- const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_linkToDeath( +- object->asBinder().get(), deathRecipient.get(), deathMonitor.get())); ++ const auto ret = ndk::ScopedAStatus::fromStatus( ++ AIBinder_linkToDeath(object->asBinder().get(), deathRecipient.get(), ++ reinterpret_cast(deathMonitor->getCookieKey()))); + HANDLE_ASTATUS(ret) << "AIBinder_linkToDeath failed"; + } + +@@ -92,8 +133,9 @@ DeathHandler::DeathHandler(std::shared_ptr object, + + DeathHandler::~DeathHandler() { + if (kObject != nullptr && kDeathRecipient.get() != nullptr && kDeathMonitor != nullptr) { +- const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_unlinkToDeath( +- kObject->asBinder().get(), kDeathRecipient.get(), kDeathMonitor.get())); ++ const auto ret = ndk::ScopedAStatus::fromStatus( ++ AIBinder_unlinkToDeath(kObject->asBinder().get(), kDeathRecipient.get(), ++ reinterpret_cast(kDeathMonitor->getCookieKey()))); + const auto maybeSuccess = handleTransportError(ret); + if (!maybeSuccess.ok()) { + LOG(ERROR) << maybeSuccess.error().message; +diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp +index f121acaf7..059f45254 100644 +--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp ++++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp +@@ -669,7 +669,8 @@ TEST(DeviceTest, prepareModelAsyncCrash) { + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&device]() { +- DeathMonitor::serviceDied(device->getDeathMonitor()); ++ DeathMonitor::serviceDied( ++ reinterpret_cast(device->getDeathMonitor()->getCookieKey())); + return ndk::ScopedAStatus::ok(); + }; + EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _, _)) +@@ -792,7 +793,8 @@ TEST(DeviceTest, prepareModelFromCacheAsyncCrash) { + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&device]() { +- DeathMonitor::serviceDied(device->getDeathMonitor()); ++ DeathMonitor::serviceDied( ++ reinterpret_cast(device->getDeathMonitor()->getCookieKey())); + return ndk::ScopedAStatus::ok(); + }; + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _, _)) +-- +2.45.2.505.gda0bf45e8d-goog + diff --git a/aosp_diff/base_aaos/system/bt/59_0059-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch b/aosp_diff/base_aaos/system/bt/59_0059-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch new file mode 100644 index 0000000000..8a0363daec --- /dev/null +++ b/aosp_diff/base_aaos/system/bt/59_0059-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch @@ -0,0 +1,63 @@ +From 1666883ffa1709b50a16f227287a894341af06c6 Mon Sep 17 00:00:00 2001 +From: Brian Delwiche +Date: Mon, 22 Apr 2024 16:43:29 +0000 +Subject: [PATCH] Fix heap-buffer overflow in sdp_utils.cc + +Fuzzer identifies a case where sdpu_compare_uuid_with_attr crashes with +an out of bounds comparison. Although the bug claims this is due to a +comparison of a uuid with a smaller data field thana the discovery +attribute, my research suggests that this instead stems from a +comparison of a 128 bit UUID with a discovery attribute of some other, +invalid size. + +Add checks for discovery attribute size. + +Bug: 287184435 +Test: atest bluetooth_test_gd_unit, net_test_stack_sdp +Tag: #security +Ignore-AOSP-First: Security +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:99210e2f251e2189c1eede15942c832e017404c2) +Merged-In: Ib536cbeac454efbf6af3d713c05c8e3e077e069b +Change-Id: Ib536cbeac454efbf6af3d713c05c8e3e077e069b +--- + stack/sdp/sdp_utils.cc | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/stack/sdp/sdp_utils.cc b/stack/sdp/sdp_utils.cc +index 3fbafb21f..4520fcd75 100644 +--- a/stack/sdp/sdp_utils.cc ++++ b/stack/sdp/sdp_utils.cc +@@ -944,8 +944,28 @@ bool sdpu_compare_uuid_arrays(uint8_t* p_uuid1, uint32_t len1, uint8_t* p_uuid2, + ******************************************************************************/ + bool sdpu_compare_uuid_with_attr(const Uuid& uuid, tSDP_DISC_ATTR* p_attr) { + int len = uuid.GetShortestRepresentationSize(); +- if (len == 2) return uuid.As16Bit() == p_attr->attr_value.v.u16; +- if (len == 4) return uuid.As32Bit() == p_attr->attr_value.v.u32; ++ if (len == 2) { ++ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == Uuid::kNumBytes16) { ++ return uuid.As16Bit() == p_attr->attr_value.v.u16; ++ } else { ++ LOG(ERROR) << "invalid length for discovery attribute"; ++ return (false); ++ } ++ } ++ if (len == 4) { ++ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == Uuid::kNumBytes32) { ++ return uuid.As32Bit() == p_attr->attr_value.v.u32; ++ } else { ++ LOG(ERROR) << "invalid length for discovery attribute"; ++ return (false); ++ } ++ } ++ ++ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) != Uuid::kNumBytes128) { ++ LOG(ERROR) << "invalid length for discovery attribute"; ++ return (false); ++ } ++ + if (memcmp(uuid.To128BitBE().data(), (void*)p_attr->attr_value.v.array, + Uuid::kNumBytes128) == 0) + return (true); +-- +2.45.2.505.gda0bf45e8d-goog + From 22db0f4fedfa4ed2ef91c02ea114def48b59eb3e Mon Sep 17 00:00:00 2001 From: "Alam, Sahibex" Date: Tue, 20 Aug 2024 08:06:35 +0000 Subject: [PATCH 2/2] ASB-SEP 2024 Security Patches integration Integrating Google Android Security Bulletin Patches Test done: STS r30 TCs Passed. Tracked-On: OAM-123585 Signed-off-by: Alam, Sahibex --- ...4-Update-security_patch_level-string.patch | 2 +- ...check-HDR10-info-param-size.bulletin.patch | 37 ++ ...ore-Sanitized-uri-scheme-by-removing.patch | 85 +++++ ...GE-Delete-keystore-keys-from-Recover.patch | 141 ++++++++ ...ypasses-to-multiple-methods.bulletin.patch | 90 +++++ ...content-s-max-length-to-500.bulletin.patch | 31 ++ ...ith-getLaunchedFromPackage-.bulletin.patch | 175 +++++++++ ...-ext-authenticator-resource.bulletin.patch | 114 ++++++ ...Homepage-prior-to-provision.bulletin.patch | 44 +++ ...rvice-when-timeout-reached-.bulletin.patch | 46 +++ ...checking-security-downgrade.bulletin.patch | 331 ++++++++++++++++++ ...ecure-Connections-downgrade.bulletin.patch | 63 ++++ ...t-with-key-length-downgrade.bulletin.patch | 57 +++ ...r-to-call-IKeystoreMaintena.bulletin.patch | 55 +++ 14 files changed, 1270 insertions(+), 1 deletion(-) create mode 100644 aosp_diff/base_aaos/frameworks/av/42_0042-omx-check-HDR10-info-param-size.bulletin.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0289-DO-NOT-MERGE-Ignore-Sanitized-uri-scheme-by-removing.patch create mode 100644 aosp_diff/base_aaos/frameworks/base/99_0290-RESTRICT-AUTOMERGE-Delete-keystore-keys-from-Recover.patch create mode 100644 aosp_diff/base_aaos/packages/apps/Bluetooth/07_0007-Fix-permission-bypasses-to-multiple-methods.bulletin.patch create mode 100644 aosp_diff/base_aaos/packages/apps/Settings/38_0038-Limit-wifi-item-edit-content-s-max-length-to-500.bulletin.patch create mode 100644 aosp_diff/base_aaos/packages/apps/Settings/39_0039-Replace-getCallingActivity-with-getLaunchedFromPackage-.bulletin.patch create mode 100644 aosp_diff/base_aaos/packages/apps/Settings/40_0040-Ignore-fragment-attr-from-ext-authenticator-resource.bulletin.patch create mode 100644 aosp_diff/base_aaos/packages/apps/Settings/41_0041-RESTRICT-AUTOMERGE-Restrict-Settings-Homepage-prior-to-provision.bulletin.patch create mode 100644 aosp_diff/base_aaos/packages/services/Telecomm/15_0015-Unbind-CallScreeningService-when-timeout-reached-.bulletin.patch create mode 100644 aosp_diff/base_aaos/system/bt/60_0060-Add-support-for-checking-security-downgrade.bulletin.patch create mode 100644 aosp_diff/base_aaos/system/bt/61_0061-Disallow-connect-with-Secure-Connections-downgrade.bulletin.patch create mode 100644 aosp_diff/base_aaos/system/bt/62_0062-Disallow-connect-with-key-length-downgrade.bulletin.patch create mode 100644 aosp_diff/base_aaos/system/sepolicy/13_0013-RESTRICT-AUTOMERGE-Allow-system_server-to-call-IKeystoreMaintena.bulletin.patch diff --git a/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch b/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch index 76a6936892..5688ae882b 100644 --- a/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch +++ b/aosp_diff/base_aaos/build/make/0004-Update-security_patch_level-string.patch @@ -20,7 +20,7 @@ index 0daae6bdcb..d14bd65167 100644 # It must match one of the Android Security Patch Level strings of the Public Security Bulletins. # If there is no $PLATFORM_SECURITY_PATCH set, keep it empty. - PLATFORM_SECURITY_PATCH := 2022-06-05 -+ PLATFORM_SECURITY_PATCH := 2024-08-01 ++ PLATFORM_SECURITY_PATCH := 2024-09-01 endif .KATI_READONLY := PLATFORM_SECURITY_PATCH diff --git a/aosp_diff/base_aaos/frameworks/av/42_0042-omx-check-HDR10-info-param-size.bulletin.patch b/aosp_diff/base_aaos/frameworks/av/42_0042-omx-check-HDR10-info-param-size.bulletin.patch new file mode 100644 index 0000000000..a362ee7e17 --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/av/42_0042-omx-check-HDR10-info-param-size.bulletin.patch @@ -0,0 +1,37 @@ +From 326c584ebafe625723ae5ddae597add1de4c1b33 Mon Sep 17 00:00:00 2001 +From: Wonsik Kim +Date: Fri, 28 Jun 2024 00:33:51 +0000 +Subject: [PATCH] omx: check HDR10+ info param size + +Bug: 329641908 +Test: presubmit +Flag: EXEMPT security fix +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:53298956ba6bb8f147a632d7aaed8566dfc203ee) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f816148a719d2a3bbf432f11da98b3d5fa7de74f) +Merged-In: I72523e1de61e5f947174272b732e170e1c2964df +Change-Id: I72523e1de61e5f947174272b732e170e1c2964df +--- + media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp +index 418302389d..4ab5d10609 100644 +--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp ++++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp +@@ -619,6 +619,13 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getConfig( + if (!isValidOMXParam(outParams)) { + return OMX_ErrorBadParameter; + } ++ if (offsetof(DescribeHDR10PlusInfoParams, nValue) + outParams->nParamSize > ++ outParams->nSize) { ++ ALOGE("b/329641908: too large param size; nParamSize=%u nSize=%u", ++ outParams->nParamSize, outParams->nSize); ++ android_errorWriteLog(0x534e4554, "329641908"); ++ return OMX_ErrorBadParameter; ++ } + + outParams->nParamSizeUsed = info->size(); + +-- +2.46.0.rc2.264.g509ed76dc8-goog + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0289-DO-NOT-MERGE-Ignore-Sanitized-uri-scheme-by-removing.patch b/aosp_diff/base_aaos/frameworks/base/99_0289-DO-NOT-MERGE-Ignore-Sanitized-uri-scheme-by-removing.patch new file mode 100644 index 0000000000..13a14436dc --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0289-DO-NOT-MERGE-Ignore-Sanitized-uri-scheme-by-removing.patch @@ -0,0 +1,85 @@ +From 8cb85afd554e0171a174d79aacc4e2200860cfb9 Mon Sep 17 00:00:00 2001 +From: Kiran Ramachandra +Date: Thu, 30 May 2024 21:21:12 +0000 +Subject: [PATCH] DO NOT MERGE Ignore - Sanitized uri scheme by removing scheme + delimiter + +Initially considered removing unsupported characters as per IANA guidelines, but this could break applications that use custom schemes with asterisks. Instead, opted to remove only the "://" to minimize disruption + +Bug: 261721900 +Test: atest FrameworksCoreTests:android.net.UriTest + +No-Typo-Check: The unit test is specifically written to test few cases, string "http://https://" is not a typo + +NOTE FOR REVIEWERS - original patch and result patch are not identical. +PLEASE REVIEW CAREFULLY. +Diffs between the patches: + @AsbSecurityTest(cveBugId = 261721900) +> + @SmallTest +> + public void testSchemeSanitization() { +> + Uri uri = new Uri.Builder() +> + .scheme("http://https://evil.com:/te:st/") +> + .authority("google.com").path("one/way").build(); +> + assertEquals("httphttpsevil.com:/te:st/", uri.getScheme()); +> + assertEquals("httphttpsevil.com:/te:st/://google.com/one/way", uri.toString()); +> + } +> + + +Original patch: + diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java +old mode 100644 +new mode 100644 +--- + core/java/android/net/Uri.java | 6 +++++- + core/tests/coretests/src/android/net/UriTest.java | 11 +++++++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java +index d71faee4cc8d..ed6705c8fa23 100644 +--- a/core/java/android/net/Uri.java ++++ b/core/java/android/net/Uri.java +@@ -1391,7 +1391,11 @@ public abstract class Uri implements Parcelable, Comparable { + * @param scheme name or {@code null} if this is a relative Uri + */ + public Builder scheme(String scheme) { +- this.scheme = scheme; ++ if (scheme != null) { ++ this.scheme = scheme.replace("://", ""); ++ } else { ++ this.scheme = null; ++ } + return this; + } + +diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java +index 3733bfa586d1..35641285e3c5 100644 +--- a/core/tests/coretests/src/android/net/UriTest.java ++++ b/core/tests/coretests/src/android/net/UriTest.java +@@ -18,6 +18,7 @@ package android.net; + + import android.content.ContentUris; + import android.os.Parcel; ++import android.platform.test.annotations.AsbSecurityTest; + + import androidx.test.filters.SmallTest; + +@@ -88,6 +89,16 @@ public class UriTest extends TestCase { + assertNull(u.getHost()); + } + ++ @AsbSecurityTest(cveBugId = 261721900) ++ @SmallTest ++ public void testSchemeSanitization() { ++ Uri uri = new Uri.Builder() ++ .scheme("http://https://evil.com:/te:st/") ++ .authority("google.com").path("one/way").build(); ++ assertEquals("httphttpsevil.com:/te:st/", uri.getScheme()); ++ assertEquals("httphttpsevil.com:/te:st/://google.com/one/way", uri.toString()); ++ } ++ + @SmallTest + public void testStringUri() { + assertEquals("bob lee", +-- +2.34.1 + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0290-RESTRICT-AUTOMERGE-Delete-keystore-keys-from-Recover.patch b/aosp_diff/base_aaos/frameworks/base/99_0290-RESTRICT-AUTOMERGE-Delete-keystore-keys-from-Recover.patch new file mode 100644 index 0000000000..5bc3197948 --- /dev/null +++ b/aosp_diff/base_aaos/frameworks/base/99_0290-RESTRICT-AUTOMERGE-Delete-keystore-keys-from-Recover.patch @@ -0,0 +1,141 @@ +From b6f7fb547e85f729d9cd650b0544785e16b835de Mon Sep 17 00:00:00 2001 +From: Nikolay Elenkov +Date: Sun, 30 Jun 2024 06:20:30 +0000 +Subject: [PATCH] RESTRICT AUTOMERGE Delete keystore keys from + RecoveryService.rebootRecoveryWithCommand() + +Adds deleteSecrets() to RecoverySystemService. This method is called +from rebootRecoveryWithCommand () before the --wipe_data command is +passed to recovery and the device is force-rebooted. + +deleteSecerts() calls IKeystoreMaintenance.deleteAllKeys() in order to +quickly destroy the keys protecting the synthetic password blobs +used to derive FBE encryption keys. + +The intent is to make FBE-encrypted data unrecoverable even if the full +data wipe in recovery is interrupted or skipped. + +Bug: 324321147 +Test: Manual - System -> Reset options -> Erase all data. +Test: Hold VolDown key to interrupt reboot and stop at bootloader +screen. +Test: fastboot oem bcd wipe command && fastboot oem bcd wipe recovery +Test: fastboot reboot +Test: Device reboots into recovery and prompts to factory reset: +Test: 'Cannot load Android system. Your data may be corrupt. ...' +(cherry picked from https://android-review.googlesource.com/q/commit:0d00031851e9f5d8ef93947205a7e8b5257f0d8d) +Ignore-AOSP-First: Security fix backport +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9cdf9eae2e02a6c3651379c33c4655368b009d13) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1e81807b183f08c9b7a68d225afff8b9ffb60fbe) +Merged-In: I5eb8e97f3ae1a18d5e7e7c2c7eca048ebff3440a +Change-Id: I5eb8e97f3ae1a18d5e7e7c2c7eca048ebff3440a +--- + .../security/AndroidKeyStoreMaintenance.java | 22 +++++++++++++++++++ + .../recoverysystem/RecoverySystemService.java | 19 ++++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java +index 919a93b8f107..b2d1755bb860 100644 +--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java ++++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java +@@ -18,8 +18,10 @@ package android.security; + + import android.annotation.NonNull; + import android.annotation.Nullable; ++import android.os.RemoteException; + import android.os.ServiceManager; + import android.os.ServiceSpecificException; ++import android.os.StrictMode; + import android.security.maintenance.IKeystoreMaintenance; + import android.system.keystore2.Domain; + import android.system.keystore2.KeyDescriptor; +@@ -183,4 +185,24 @@ public class AndroidKeyStoreMaintenance { + return SYSTEM_ERROR; + } + } ++ ++ /** ++ * Deletes all keys in all KeyMint devices. ++ * Called by RecoverySystem before rebooting to recovery in order to delete all KeyMint keys, ++ * including synthetic password protector keys (used by LockSettingsService), as well as keys ++ * protecting DE and metadata encryption keys (used by vold). This ensures that FBE-encrypted ++ * data is unrecoverable even if the data wipe in recovery is interrupted or skipped. ++ */ ++ public static void deleteAllKeys() throws KeyStoreException { ++ StrictMode.noteDiskWrite(); ++ try { ++ getService().deleteAllKeys(); ++ } catch (RemoteException | NullPointerException e) { ++ throw new KeyStoreException(SYSTEM_ERROR, ++ "Failure to connect to Keystore while trying to delete all keys."); ++ } catch (ServiceSpecificException e) { ++ throw new KeyStoreException(e.errorCode, ++ "Keystore error while trying to delete all keys."); ++ } ++ } + } +diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +index 13218731af70..23941bc338b8 100644 +--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java ++++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +@@ -52,6 +52,7 @@ import android.os.ShellCallback; + import android.os.SystemProperties; + import android.provider.DeviceConfig; + import android.sysprop.ApexProperties; ++import android.security.AndroidKeyStoreMaintenance; + import android.util.ArrayMap; + import android.util.ArraySet; + import android.util.FastImmutableArraySet; +@@ -66,6 +67,7 @@ import com.android.internal.widget.RebootEscrowListener; + import com.android.server.LocalServices; + import com.android.server.SystemService; + import com.android.server.pm.ApexManager; ++import com.android.server.utils.Slogf; + + import libcore.io.IoUtils; + +@@ -117,6 +119,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo + static final String LSKF_CAPTURED_TIMESTAMP_PREF = "lskf_captured_timestamp"; + static final String LSKF_CAPTURED_COUNT_PREF = "lskf_captured_count"; + ++ static final String RECOVERY_WIPE_DATA_COMMAND = "--wipe_data"; ++ + private final Injector mInjector; + private final Context mContext; + +@@ -511,17 +515,32 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo + @Override // Binder call + public void rebootRecoveryWithCommand(String command) { + if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]"); ++ ++ boolean isForcedWipe = command != null && command.contains(RECOVERY_WIPE_DATA_COMMAND); + synchronized (sRequestLock) { + if (!setupOrClearBcb(true, command)) { + return; + } + ++ if (isForcedWipe) { ++ deleteSecrets(); ++ } ++ + // Having set up the BCB, go ahead and reboot. + PowerManager pm = mInjector.getPowerManager(); + pm.reboot(PowerManager.REBOOT_RECOVERY); + } + } + ++ private static void deleteSecrets() { ++ Slogf.w(TAG, "deleteSecrets"); ++ try { ++ AndroidKeyStoreMaintenance.deleteAllKeys(); ++ } catch (android.security.KeyStoreException e) { ++ Log.wtf(TAG, "Failed to delete all keys from keystore.", e); ++ } ++ } ++ + private void enforcePermissionForResumeOnReboot() { + if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY) + != PackageManager.PERMISSION_GRANTED +-- +2.34.1 + diff --git a/aosp_diff/base_aaos/packages/apps/Bluetooth/07_0007-Fix-permission-bypasses-to-multiple-methods.bulletin.patch b/aosp_diff/base_aaos/packages/apps/Bluetooth/07_0007-Fix-permission-bypasses-to-multiple-methods.bulletin.patch new file mode 100644 index 0000000000..4cc76417a3 --- /dev/null +++ b/aosp_diff/base_aaos/packages/apps/Bluetooth/07_0007-Fix-permission-bypasses-to-multiple-methods.bulletin.patch @@ -0,0 +1,90 @@ +From a82c33e2e9e702214e932b25d27c25dcec448fc1 Mon Sep 17 00:00:00 2001 +From: Brian Delwiche +Date: Mon, 6 May 2024 17:49:09 +0000 +Subject: [PATCH] Fix permission bypasses to multiple methods + +Researcher reports that some BT calls across Binder are validating only +BT's own permissions and not the calling app's permissions. On +investigation this seems to be due to a missing null check in several BT +permissions checks, which allows a malicious app to pass in a null +AttributionSource and therefore produce a stub AttributionSource chain +which does not properly check for the caller's permissions. + +Add null checks. + +Bug: 242996380 +Test: atest UtilsTest +Test: researcher POC +Tag: #security +Ignore-AOSP-First: Security +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:244e4734d1ed316e8725b0f33e18d8eb709554f1) +Merged-In: I57d80cfa07bd6d3fd410a01764b3db2db9b41b81 +Change-Id: I57d80cfa07bd6d3fd410a01764b3db2db9b41b81 +--- + src/com/android/bluetooth/Utils.java | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/src/com/android/bluetooth/Utils.java b/src/com/android/bluetooth/Utils.java +index f1e8e0f10..ab30c3e55 100644 +--- a/src/com/android/bluetooth/Utils.java ++++ b/src/com/android/bluetooth/Utils.java +@@ -79,6 +79,7 @@ import java.nio.charset.CharsetDecoder; + import java.time.Instant; + import java.time.ZoneId; + import java.time.format.DateTimeFormatter; ++import java.util.Objects; + import java.util.UUID; + import java.util.concurrent.TimeUnit; + +@@ -451,7 +452,8 @@ public final class Utils { + // attributionSource.enforceCallingUid(); + final int result = PermissionChecker.checkPermissionForDataDeliveryFromDataSource( + context, permission, PID_UNKNOWN, +- new AttributionSource(context.getAttributionSource(), attributionSource), message); ++ new AttributionSource(context.getAttributionSource(), ++ Objects.requireNonNull(attributionSource)), message); + if (result == PERMISSION_GRANTED) { + return true; + } +@@ -693,7 +695,8 @@ public final class Utils { + // attributionSource.enforceCallingUid(); + if (PermissionChecker.checkPermissionForDataDeliveryFromDataSource( + context, ACCESS_COARSE_LOCATION, PID_UNKNOWN, +- new AttributionSource(context.getAttributionSource(), attributionSource), ++ new AttributionSource(context.getAttributionSource(), ++ Objects.requireNonNull(attributionSource)), + "Bluetooth location check") == PERMISSION_GRANTED) { + return true; + } +@@ -721,14 +724,16 @@ public final class Utils { + // attributionSource.enforceCallingUid(); + if (PermissionChecker.checkPermissionForDataDeliveryFromDataSource( + context, ACCESS_FINE_LOCATION, PID_UNKNOWN, +- new AttributionSource(context.getAttributionSource(), attributionSource), ++ new AttributionSource(context.getAttributionSource(), ++ Objects.requireNonNull(attributionSource)), + "Bluetooth location check") == PERMISSION_GRANTED) { + return true; + } + + if (PermissionChecker.checkPermissionForDataDeliveryFromDataSource( + context, ACCESS_COARSE_LOCATION, PID_UNKNOWN, +- new AttributionSource(context.getAttributionSource(), attributionSource), ++ new AttributionSource(context.getAttributionSource(), ++ Objects.requireNonNull(attributionSource)), + "Bluetooth location check") == PERMISSION_GRANTED) { + return true; + } +@@ -755,7 +760,8 @@ public final class Utils { + // attributionSource.enforceCallingUid(); + if (PermissionChecker.checkPermissionForDataDeliveryFromDataSource( + context, ACCESS_FINE_LOCATION, PID_UNKNOWN, +- new AttributionSource(context.getAttributionSource(), attributionSource), ++ new AttributionSource(context.getAttributionSource(), ++ Objects.requireNonNull(attributionSource)), + "Bluetooth location check") == PERMISSION_GRANTED) { + return true; + } +-- +2.46.0.rc2.264.g509ed76dc8-goog + diff --git a/aosp_diff/base_aaos/packages/apps/Settings/38_0038-Limit-wifi-item-edit-content-s-max-length-to-500.bulletin.patch b/aosp_diff/base_aaos/packages/apps/Settings/38_0038-Limit-wifi-item-edit-content-s-max-length-to-500.bulletin.patch new file mode 100644 index 0000000000..c34b0edd3d --- /dev/null +++ b/aosp_diff/base_aaos/packages/apps/Settings/38_0038-Limit-wifi-item-edit-content-s-max-length-to-500.bulletin.patch @@ -0,0 +1,31 @@ +From ccabd3d0e7e921941d54180970d5e7de260d32e9 Mon Sep 17 00:00:00 2001 +From: Chaohui Wang +Date: Thu, 2 Nov 2023 11:43:00 +0800 +Subject: [PATCH] Limit wifi item edit content's max length to 500 + +Bug: 293199910 +Test: manual - on "Add network" + +(cherry picked from commit 855053ca4124f2d515b21c469096f8c18bd4829d) +(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:092668676af741719d50ac0f121a8f8461aa21ad) +Merged-In: I303b8c6e0f3c3a1174a047ba98f302042e5db9ae +Change-Id: I303b8c6e0f3c3a1174a047ba98f302042e5db9ae +--- + res/values/styles.xml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/res/values/styles.xml b/res/values/styles.xml +index 8402dec73c..9a9477bb5d 100644 +--- a/res/values/styles.xml ++++ b/res/values/styles.xml +@@ -148,6 +148,7 @@ + @android:style/TextAppearance.DeviceDefault.Medium + ?android:attr/textColorSecondary + @dimen/min_tap_target_size ++ 500 + + +