From 6fb0a581c3bac3abae28b7ba05d3377cdc441180 Mon Sep 17 00:00:00 2001 From: Tad Date: Sun, 7 May 2023 20:02:14 -0400 Subject: [PATCH] 15.1 and 16.0 May ASB work Signed-off-by: Tad --- .../355765-backport.patch | 81 ++++ .../android_frameworks_base/355767.patch | 74 +++ .../android_frameworks_base/355865.patch | 62 +++ .../android_frameworks_native/355772.patch | 35 ++ .../355773-backport.patch | 67 +++ .../355774-backport.patch | 71 +++ .../355777-backport.patch | 446 +++++++++++++++++ .../355765-backport.patch | 81 ++++ .../android_frameworks_base/355767.patch | 74 +++ .../android_frameworks_base/355865.patch | 62 +++ .../0001-Sensors.patch | 2 +- .../android_frameworks_native/355772.patch | 35 ++ .../355773-backport.patch | 67 +++ .../355774-backport.patch | 71 +++ .../355777-backport.patch | 449 ++++++++++++++++++ .../0014-Special_Permissions.patch | 4 +- .../355766-backport.patch | 4 +- Scripts/LineageOS-15.1/Patch.sh | 9 +- Scripts/LineageOS-16.0/Patch.sh | 12 +- 19 files changed, 1699 insertions(+), 7 deletions(-) create mode 100644 Patches/LineageOS-15.1/android_frameworks_base/355765-backport.patch create mode 100644 Patches/LineageOS-15.1/android_frameworks_base/355767.patch create mode 100644 Patches/LineageOS-15.1/android_frameworks_base/355865.patch create mode 100644 Patches/LineageOS-15.1/android_frameworks_native/355772.patch create mode 100644 Patches/LineageOS-15.1/android_frameworks_native/355773-backport.patch create mode 100644 Patches/LineageOS-15.1/android_frameworks_native/355774-backport.patch create mode 100644 Patches/LineageOS-15.1/android_packages_services_Telecomm/355777-backport.patch create mode 100644 Patches/LineageOS-16.0/android_frameworks_base/355765-backport.patch create mode 100644 Patches/LineageOS-16.0/android_frameworks_base/355767.patch create mode 100644 Patches/LineageOS-16.0/android_frameworks_base/355865.patch create mode 100644 Patches/LineageOS-16.0/android_frameworks_native/355772.patch create mode 100644 Patches/LineageOS-16.0/android_frameworks_native/355773-backport.patch create mode 100644 Patches/LineageOS-16.0/android_frameworks_native/355774-backport.patch create mode 100644 Patches/LineageOS-16.0/android_packages_services_Telecomm/355777-backport.patch diff --git a/Patches/LineageOS-15.1/android_frameworks_base/355765-backport.patch b/Patches/LineageOS-15.1/android_frameworks_base/355765-backport.patch new file mode 100644 index 00000000..d8e5f29e --- /dev/null +++ b/Patches/LineageOS-15.1/android_frameworks_base/355765-backport.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Norman +Date: Thu, 9 Feb 2023 12:28:26 -0800 +Subject: [PATCH] Checks if AccessibilityServiceInfo is within parcelable size. + +- If too large when parsing service XMLs then skip this service. +- If too large when a service attempts to update its own info + then throw an error. + +Bug: 261589597 +Test: atest AccessibilityServiceInfoTest +Change-Id: Iffc0cd48cc713f7904d68059e141cb7de5a4b906 +Merged-In: Iffc0cd48cc713f7904d68059e141cb7de5a4b906 +(cherry picked from commit on googleplex-android-review.googlesource.com host: 553232c29079fbeab28f95307d025c1426aa7142) +Merged-In: Iffc0cd48cc713f7904d68059e141cb7de5a4b906 +--- + .../accessibilityservice/AccessibilityService.java | 4 ++++ + .../accessibilityservice/AccessibilityServiceInfo.java | 10 ++++++++++ + .../accessibility/AccessibilityManagerService.java | 6 ++++++ + 3 files changed, 20 insertions(+) + +diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java +index a558d6850af1..5436800026f7 100644 +--- a/core/java/android/accessibilityservice/AccessibilityService.java ++++ b/core/java/android/accessibilityservice/AccessibilityService.java +@@ -1474,6 +1474,10 @@ public abstract class AccessibilityService extends Service { + IAccessibilityServiceConnection connection = + AccessibilityInteractionClient.getInstance().getConnection(mConnectionId); + if (mInfo != null && connection != null) { ++ if (!mInfo.isWithinParcelableSize()) { ++ throw new IllegalStateException( ++ "Cannot update service info: size is larger than safe parcelable limits."); ++ } + try { + connection.setServiceInfo(mInfo); + mInfo = null; +diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +index 06a9b0676d08..9c50805d868c 100644 +--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java ++++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +@@ -26,6 +26,7 @@ import android.content.res.Resources; + import android.content.res.TypedArray; + import android.content.res.XmlResourceParser; + import android.hardware.fingerprint.FingerprintManager; ++import android.os.IBinder; + import android.os.Build; + import android.os.Parcel; + import android.os.Parcelable; +@@ -734,6 +735,15 @@ public class AccessibilityServiceInfo implements Parcelable { + return 0; + } + ++ /** @hide */ ++ public final boolean isWithinParcelableSize() { ++ final Parcel parcel = Parcel.obtain(); ++ writeToParcel(parcel, 0); ++ final boolean result = parcel.dataSize() <= IBinder.MAX_IPC_SIZE; ++ parcel.recycle(); ++ return result; ++ } ++ + public void writeToParcel(Parcel parcel, int flagz) { + parcel.writeInt(eventTypes); + parcel.writeStringArray(packageNames); +diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +index 620db7345fab..1e07aa5d4376 100644 +--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java ++++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +@@ -1279,6 +1279,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { + AccessibilityServiceInfo accessibilityServiceInfo; + try { + accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext); ++ if (!accessibilityServiceInfo.isWithinParcelableSize()) { ++ Slog.e(LOG_TAG, "Skipping service " ++ + accessibilityServiceInfo.getResolveInfo().getComponentInfo() ++ + " because service info size is larger than safe parcelable limits."); ++ continue; ++ } + mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo); + } catch (XmlPullParserException | IOException xppe) { + Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe); diff --git a/Patches/LineageOS-15.1/android_frameworks_base/355767.patch b/Patches/LineageOS-15.1/android_frameworks_base/355767.patch new file mode 100644 index 00000000..9aebce49 --- /dev/null +++ b/Patches/LineageOS-15.1/android_frameworks_base/355767.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Stuart +Date: Mon, 21 Nov 2022 17:38:21 -0800 +Subject: [PATCH] enforce stricter rules when registering phoneAccounts + +- include disable accounts when looking up accounts for a package to + check if the limit is reached (10) +- put a new limit of 10 supported schemes +- put a new limit of 256 characters per scheme +- put a new limit of 256 characters per address +- ensure the Icon can write to memory w/o throwing an exception + +bug: 259064622 +bug: 256819769 +Test: cts + unit +Change-Id: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7 +Merged-In: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7 +(cherry picked from commit on googleplex-android-review.googlesource.com host: a66a3156e03fbd1c3a29015db9193d66f2709f98) +Merged-In: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7 +--- + .../java/android/telecom/PhoneAccount.java | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java +index 691e7cf1d34f..7d2f705bf7e7 100644 +--- a/telecomm/java/android/telecom/PhoneAccount.java ++++ b/telecomm/java/android/telecom/PhoneAccount.java +@@ -393,6 +393,11 @@ public final class PhoneAccount implements Parcelable { + + /** + * Sets the address. See {@link PhoneAccount#getAddress}. ++ *

++ * Note: The entire URI value is limited to 256 characters. This check is ++ * enforced when registering the PhoneAccount via ++ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an ++ * {@link IllegalArgumentException} to be thrown if URI is over 256. + * + * @param value The address of the phone account. + * @return The builder. +@@ -426,6 +431,10 @@ public final class PhoneAccount implements Parcelable { + + /** + * Sets the icon. See {@link PhoneAccount#getIcon}. ++ *

++ * Note: An {@link IllegalArgumentException} if the Icon cannot be written to memory. ++ * This check is enforced when registering the PhoneAccount via ++ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} + * + * @param icon The icon to set. + */ +@@ -459,6 +468,10 @@ public final class PhoneAccount implements Parcelable { + /** + * Specifies an additional URI scheme supported by the {@link PhoneAccount}. + * ++ *

++ * Each URI scheme is limited to 256 characters. Adding a scheme over 256 characters will ++ * cause an {@link IllegalArgumentException} to be thrown when the account is registered. ++ * + * @param uriScheme The URI scheme. + * @return The builder. + */ +@@ -472,6 +485,12 @@ public final class PhoneAccount implements Parcelable { + /** + * Specifies the URI schemes supported by the {@link PhoneAccount}. + * ++ *

++ * A max of 10 URI schemes can be added per account. Additionally, each URI scheme is ++ * limited to 256 characters. Adding more than 10 URI schemes or 256 characters on any ++ * scheme will cause an {@link IllegalArgumentException} to be thrown when the account ++ * is registered. ++ * + * @param uriSchemes The URI schemes. + * @return The builder. + */ diff --git a/Patches/LineageOS-15.1/android_frameworks_base/355865.patch b/Patches/LineageOS-15.1/android_frameworks_base/355865.patch new file mode 100644 index 00000000..a984c56c --- /dev/null +++ b/Patches/LineageOS-15.1/android_frameworks_base/355865.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orion Hodson +Date: Thu, 7 Apr 2022 21:42:04 +0100 +Subject: [PATCH] Uri: check authority and scheme as part of determining URI + path + +The interpretation of the path depends on whether the scheme or +authority are specified and should be observed when unparcelling +URIs. + +Bug: 171966843 +Test: atest FrameworksCoreTests:android.net.UriTest +Test: atest com.android.devicehealthchecks.SystemAppCheck +Change-Id: I06981d1c6e387b16df792494523994518848db37 +Merged-In: I06981d1c6e387b16df792494523994518848db37 +(cherry picked from commit f37a94ae920fa5879c557603fc285942ec4b84b1) +(cherry picked from commit on googleplex-android-review.googlesource.com host: c87f0623be4042c39a9b73f7a6e02aa116925e50) +Merged-In: I06981d1c6e387b16df792494523994518848db37 +--- + core/java/android/net/Uri.java | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java +index 5ca3a4106a2d..8af3687af40b 100644 +--- a/core/java/android/net/Uri.java ++++ b/core/java/android/net/Uri.java +@@ -1165,13 +1165,16 @@ public abstract class Uri implements Parcelable, Comparable { + } + + static Uri readFrom(Parcel parcel) { +- return new HierarchicalUri( +- parcel.readString(), +- Part.readFrom(parcel), +- PathPart.readFrom(parcel), +- Part.readFrom(parcel), +- Part.readFrom(parcel) +- ); ++ final String scheme = parcel.readString(); ++ final Part authority = Part.readFrom(parcel); ++ // In RFC3986 the path should be determined based on whether there is a scheme or ++ // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3). ++ final boolean hasSchemeOrAuthority = ++ (scheme != null && scheme.length() > 0) || !authority.isEmpty(); ++ final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel); ++ final Part query = Part.readFrom(parcel); ++ final Part fragment = Part.readFrom(parcel); ++ return new HierarchicalUri(scheme, authority, path, query, fragment); + } + + public int describeContents() { +@@ -2225,6 +2228,11 @@ public abstract class Uri implements Parcelable, Comparable { + } + } + ++ static PathPart readFrom(boolean hasSchemeOrAuthority, Parcel parcel) { ++ final PathPart path = readFrom(parcel); ++ return hasSchemeOrAuthority ? makeAbsolute(path) : path; ++ } ++ + /** + * Creates a path from the encoded string. + * diff --git a/Patches/LineageOS-15.1/android_frameworks_native/355772.patch b/Patches/LineageOS-15.1/android_frameworks_native/355772.patch new file mode 100644 index 00000000..f88e0e68 --- /dev/null +++ b/Patches/LineageOS-15.1/android_frameworks_native/355772.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Devin Moore +Date: Fri, 17 Feb 2023 17:12:46 +0000 +Subject: [PATCH] Check for malformed Sensor Flattenable + +Test: libsensorserviceaidl_fuzzer with testcase from bug +Bug: 269014004 +Merged-In: I0e255c64243c38876fb657cbf942fc1613363216 +Change-Id: I0e255c64243c38876fb657cbf942fc1613363216 +(cherry picked from commit aeec1802f7befc8fbb18313ad3ac0969c3811870) +Merged-In: I0e255c64243c38876fb657cbf942fc1613363216 +(cherry picked from commit on googleplex-android-review.googlesource.com host: f1aa5fb53437ec2fabc9be00099af836da5f07f2) +Merged-In: I0e255c64243c38876fb657cbf942fc1613363216 +--- + libs/sensor/Sensor.cpp | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp +index 2383516c95..f4421c8c65 100644 +--- a/libs/sensor/Sensor.cpp ++++ b/libs/sensor/Sensor.cpp +@@ -576,7 +576,13 @@ bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& output + return false; + } + outputString8.setTo(static_cast(buffer), len); ++ ++ if (size < FlattenableUtils::align<4>(len)) { ++ ALOGE("Malformed Sensor String8 field. Should be in a 4-byte aligned buffer but is not."); ++ return false; ++ } + FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); ++ + return true; + } + diff --git a/Patches/LineageOS-15.1/android_frameworks_native/355773-backport.patch b/Patches/LineageOS-15.1/android_frameworks_native/355773-backport.patch new file mode 100644 index 00000000..986e33bd --- /dev/null +++ b/Patches/LineageOS-15.1/android_frameworks_native/355773-backport.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Devin Moore +Date: Fri, 17 Feb 2023 19:35:25 +0000 +Subject: [PATCH] Remove some new memory leaks from SensorManager + +After catching an error in Sensor::unflatten, there are memory leaks +caught by the fuzzer in the same test case. + +Test: libsensorserviceaidl_fuzzer with testcase from bug +Bug: 269014004 +Merged-In: I509cceb41f56ca117d9475f6f6674244560fe582 +Change-Id: I509cceb41f56ca117d9475f6f6674244560fe582 +(cherry picked from commit c95fa0f0e7c7b73746ff850b85a79fc5f92b784e) +Merged-In: I509cceb41f56ca117d9475f6f6674244560fe582 +(cherry picked from commit on googleplex-android-review.googlesource.com host: ceb0d52273256c6a5c5622bf81b0ac4ba106faa1) +Merged-In: I509cceb41f56ca117d9475f6f6674244560fe582 +--- + libs/sensor/ISensorServer.cpp | 12 ++++++++++-- + libs/sensor/SensorManager.cpp | 5 +++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp +index f20668d1e9..da954ac4c1 100644 +--- a/libs/sensor/ISensorServer.cpp ++++ b/libs/sensor/ISensorServer.cpp +@@ -64,7 +64,11 @@ public: + uint32_t n = reply.readUint32(); + v.setCapacity(n); + while (n--) { +- reply.read(s); ++ if(reply.read(s) != OK) { ++ ALOGE("Failed to read reply from getSensorList"); ++ v.clear(); ++ break; ++ } + v.add(s); + } + return v; +@@ -81,7 +85,11 @@ public: + uint32_t n = reply.readUint32(); + v.setCapacity(n); + while (n--) { +- reply.read(s); ++ if(reply.read(s) != OK) { ++ ALOGE("Failed to read reply from getDynamicSensorList"); ++ v.clear(); ++ break; ++ } + v.add(s); + } + return v; +diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp +index 5fbaf1bf1e..d4cccfe3b5 100644 +--- a/libs/sensor/SensorManager.cpp ++++ b/libs/sensor/SensorManager.cpp +@@ -161,6 +161,11 @@ status_t SensorManager::assertStateLocked() { + + mSensors = mSensorServer->getSensorList(mOpPackageName); + size_t count = mSensors.size(); ++ if (count == 0) { ++ ALOGE("Failed to get Sensor list"); ++ mSensorServer.clear(); ++ return UNKNOWN_ERROR; ++ } + mSensorList = + static_cast(malloc(count * sizeof(Sensor*))); + LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL"); diff --git a/Patches/LineageOS-15.1/android_frameworks_native/355774-backport.patch b/Patches/LineageOS-15.1/android_frameworks_native/355774-backport.patch new file mode 100644 index 00000000..c8641f6e --- /dev/null +++ b/Patches/LineageOS-15.1/android_frameworks_native/355774-backport.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Anthony Stange +Date: Tue, 21 Feb 2023 17:57:38 +0000 +Subject: [PATCH] Add removeInstanceForPackageMethod to SensorManager + +In order to ensure that clients don't leak their sensor manager +instance that we currently store in a static map, they need to be able +to remove their instance. Otherwise, this instance is never removed from +the list and will hang around until our SensorManage instance is +destroyed. + +Bug: 269014004 +Test: Run ./libsensorserviceaidl_fuzzer +Change-Id: I52185f74ae8d28b379440235ca6f03c5089081f5 +(cherry picked from commit 9532f7c682fdd4b1e6e553cd6f61fc0cf2555902) +Merged-In: I52185f74ae8d28b379440235ca6f03c5089081f5 +(cherry picked from commit on googleplex-android-review.googlesource.com host: 4521fbf8095439a1c1681b5c709b306a5dc1d1e3) +Merged-In: I52185f74ae8d28b379440235ca6f03c5089081f5 +--- + libs/sensor/SensorManager.cpp | 10 ++++++++++ + libs/sensor/include/sensor/SensorManager.h | 1 + + services/sensorservice/hidl/SensorManager.cpp | 3 +++ + 3 files changed, 14 insertions(+) + +diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp +index d4cccfe3b5..e5a0438fc5 100644 +--- a/libs/sensor/SensorManager.cpp ++++ b/libs/sensor/SensorManager.cpp +@@ -91,6 +91,16 @@ SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) + return *sensorManager; + } + ++void SensorManager::removeInstanceForPackage(const String16& packageName) { ++ Mutex::Autolock _l(sLock); ++ auto iterator = sPackageInstances.find(packageName); ++ if (iterator != sPackageInstances.end()) { ++ SensorManager* sensorManager = iterator->second; ++ delete sensorManager; ++ sPackageInstances.erase(iterator); ++ } ++} ++ + SensorManager::SensorManager(const String16& opPackageName) + : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) { + Mutex::Autolock _l(mLock); +diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h +index 23f7a918bb..d6eab17c45 100644 +--- a/libs/sensor/include/sensor/SensorManager.h ++++ b/libs/sensor/include/sensor/SensorManager.h +@@ -54,6 +54,7 @@ class SensorManager : public ASensorManager + { + public: + static SensorManager& getInstanceForPackage(const String16& packageName); ++ static void removeInstanceForPackage(const String16& packageName); + ~SensorManager(); + + ssize_t getSensorList(Sensor const* const** list); +diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp +index fee6da1e60..cf2fc448ea 100644 +--- a/services/sensorservice/hidl/SensorManager.cpp ++++ b/services/sensorservice/hidl/SensorManager.cpp +@@ -60,6 +60,9 @@ SensorManager::~SensorManager() { + if (mPollThread.joinable()) { + mPollThread.join(); + } ++ ++ ::android::SensorManager::removeInstanceForPackage( ++ String16(ISensorManager::descriptor)); + } + + // Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow. diff --git a/Patches/LineageOS-15.1/android_packages_services_Telecomm/355777-backport.patch b/Patches/LineageOS-15.1/android_packages_services_Telecomm/355777-backport.patch new file mode 100644 index 00000000..5a686a0a --- /dev/null +++ b/Patches/LineageOS-15.1/android_packages_services_Telecomm/355777-backport.patch @@ -0,0 +1,446 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Stuart +Date: Mon, 21 Nov 2022 17:36:52 -0800 +Subject: [PATCH] enforce stricter rules when registering phoneAccounts + +- include disable accounts when looking up accounts for a package to + check if the limit is reached (10) +- put a new limit of 10 supported schemes +- put a new limit of 256 characters per scheme +- put a new limit of 256 characters per address +- ensure the Icon can write to memory w/o an exception + +bug: 259064622 +bug: 256819769 +Test: cts + unit +Change-Id: I5eb2a127a44d5ec725d0ba39cb0ef478b12013de +Merged-In: I5eb2a127a44d5ec725d0ba39cb0ef478b12013de +(cherry picked from commit on googleplex-android-review.googlesource.com host: 56ef9e15506f71ae555a4535d5c0ac9bd3f587f1) +Merged-In: I5eb2a127a44d5ec725d0ba39cb0ef478b12013de +--- + .../server/telecom/PhoneAccountRegistrar.java | 185 ++++++++++++++++-- + .../server/telecom/TelecomServiceImpl.java | 4 +- + .../tests/PhoneAccountRegistrarTest.java | 101 ++++++++++ + .../telecom/tests/TelecomServiceImplTest.java | 2 +- + 4 files changed, 276 insertions(+), 16 deletions(-) + +diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java +index 4bcd2e5c3..8e7826bd6 100644 +--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java ++++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java +@@ -17,6 +17,7 @@ + package com.android.server.telecom; + + import android.Manifest; ++import android.annotation.NonNull; + import android.content.ComponentName; + import android.content.Context; + import android.content.Intent; +@@ -28,6 +29,7 @@ import android.graphics.Bitmap; + import android.graphics.BitmapFactory; + import android.graphics.drawable.Icon; + import android.net.Uri; ++import android.os.Binder; + import android.os.Bundle; + import android.os.AsyncTask; + import android.os.PersistableBundle; +@@ -137,9 +139,14 @@ public class PhoneAccountRegistrar { + } + + private static final String FILE_NAME = "phone-account-registrar-state.xml"; ++ public static final String ICON_ERROR_MSG = ++ "Icon cannot be written to memory. Try compressing or downsizing"; + @VisibleForTesting + public static final int EXPECTED_STATE_VERSION = 9; + public static final int MAX_PHONE_ACCOUNT_REGISTRATIONS = 10; ++ public static final int MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT = 100; ++ public static final int MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT = 256; ++ public static final int MAX_SCHEMES_PER_ACCOUNT = 10; + + /** Keep in sync with the same in SipSettings.java */ + private static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES"; +@@ -630,12 +637,25 @@ public class PhoneAccountRegistrar { + return getPhoneAccountHandles(0, null, packageName, false, userHandle); + } + ++ ++ /** ++ * includes disabled, includes crossUserAccess ++ */ ++ public List getAllPhoneAccountHandlesForPackage(UserHandle userHandle, ++ String packageName) { ++ return getPhoneAccountHandles(0, null, packageName, true /* includeDisabled */, userHandle); ++ } ++ ++ + /** + * Performs checks before calling addOrReplacePhoneAccount(PhoneAccount) + * + * @param account The {@code PhoneAccount} to add or replace. +- * @throws SecurityException if package does not have BIND_TELECOM_CONNECTION_SERVICE permission ++ * @throws SecurityException if package does not have BIND_TELECOM_CONNECTION_SERVICE ++ * permission + * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_REGISTRATIONS are reached ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT is reached ++ * @throws IllegalArgumentException if writing the Icon to memory will cause an Exception + */ + public void registerPhoneAccount(PhoneAccount account) { + // Enforce the requirement that a connection service for a phone account has the correct +@@ -647,21 +667,155 @@ public class PhoneAccountRegistrar { + throw new SecurityException("PhoneAccount connection service requires " + + "BIND_TELECOM_CONNECTION_SERVICE permission."); + } +- //Enforce an upper bound on the number of PhoneAccount's a package can register. +- // Most apps should only require 1-2. +- if (getPhoneAccountsForPackage( +- account.getAccountHandle().getComponentName().getPackageName(), +- account.getAccountHandle().getUserHandle()).size() ++ enforceCharacterLimit(account); ++ enforceIconSizeLimit(account); ++ enforceMaxPhoneAccountLimit(account); ++ addOrReplacePhoneAccount(account); ++ } ++ ++ /** ++ * Enforce an upper bound on the number of PhoneAccount's a package can register. ++ * Most apps should only require 1-2. * Include disabled accounts. ++ * ++ * @param account to enforce check on ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_REGISTRATIONS are reached ++ */ ++ private void enforceMaxPhoneAccountLimit(@NonNull PhoneAccount account) { ++ final PhoneAccountHandle accountHandle = account.getAccountHandle(); ++ final UserHandle user = accountHandle.getUserHandle(); ++ final ComponentName componentName = accountHandle.getComponentName(); ++ ++ if (getPhoneAccountHandles(0, null, componentName.getPackageName(), ++ true /* includeDisabled */, user).size() + >= MAX_PHONE_ACCOUNT_REGISTRATIONS) { +- Log.w(this, "Phone account %s reached max registration limit for package", +- account.getAccountHandle()); ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceMaxPhoneAccountLimit"); + throw new IllegalArgumentException( + "Error, cannot register phone account " + account.getAccountHandle() + + " because the limit, " + MAX_PHONE_ACCOUNT_REGISTRATIONS + + ", has been reached"); + } ++ } ++ /** ++ * determine if there will be an issue writing the icon to memory ++ * ++ * @param account to enforce check on ++ * @throws IllegalArgumentException if writing the Icon to memory will cause an Exception ++ */ ++ @VisibleForTesting ++ public void enforceIconSizeLimit(PhoneAccount account) { ++ if (account.getIcon() == null) { ++ return; ++ } ++ String text = ""; ++ // convert the icon into a Base64 String ++ try { ++ text = XmlSerialization.writeIconToBase64String(account.getIcon()); ++ } catch (IOException e) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceIconSizeLimit"); ++ throw new IllegalArgumentException(ICON_ERROR_MSG); ++ } ++ } + +- addOrReplacePhoneAccount(account); ++ /** ++ * All {@link PhoneAccount} and{@link PhoneAccountHandle} String and Char-Sequence fields ++ * should be restricted to character limit of MAX_PHONE_ACCOUNT_CHAR_LIMIT to prevent exceptions ++ * when writing large character streams to XML-Serializer. ++ * ++ * @param account to enforce character limit checks on ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT reached ++ */ ++ public void enforceCharacterLimit(PhoneAccount account) { ++ if (account == null) { ++ return; ++ } ++ PhoneAccountHandle handle = account.getAccountHandle(); ++ ++ String[] fields = ++ {"Package Name", "Class Name", "PhoneAccountHandle Id", "Label", "ShortDescription", ++ "GroupId", "Address", "SubscriptionAddress"}; ++ CharSequence[] args = {handle.getComponentName().getPackageName(), ++ handle.getComponentName().getClassName(), handle.getId(), account.getLabel(), ++ account.getShortDescription(), account.getGroupId(), ++ (account.getAddress() != null ? account.getAddress().toString() : ""), ++ (account.getSubscriptionAddress() != null ? ++ account.getSubscriptionAddress().toString() : "")}; ++ ++ for (int i = 0; i < fields.length; i++) { ++ if (args[i] != null && args[i].length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceCharacterLimit"); ++ throw new IllegalArgumentException("The PhoneAccount or PhoneAccountHandle" ++ + fields[i] + " field has an invalid character count. PhoneAccount and " ++ + "PhoneAccountHandle String and Char-Sequence fields are limited to " ++ + MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + " characters."); ++ } ++ } ++ ++ // Enforce limits on the URI Schemes provided ++ enforceLimitsOnSchemes(account); ++ ++ // Enforce limit on the PhoneAccount#mExtras ++ Bundle extras = account.getExtras(); ++ if (extras != null) { ++ if (extras.keySet().size() > MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceCharacterLimit"); ++ throw new IllegalArgumentException("The PhoneAccount#mExtras is limited to " + ++ MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT + " (key,value) pairs."); ++ } ++ ++ for (String key : extras.keySet()) { ++ Object value = extras.get(key); ++ ++ if ((key != null && key.length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT) || ++ (value instanceof String && ++ ((String) value).length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT)) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceCharacterLimit"); ++ throw new IllegalArgumentException("The PhoneAccount#mExtras contains a String" ++ + " key or value that has an invalid character count. PhoneAccount and " ++ + "PhoneAccountHandle String and Char-Sequence fields are limited to " ++ + MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + " characters."); ++ } ++ } ++ } ++ } ++ ++ /** ++ * Enforce a character limit on all PA and PAH string or char-sequence fields. ++ * ++ * @param account to enforce check on ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT reached ++ */ ++ @VisibleForTesting ++ public void enforceLimitsOnSchemes(@NonNull PhoneAccount account) { ++ List schemes = account.getSupportedUriSchemes(); ++ ++ if (schemes == null) { ++ return; ++ } ++ ++ if (schemes.size() > MAX_SCHEMES_PER_ACCOUNT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceLimitsOnSchemes"); ++ throw new IllegalArgumentException( ++ "Error, cannot register phone account " + account.getAccountHandle() ++ + " because the URI scheme limit of " ++ + MAX_SCHEMES_PER_ACCOUNT + " has been reached"); ++ } ++ ++ for (String scheme : schemes) { ++ if (scheme.length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceLimitsOnSchemes"); ++ throw new IllegalArgumentException( ++ "Error, cannot register phone account " + account.getAccountHandle() ++ + " because the max scheme limit of " ++ + MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + " has been reached"); ++ } ++ } + } + + /** +@@ -1374,17 +1528,20 @@ public class PhoneAccountRegistrar { + protected void writeIconIfNonNull(String tagName, Icon value, XmlSerializer serializer) + throws IOException { + if (value != null) { +- ByteArrayOutputStream stream = new ByteArrayOutputStream(); +- value.writeToStream(stream); +- byte[] iconByteArray = stream.toByteArray(); +- String text = Base64.encodeToString(iconByteArray, 0, iconByteArray.length, 0); +- ++ String text = writeIconToBase64String(value); + serializer.startTag(null, tagName); + serializer.text(text); + serializer.endTag(null, tagName); + } + } + ++ public static String writeIconToBase64String(Icon icon) throws IOException { ++ ByteArrayOutputStream stream = new ByteArrayOutputStream(); ++ icon.writeToStream(stream); ++ byte[] iconByteArray = stream.toByteArray(); ++ return Base64.encodeToString(iconByteArray, 0, iconByteArray.length, 0); ++ } ++ + protected void writeLong(String tagName, long value, XmlSerializer serializer) + throws IOException { + serializer.startTag(null, tagName); +diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java +index e3e0a8511..2f9ffdbc4 100644 +--- a/src/com/android/server/telecom/TelecomServiceImpl.java ++++ b/src/com/android/server/telecom/TelecomServiceImpl.java +@@ -59,7 +59,9 @@ import com.android.server.telecom.settings.BlockedNumbersActivity; + import java.io.FileDescriptor; + import java.io.PrintWriter; + import java.util.Collections; ++import java.util.HashSet; + import java.util.List; ++import java.util.Set; + + // TODO: Needed for move to system service: import com.android.internal.R; + +@@ -263,7 +265,7 @@ public class TelecomServiceImpl { + try { + Log.startSession("TSI.gPAFP"); + return new ParceledListSlice<>(mPhoneAccountRegistrar +- .getPhoneAccountsForPackage(packageName, callingUserHandle)); ++ .getAllPhoneAccountHandlesForPackage(callingUserHandle, packageName)); + } catch (Exception e) { + Log.e(this, e, "getPhoneAccountsForPackage %s", packageName); + throw e; +diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java +index a98712c24..d831196f9 100644 +--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java ++++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java +@@ -50,12 +50,24 @@ import java.io.BufferedOutputStream; + import java.io.ByteArrayInputStream; + import java.io.ByteArrayOutputStream; + import java.io.File; ++import java.io.IOException; ++import java.io.OutputStream; + import java.util.Arrays; + import java.util.List; + import java.util.Set; + ++import static org.mockito.ArgumentMatchers.any; ++import static org.mockito.ArgumentMatchers.anyObject; ++import static org.mockito.ArgumentMatchers.isA; + import static org.mockito.Matchers.anyInt; + import static org.mockito.Matchers.anyString; ++import static org.mockito.Mockito.clearInvocations; ++import static org.mockito.Mockito.doThrow; ++import static org.mockito.Mockito.mock; ++import static org.mockito.Mockito.never; ++import static org.mockito.Mockito.spy; ++import static org.mockito.Mockito.times; ++import static org.mockito.Mockito.verify; + import static org.mockito.Mockito.when; + + public class PhoneAccountRegistrarTest extends TelecomTestCase { +@@ -63,6 +75,9 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase { + private static final int MAX_VERSION = Integer.MAX_VALUE; + private static final String FILE_NAME = "phone-account-registrar-test-1223.xml"; + private static final String TEST_LABEL = "right"; ++ private static final String TEST_ID = "123"; ++ private final String PACKAGE_1 = "PACKAGE_1"; ++ private final String PACKAGE_2 = "PACKAGE_2"; + private PhoneAccountRegistrar mRegistrar; + @Mock private TelecomManager mTelecomManager; + @Mock private DefaultDialerCache mDefaultDialerCache; +@@ -764,6 +779,92 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase { + assertTrue(accounts.get(5).getLabel().toString().equals("b")); + } + ++ /** ++ * Ensure an IllegalArgumentException is thrown when adding more than 10 schemes for a single ++ * account ++ */ ++ @Test ++ public void testLimitOnSchemeCount() { ++ PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID); ++ PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, TEST_LABEL); ++ for (int i = 0; i < PhoneAccountRegistrar.MAX_PHONE_ACCOUNT_REGISTRATIONS + 1; i++) { ++ builder.addSupportedUriScheme(Integer.toString(i)); ++ } ++ try { ++ mRegistrar.enforceLimitsOnSchemes(builder.build()); ++ fail("should have hit exception in enforceLimitOnSchemes"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ } ++ } ++ ++ /** ++ * Ensure an IllegalArgumentException is thrown when adding more 256 chars for a single ++ * account ++ */ ++ @Test ++ public void testLimitOnSchemeLength() { ++ PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID); ++ PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, TEST_LABEL); ++ builder.addSupportedUriScheme(generateStringOfLen(257)); ++ try { ++ mRegistrar.enforceLimitsOnSchemes(builder.build()); ++ fail("should have hit exception in enforceLimitOnSchemes"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ } ++ } ++ ++ /** ++ * Ensure an IllegalArgumentException is thrown when adding an address over the limit ++ */ ++ @Test ++ public void testLimitOnAddress() { ++ String text = generateStringOfLen(100); ++ PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID); ++ PhoneAccount.Builder builder = new PhoneAccount.Builder(handle,TEST_LABEL) ++ .setAddress(Uri.fromParts(text, text, text)); ++ try { ++ mRegistrar.enforceCharacterLimit(builder.build()); ++ fail("failed to throw IllegalArgumentException"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ } ++ finally { ++ mRegistrar.unregisterPhoneAccount(handle); ++ } ++ } ++ ++ /** ++ * Ensure an IllegalArgumentException is thrown when an Icon that throws an IOException is given ++ */ ++ @Test ++ public void testLimitOnIcon() throws Exception { ++ Icon mockIcon = mock(Icon.class); ++ // GIVEN ++ PhoneAccount.Builder builder = new PhoneAccount.Builder( ++ makeQuickAccountHandle(TEST_ID), TEST_LABEL).setIcon(mockIcon); ++ try { ++ // WHEN ++ Mockito.doThrow(new IOException()) ++ .when(mockIcon).writeToStream(any(OutputStream.class)); ++ //THEN ++ mRegistrar.enforceIconSizeLimit(builder.build()); ++ fail("failed to throw IllegalArgumentException"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ assertTrue(e.getMessage().contains(PhoneAccountRegistrar.ICON_ERROR_MSG)); ++ } ++ } ++ ++ private String generateStringOfLen(int len){ ++ StringBuilder sb = new StringBuilder(); ++ for(int i=0; i < len; i++){ ++ sb.append("a"); ++ } ++ return sb.toString(); ++ } ++ + private static ComponentName makeQuickConnectionServiceComponentName() { + return new ComponentName( + "com.android.server.telecom.tests", +diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +index afeb7122b..1d46f1abb 100644 +--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java ++++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +@@ -346,7 +346,7 @@ public class TelecomServiceImplTest extends TelecomTestCase { + add(SIP_PA_HANDLE_17); + }}; + when(mFakePhoneAccountRegistrar +- .getPhoneAccountsForPackage(anyString(), any(UserHandle.class))) ++ .getAllPhoneAccountHandlesForPackage(any(UserHandle.class), anyString())) + .thenReturn(phoneAccountHandleList); + makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17); + assertEquals(phoneAccountHandleList, diff --git a/Patches/LineageOS-16.0/android_frameworks_base/355765-backport.patch b/Patches/LineageOS-16.0/android_frameworks_base/355765-backport.patch new file mode 100644 index 00000000..11b9d3c1 --- /dev/null +++ b/Patches/LineageOS-16.0/android_frameworks_base/355765-backport.patch @@ -0,0 +1,81 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Norman +Date: Thu, 9 Feb 2023 12:28:26 -0800 +Subject: [PATCH] Checks if AccessibilityServiceInfo is within parcelable size. + +- If too large when parsing service XMLs then skip this service. +- If too large when a service attempts to update its own info + then throw an error. + +Bug: 261589597 +Test: atest AccessibilityServiceInfoTest +Change-Id: Iffc0cd48cc713f7904d68059e141cb7de5a4b906 +Merged-In: Iffc0cd48cc713f7904d68059e141cb7de5a4b906 +(cherry picked from commit on googleplex-android-review.googlesource.com host: 553232c29079fbeab28f95307d025c1426aa7142) +Merged-In: Iffc0cd48cc713f7904d68059e141cb7de5a4b906 +--- + .../accessibilityservice/AccessibilityService.java | 4 ++++ + .../accessibilityservice/AccessibilityServiceInfo.java | 10 ++++++++++ + .../accessibility/AccessibilityManagerService.java | 6 ++++++ + 3 files changed, 20 insertions(+) + +diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java +index 6933e5201a21..ef59803e3ede 100644 +--- a/core/java/android/accessibilityservice/AccessibilityService.java ++++ b/core/java/android/accessibilityservice/AccessibilityService.java +@@ -1488,6 +1488,10 @@ public abstract class AccessibilityService extends Service { + IAccessibilityServiceConnection connection = + AccessibilityInteractionClient.getInstance().getConnection(mConnectionId); + if (mInfo != null && connection != null) { ++ if (!mInfo.isWithinParcelableSize()) { ++ throw new IllegalStateException( ++ "Cannot update service info: size is larger than safe parcelable limits."); ++ } + try { + connection.setServiceInfo(mInfo); + mInfo = null; +diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +index f85f35889aae..76930d75c5de 100644 +--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java ++++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +@@ -29,6 +29,7 @@ import android.content.res.Resources; + import android.content.res.TypedArray; + import android.content.res.XmlResourceParser; + import android.hardware.fingerprint.FingerprintManager; ++import android.os.IBinder; + import android.os.Parcel; + import android.os.Parcelable; + import android.util.AttributeSet; +@@ -766,6 +767,15 @@ public class AccessibilityServiceInfo implements Parcelable { + return 0; + } + ++ /** @hide */ ++ public final boolean isWithinParcelableSize() { ++ final Parcel parcel = Parcel.obtain(); ++ writeToParcel(parcel, 0); ++ final boolean result = parcel.dataSize() <= IBinder.MAX_IPC_SIZE; ++ parcel.recycle(); ++ return result; ++ } ++ + public void writeToParcel(Parcel parcel, int flagz) { + parcel.writeInt(eventTypes); + parcel.writeStringArray(packageNames); +diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +index 91d1b7576ca7..fd87be3e5649 100644 +--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java ++++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +@@ -1302,6 +1302,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub + AccessibilityServiceInfo accessibilityServiceInfo; + try { + accessibilityServiceInfo = new AccessibilityServiceInfo(resolveInfo, mContext); ++ if (!accessibilityServiceInfo.isWithinParcelableSize()) { ++ Slog.e(LOG_TAG, "Skipping service " ++ + accessibilityServiceInfo.getResolveInfo().getComponentInfo() ++ + " because service info size is larger than safe parcelable limits."); ++ continue; ++ } + mTempAccessibilityServiceInfoList.add(accessibilityServiceInfo); + } catch (XmlPullParserException | IOException xppe) { + Slog.e(LOG_TAG, "Error while initializing AccessibilityServiceInfo", xppe); diff --git a/Patches/LineageOS-16.0/android_frameworks_base/355767.patch b/Patches/LineageOS-16.0/android_frameworks_base/355767.patch new file mode 100644 index 00000000..e4ce68d7 --- /dev/null +++ b/Patches/LineageOS-16.0/android_frameworks_base/355767.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Stuart +Date: Mon, 21 Nov 2022 17:38:21 -0800 +Subject: [PATCH] enforce stricter rules when registering phoneAccounts + +- include disable accounts when looking up accounts for a package to + check if the limit is reached (10) +- put a new limit of 10 supported schemes +- put a new limit of 256 characters per scheme +- put a new limit of 256 characters per address +- ensure the Icon can write to memory w/o throwing an exception + +bug: 259064622 +bug: 256819769 +Test: cts + unit +Change-Id: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7 +Merged-In: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7 +(cherry picked from commit on googleplex-android-review.googlesource.com host: a66a3156e03fbd1c3a29015db9193d66f2709f98) +Merged-In: Ia7d8d00d9de0fb6694ded6a80c40bd55d7fdf7a7 +--- + .../java/android/telecom/PhoneAccount.java | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java +index 8e22221d7876..702b1cf87d7d 100644 +--- a/telecomm/java/android/telecom/PhoneAccount.java ++++ b/telecomm/java/android/telecom/PhoneAccount.java +@@ -439,6 +439,11 @@ public final class PhoneAccount implements Parcelable { + + /** + * Sets the address. See {@link PhoneAccount#getAddress}. ++ *

++ * Note: The entire URI value is limited to 256 characters. This check is ++ * enforced when registering the PhoneAccount via ++ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} and will cause an ++ * {@link IllegalArgumentException} to be thrown if URI is over 256. + * + * @param value The address of the phone account. + * @return The builder. +@@ -472,6 +477,10 @@ public final class PhoneAccount implements Parcelable { + + /** + * Sets the icon. See {@link PhoneAccount#getIcon}. ++ *

++ * Note: An {@link IllegalArgumentException} if the Icon cannot be written to memory. ++ * This check is enforced when registering the PhoneAccount via ++ * {@link TelecomManager#registerPhoneAccount(PhoneAccount)} + * + * @param icon The icon to set. + */ +@@ -505,6 +514,10 @@ public final class PhoneAccount implements Parcelable { + /** + * Specifies an additional URI scheme supported by the {@link PhoneAccount}. + * ++ *

++ * Each URI scheme is limited to 256 characters. Adding a scheme over 256 characters will ++ * cause an {@link IllegalArgumentException} to be thrown when the account is registered. ++ * + * @param uriScheme The URI scheme. + * @return The builder. + */ +@@ -518,6 +531,12 @@ public final class PhoneAccount implements Parcelable { + /** + * Specifies the URI schemes supported by the {@link PhoneAccount}. + * ++ *

++ * A max of 10 URI schemes can be added per account. Additionally, each URI scheme is ++ * limited to 256 characters. Adding more than 10 URI schemes or 256 characters on any ++ * scheme will cause an {@link IllegalArgumentException} to be thrown when the account ++ * is registered. ++ * + * @param uriSchemes The URI schemes. + * @return The builder. + */ diff --git a/Patches/LineageOS-16.0/android_frameworks_base/355865.patch b/Patches/LineageOS-16.0/android_frameworks_base/355865.patch new file mode 100644 index 00000000..bff79087 --- /dev/null +++ b/Patches/LineageOS-16.0/android_frameworks_base/355865.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Orion Hodson +Date: Thu, 7 Apr 2022 21:42:04 +0100 +Subject: [PATCH] Uri: check authority and scheme as part of determining URI + path + +The interpretation of the path depends on whether the scheme or +authority are specified and should be observed when unparcelling +URIs. + +Bug: 171966843 +Test: atest FrameworksCoreTests:android.net.UriTest +Test: atest com.android.devicehealthchecks.SystemAppCheck +Change-Id: I06981d1c6e387b16df792494523994518848db37 +Merged-In: I06981d1c6e387b16df792494523994518848db37 +(cherry picked from commit f37a94ae920fa5879c557603fc285942ec4b84b1) +(cherry picked from commit on googleplex-android-review.googlesource.com host: c87f0623be4042c39a9b73f7a6e02aa116925e50) +Merged-In: I06981d1c6e387b16df792494523994518848db37 +--- + core/java/android/net/Uri.java | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java +index 0fb84b723634..af1c0e8e9178 100644 +--- a/core/java/android/net/Uri.java ++++ b/core/java/android/net/Uri.java +@@ -1179,13 +1179,16 @@ public abstract class Uri implements Parcelable, Comparable { + } + + static Uri readFrom(Parcel parcel) { +- return new HierarchicalUri( +- parcel.readString(), +- Part.readFrom(parcel), +- PathPart.readFrom(parcel), +- Part.readFrom(parcel), +- Part.readFrom(parcel) +- ); ++ final String scheme = parcel.readString(); ++ final Part authority = Part.readFrom(parcel); ++ // In RFC3986 the path should be determined based on whether there is a scheme or ++ // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3). ++ final boolean hasSchemeOrAuthority = ++ (scheme != null && scheme.length() > 0) || !authority.isEmpty(); ++ final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel); ++ final Part query = Part.readFrom(parcel); ++ final Part fragment = Part.readFrom(parcel); ++ return new HierarchicalUri(scheme, authority, path, query, fragment); + } + + public int describeContents() { +@@ -2240,6 +2243,11 @@ public abstract class Uri implements Parcelable, Comparable { + } + } + ++ static PathPart readFrom(boolean hasSchemeOrAuthority, Parcel parcel) { ++ final PathPart path = readFrom(parcel); ++ return hasSchemeOrAuthority ? makeAbsolute(path) : path; ++ } ++ + /** + * Creates a path from the encoded string. + * diff --git a/Patches/LineageOS-16.0/android_frameworks_native/0001-Sensors.patch b/Patches/LineageOS-16.0/android_frameworks_native/0001-Sensors.patch index 01cb78b8..21f7170f 100644 --- a/Patches/LineageOS-16.0/android_frameworks_native/0001-Sensors.patch +++ b/Patches/LineageOS-16.0/android_frameworks_native/0001-Sensors.patch @@ -8,7 +8,7 @@ Subject: [PATCH] require OTHER_SENSORS permission for sensors 1 file changed, 1 insertion(+) diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp -index 2383516c95..054596b83a 100644 +index f4421c8c65..24eae47955 100644 --- a/libs/sensor/Sensor.cpp +++ b/libs/sensor/Sensor.cpp @@ -52,6 +52,7 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi diff --git a/Patches/LineageOS-16.0/android_frameworks_native/355772.patch b/Patches/LineageOS-16.0/android_frameworks_native/355772.patch new file mode 100644 index 00000000..f88e0e68 --- /dev/null +++ b/Patches/LineageOS-16.0/android_frameworks_native/355772.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Devin Moore +Date: Fri, 17 Feb 2023 17:12:46 +0000 +Subject: [PATCH] Check for malformed Sensor Flattenable + +Test: libsensorserviceaidl_fuzzer with testcase from bug +Bug: 269014004 +Merged-In: I0e255c64243c38876fb657cbf942fc1613363216 +Change-Id: I0e255c64243c38876fb657cbf942fc1613363216 +(cherry picked from commit aeec1802f7befc8fbb18313ad3ac0969c3811870) +Merged-In: I0e255c64243c38876fb657cbf942fc1613363216 +(cherry picked from commit on googleplex-android-review.googlesource.com host: f1aa5fb53437ec2fabc9be00099af836da5f07f2) +Merged-In: I0e255c64243c38876fb657cbf942fc1613363216 +--- + libs/sensor/Sensor.cpp | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp +index 2383516c95..f4421c8c65 100644 +--- a/libs/sensor/Sensor.cpp ++++ b/libs/sensor/Sensor.cpp +@@ -576,7 +576,13 @@ bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& output + return false; + } + outputString8.setTo(static_cast(buffer), len); ++ ++ if (size < FlattenableUtils::align<4>(len)) { ++ ALOGE("Malformed Sensor String8 field. Should be in a 4-byte aligned buffer but is not."); ++ return false; ++ } + FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); ++ + return true; + } + diff --git a/Patches/LineageOS-16.0/android_frameworks_native/355773-backport.patch b/Patches/LineageOS-16.0/android_frameworks_native/355773-backport.patch new file mode 100644 index 00000000..b9ffc91b --- /dev/null +++ b/Patches/LineageOS-16.0/android_frameworks_native/355773-backport.patch @@ -0,0 +1,67 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Devin Moore +Date: Fri, 17 Feb 2023 19:35:25 +0000 +Subject: [PATCH] Remove some new memory leaks from SensorManager + +After catching an error in Sensor::unflatten, there are memory leaks +caught by the fuzzer in the same test case. + +Test: libsensorserviceaidl_fuzzer with testcase from bug +Bug: 269014004 +Merged-In: I509cceb41f56ca117d9475f6f6674244560fe582 +Change-Id: I509cceb41f56ca117d9475f6f6674244560fe582 +(cherry picked from commit c95fa0f0e7c7b73746ff850b85a79fc5f92b784e) +Merged-In: I509cceb41f56ca117d9475f6f6674244560fe582 +(cherry picked from commit on googleplex-android-review.googlesource.com host: ceb0d52273256c6a5c5622bf81b0ac4ba106faa1) +Merged-In: I509cceb41f56ca117d9475f6f6674244560fe582 +--- + libs/sensor/ISensorServer.cpp | 12 ++++++++++-- + libs/sensor/SensorManager.cpp | 5 +++++ + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp +index 5200545a53..b2f1ba2507 100644 +--- a/libs/sensor/ISensorServer.cpp ++++ b/libs/sensor/ISensorServer.cpp +@@ -66,7 +66,11 @@ public: + v.setCapacity(n); + while (n) { + n--; +- reply.read(s); ++ if(reply.read(s) != OK) { ++ ALOGE("Failed to read reply from getSensorList"); ++ v.clear(); ++ break; ++ } + v.add(s); + } + return v; +@@ -84,7 +88,11 @@ public: + v.setCapacity(n); + while (n) { + n--; +- reply.read(s); ++ if(reply.read(s) != OK) { ++ ALOGE("Failed to read reply from getDynamicSensorList"); ++ v.clear(); ++ break; ++ } + v.add(s); + } + return v; +diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp +index c97e4da9b5..c9b857c60f 100644 +--- a/libs/sensor/SensorManager.cpp ++++ b/libs/sensor/SensorManager.cpp +@@ -162,6 +162,11 @@ status_t SensorManager::assertStateLocked() { + + mSensors = mSensorServer->getSensorList(mOpPackageName); + size_t count = mSensors.size(); ++ if (count == 0) { ++ ALOGE("Failed to get Sensor list"); ++ mSensorServer.clear(); ++ return UNKNOWN_ERROR; ++ } + mSensorList = + static_cast(malloc(count * sizeof(Sensor*))); + LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL"); diff --git a/Patches/LineageOS-16.0/android_frameworks_native/355774-backport.patch b/Patches/LineageOS-16.0/android_frameworks_native/355774-backport.patch new file mode 100644 index 00000000..816fe925 --- /dev/null +++ b/Patches/LineageOS-16.0/android_frameworks_native/355774-backport.patch @@ -0,0 +1,71 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Anthony Stange +Date: Tue, 21 Feb 2023 17:57:38 +0000 +Subject: [PATCH] Add removeInstanceForPackageMethod to SensorManager + +In order to ensure that clients don't leak their sensor manager +instance that we currently store in a static map, they need to be able +to remove their instance. Otherwise, this instance is never removed from +the list and will hang around until our SensorManage instance is +destroyed. + +Bug: 269014004 +Test: Run ./libsensorserviceaidl_fuzzer +Change-Id: I52185f74ae8d28b379440235ca6f03c5089081f5 +(cherry picked from commit 9532f7c682fdd4b1e6e553cd6f61fc0cf2555902) +Merged-In: I52185f74ae8d28b379440235ca6f03c5089081f5 +(cherry picked from commit on googleplex-android-review.googlesource.com host: 4521fbf8095439a1c1681b5c709b306a5dc1d1e3) +Merged-In: I52185f74ae8d28b379440235ca6f03c5089081f5 +--- + libs/sensor/SensorManager.cpp | 10 ++++++++++ + libs/sensor/include/sensor/SensorManager.h | 1 + + services/sensorservice/hidl/SensorManager.cpp | 3 +++ + 3 files changed, 14 insertions(+) + +diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp +index c9b857c60f..d7210b10e0 100644 +--- a/libs/sensor/SensorManager.cpp ++++ b/libs/sensor/SensorManager.cpp +@@ -92,6 +92,16 @@ SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) + return *sensorManager; + } + ++void SensorManager::removeInstanceForPackage(const String16& packageName) { ++ Mutex::Autolock _l(sLock); ++ auto iterator = sPackageInstances.find(packageName); ++ if (iterator != sPackageInstances.end()) { ++ SensorManager* sensorManager = iterator->second; ++ delete sensorManager; ++ sPackageInstances.erase(iterator); ++ } ++} ++ + SensorManager::SensorManager(const String16& opPackageName) + : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) { + Mutex::Autolock _l(mLock); +diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h +index 23f7a918bb..d6eab17c45 100644 +--- a/libs/sensor/include/sensor/SensorManager.h ++++ b/libs/sensor/include/sensor/SensorManager.h +@@ -54,6 +54,7 @@ class SensorManager : public ASensorManager + { + public: + static SensorManager& getInstanceForPackage(const String16& packageName); ++ static void removeInstanceForPackage(const String16& packageName); + ~SensorManager(); + + ssize_t getSensorList(Sensor const* const** list); +diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp +index fee6da1e60..cf2fc448ea 100644 +--- a/services/sensorservice/hidl/SensorManager.cpp ++++ b/services/sensorservice/hidl/SensorManager.cpp +@@ -60,6 +60,9 @@ SensorManager::~SensorManager() { + if (mPollThread.joinable()) { + mPollThread.join(); + } ++ ++ ::android::SensorManager::removeInstanceForPackage( ++ String16(ISensorManager::descriptor)); + } + + // Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow. diff --git a/Patches/LineageOS-16.0/android_packages_services_Telecomm/355777-backport.patch b/Patches/LineageOS-16.0/android_packages_services_Telecomm/355777-backport.patch new file mode 100644 index 00000000..ca4f5052 --- /dev/null +++ b/Patches/LineageOS-16.0/android_packages_services_Telecomm/355777-backport.patch @@ -0,0 +1,449 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Thomas Stuart +Date: Mon, 21 Nov 2022 17:36:52 -0800 +Subject: [PATCH] enforce stricter rules when registering phoneAccounts + +- include disable accounts when looking up accounts for a package to + check if the limit is reached (10) +- put a new limit of 10 supported schemes +- put a new limit of 256 characters per scheme +- put a new limit of 256 characters per address +- ensure the Icon can write to memory w/o an exception + +bug: 259064622 +bug: 256819769 +Test: cts + unit +Change-Id: I5eb2a127a44d5ec725d0ba39cb0ef478b12013de +Merged-In: I5eb2a127a44d5ec725d0ba39cb0ef478b12013de +(cherry picked from commit on googleplex-android-review.googlesource.com host: 56ef9e15506f71ae555a4535d5c0ac9bd3f587f1) +Merged-In: I5eb2a127a44d5ec725d0ba39cb0ef478b12013de +--- + .../server/telecom/PhoneAccountRegistrar.java | 185 ++++++++++++++++-- + .../server/telecom/TelecomServiceImpl.java | 4 +- + .../tests/PhoneAccountRegistrarTest.java | 101 ++++++++++ + .../telecom/tests/TelecomServiceImplTest.java | 2 +- + 4 files changed, 276 insertions(+), 16 deletions(-) + +diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java +index 0864683be..a077e4a4b 100644 +--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java ++++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java +@@ -17,6 +17,7 @@ + package com.android.server.telecom; + + import android.Manifest; ++import android.annotation.NonNull; + import android.content.ComponentName; + import android.content.Context; + import android.content.Intent; +@@ -28,6 +29,7 @@ import android.graphics.Bitmap; + import android.graphics.BitmapFactory; + import android.graphics.drawable.Icon; + import android.net.Uri; ++import android.os.Binder; + import android.os.Bundle; + import android.os.AsyncTask; + import android.os.PersistableBundle; +@@ -137,9 +139,14 @@ public class PhoneAccountRegistrar { + } + + private static final String FILE_NAME = "phone-account-registrar-state.xml"; ++ public static final String ICON_ERROR_MSG = ++ "Icon cannot be written to memory. Try compressing or downsizing"; + @VisibleForTesting + public static final int EXPECTED_STATE_VERSION = 9; + public static final int MAX_PHONE_ACCOUNT_REGISTRATIONS = 10; ++ public static final int MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT = 100; ++ public static final int MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT = 256; ++ public static final int MAX_SCHEMES_PER_ACCOUNT = 10; + + /** Keep in sync with the same in SipSettings.java */ + private static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES"; +@@ -652,12 +659,25 @@ public class PhoneAccountRegistrar { + return getPhoneAccountHandles(0, null, packageName, false, userHandle); + } + ++ ++ /** ++ * includes disabled, includes crossUserAccess ++ */ ++ public List getAllPhoneAccountHandlesForPackage(UserHandle userHandle, ++ String packageName) { ++ return getPhoneAccountHandles(0, null, packageName, true /* includeDisabled */, userHandle); ++ } ++ ++ + /** + * Performs checks before calling addOrReplacePhoneAccount(PhoneAccount) + * + * @param account The {@code PhoneAccount} to add or replace. +- * @throws SecurityException if package does not have BIND_TELECOM_CONNECTION_SERVICE permission ++ * @throws SecurityException if package does not have BIND_TELECOM_CONNECTION_SERVICE ++ * permission + * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_REGISTRATIONS are reached ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT is reached ++ * @throws IllegalArgumentException if writing the Icon to memory will cause an Exception + */ + public void registerPhoneAccount(PhoneAccount account) { + // Enforce the requirement that a connection service for a phone account has the correct +@@ -669,21 +689,155 @@ public class PhoneAccountRegistrar { + throw new SecurityException("PhoneAccount connection service requires " + + "BIND_TELECOM_CONNECTION_SERVICE permission."); + } +- //Enforce an upper bound on the number of PhoneAccount's a package can register. +- // Most apps should only require 1-2. +- if (getPhoneAccountsForPackage( +- account.getAccountHandle().getComponentName().getPackageName(), +- account.getAccountHandle().getUserHandle()).size() ++ enforceCharacterLimit(account); ++ enforceIconSizeLimit(account); ++ enforceMaxPhoneAccountLimit(account); ++ addOrReplacePhoneAccount(account); ++ } ++ ++ /** ++ * Enforce an upper bound on the number of PhoneAccount's a package can register. ++ * Most apps should only require 1-2. * Include disabled accounts. ++ * ++ * @param account to enforce check on ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_REGISTRATIONS are reached ++ */ ++ private void enforceMaxPhoneAccountLimit(@NonNull PhoneAccount account) { ++ final PhoneAccountHandle accountHandle = account.getAccountHandle(); ++ final UserHandle user = accountHandle.getUserHandle(); ++ final ComponentName componentName = accountHandle.getComponentName(); ++ ++ if (getPhoneAccountHandles(0, null, componentName.getPackageName(), ++ true /* includeDisabled */, user).size() + >= MAX_PHONE_ACCOUNT_REGISTRATIONS) { +- Log.w(this, "Phone account %s reached max registration limit for package", +- account.getAccountHandle()); ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceMaxPhoneAccountLimit"); + throw new IllegalArgumentException( + "Error, cannot register phone account " + account.getAccountHandle() + + " because the limit, " + MAX_PHONE_ACCOUNT_REGISTRATIONS + + ", has been reached"); + } ++ } ++ /** ++ * determine if there will be an issue writing the icon to memory ++ * ++ * @param account to enforce check on ++ * @throws IllegalArgumentException if writing the Icon to memory will cause an Exception ++ */ ++ @VisibleForTesting ++ public void enforceIconSizeLimit(PhoneAccount account) { ++ if (account.getIcon() == null) { ++ return; ++ } ++ String text = ""; ++ // convert the icon into a Base64 String ++ try { ++ text = XmlSerialization.writeIconToBase64String(account.getIcon()); ++ } catch (IOException e) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceIconSizeLimit"); ++ throw new IllegalArgumentException(ICON_ERROR_MSG); ++ } ++ } + +- addOrReplacePhoneAccount(account); ++ /** ++ * All {@link PhoneAccount} and{@link PhoneAccountHandle} String and Char-Sequence fields ++ * should be restricted to character limit of MAX_PHONE_ACCOUNT_CHAR_LIMIT to prevent exceptions ++ * when writing large character streams to XML-Serializer. ++ * ++ * @param account to enforce character limit checks on ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT reached ++ */ ++ public void enforceCharacterLimit(PhoneAccount account) { ++ if (account == null) { ++ return; ++ } ++ PhoneAccountHandle handle = account.getAccountHandle(); ++ ++ String[] fields = ++ {"Package Name", "Class Name", "PhoneAccountHandle Id", "Label", "ShortDescription", ++ "GroupId", "Address", "SubscriptionAddress"}; ++ CharSequence[] args = {handle.getComponentName().getPackageName(), ++ handle.getComponentName().getClassName(), handle.getId(), account.getLabel(), ++ account.getShortDescription(), account.getGroupId(), ++ (account.getAddress() != null ? account.getAddress().toString() : ""), ++ (account.getSubscriptionAddress() != null ? ++ account.getSubscriptionAddress().toString() : "")}; ++ ++ for (int i = 0; i < fields.length; i++) { ++ if (args[i] != null && args[i].length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceCharacterLimit"); ++ throw new IllegalArgumentException("The PhoneAccount or PhoneAccountHandle" ++ + fields[i] + " field has an invalid character count. PhoneAccount and " ++ + "PhoneAccountHandle String and Char-Sequence fields are limited to " ++ + MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + " characters."); ++ } ++ } ++ ++ // Enforce limits on the URI Schemes provided ++ enforceLimitsOnSchemes(account); ++ ++ // Enforce limit on the PhoneAccount#mExtras ++ Bundle extras = account.getExtras(); ++ if (extras != null) { ++ if (extras.keySet().size() > MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceCharacterLimit"); ++ throw new IllegalArgumentException("The PhoneAccount#mExtras is limited to " + ++ MAX_PHONE_ACCOUNT_EXTRAS_KEY_PAIR_LIMIT + " (key,value) pairs."); ++ } ++ ++ for (String key : extras.keySet()) { ++ Object value = extras.get(key); ++ ++ if ((key != null && key.length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT) || ++ (value instanceof String && ++ ((String) value).length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT)) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceCharacterLimit"); ++ throw new IllegalArgumentException("The PhoneAccount#mExtras contains a String" ++ + " key or value that has an invalid character count. PhoneAccount and " ++ + "PhoneAccountHandle String and Char-Sequence fields are limited to " ++ + MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + " characters."); ++ } ++ } ++ } ++ } ++ ++ /** ++ * Enforce a character limit on all PA and PAH string or char-sequence fields. ++ * ++ * @param account to enforce check on ++ * @throws IllegalArgumentException if MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT reached ++ */ ++ @VisibleForTesting ++ public void enforceLimitsOnSchemes(@NonNull PhoneAccount account) { ++ List schemes = account.getSupportedUriSchemes(); ++ ++ if (schemes == null) { ++ return; ++ } ++ ++ if (schemes.size() > MAX_SCHEMES_PER_ACCOUNT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceLimitsOnSchemes"); ++ throw new IllegalArgumentException( ++ "Error, cannot register phone account " + account.getAccountHandle() ++ + " because the URI scheme limit of " ++ + MAX_SCHEMES_PER_ACCOUNT + " has been reached"); ++ } ++ ++ for (String scheme : schemes) { ++ if (scheme.length() > MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT) { ++ EventLog.writeEvent(0x534e4554, "259064622", Binder.getCallingUid(), ++ "enforceLimitsOnSchemes"); ++ throw new IllegalArgumentException( ++ "Error, cannot register phone account " + account.getAccountHandle() ++ + " because the max scheme limit of " ++ + MAX_PHONE_ACCOUNT_FIELD_CHAR_LIMIT + " has been reached"); ++ } ++ } + } + + /** +@@ -1396,17 +1550,20 @@ public class PhoneAccountRegistrar { + protected void writeIconIfNonNull(String tagName, Icon value, XmlSerializer serializer) + throws IOException { + if (value != null) { +- ByteArrayOutputStream stream = new ByteArrayOutputStream(); +- value.writeToStream(stream); +- byte[] iconByteArray = stream.toByteArray(); +- String text = Base64.encodeToString(iconByteArray, 0, iconByteArray.length, 0); +- ++ String text = writeIconToBase64String(value); + serializer.startTag(null, tagName); + serializer.text(text); + serializer.endTag(null, tagName); + } + } + ++ public static String writeIconToBase64String(Icon icon) throws IOException { ++ ByteArrayOutputStream stream = new ByteArrayOutputStream(); ++ icon.writeToStream(stream); ++ byte[] iconByteArray = stream.toByteArray(); ++ return Base64.encodeToString(iconByteArray, 0, iconByteArray.length, 0); ++ } ++ + protected void writeLong(String tagName, long value, XmlSerializer serializer) + throws IOException { + serializer.startTag(null, tagName); +diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java +index 8c28a7b6f..74a7d840b 100644 +--- a/src/com/android/server/telecom/TelecomServiceImpl.java ++++ b/src/com/android/server/telecom/TelecomServiceImpl.java +@@ -60,7 +60,9 @@ import com.android.server.telecom.settings.BlockedNumbersActivity; + import java.io.FileDescriptor; + import java.io.PrintWriter; + import java.util.Collections; ++import java.util.HashSet; + import java.util.List; ++import java.util.Set; + + // TODO: Needed for move to system service: import com.android.internal.R; + +@@ -264,7 +266,7 @@ public class TelecomServiceImpl { + try { + Log.startSession("TSI.gPAFP"); + return new ParceledListSlice<>(mPhoneAccountRegistrar +- .getPhoneAccountsForPackage(packageName, callingUserHandle)); ++ .getAllPhoneAccountHandlesForPackage(callingUserHandle, packageName)); + } catch (Exception e) { + Log.e(this, e, "getPhoneAccountsForPackage %s", packageName); + throw e; +diff --git a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java +index f8acb9d2c..b223cdc12 100644 +--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java ++++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java +@@ -57,6 +57,8 @@ import java.io.BufferedOutputStream; + import java.io.ByteArrayInputStream; + import java.io.ByteArrayOutputStream; + import java.io.File; ++import java.io.IOException; ++import java.io.OutputStream; + import java.util.Arrays; + import java.util.List; + import java.util.Map; +@@ -68,8 +70,18 @@ import static org.junit.Assert.assertNotNull; + import static org.junit.Assert.assertNull; + import static org.junit.Assert.assertTrue; + import static org.junit.Assert.fail; ++import static org.mockito.ArgumentMatchers.any; ++import static org.mockito.ArgumentMatchers.anyObject; ++import static org.mockito.ArgumentMatchers.isA; + import static org.mockito.Matchers.anyInt; + import static org.mockito.Matchers.anyString; ++import static org.mockito.Mockito.clearInvocations; ++import static org.mockito.Mockito.doThrow; ++import static org.mockito.Mockito.mock; ++import static org.mockito.Mockito.never; ++import static org.mockito.Mockito.spy; ++import static org.mockito.Mockito.times; ++import static org.mockito.Mockito.verify; + import static org.mockito.Mockito.when; + + @RunWith(JUnit4.class) +@@ -78,6 +90,9 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase { + private static final int MAX_VERSION = Integer.MAX_VALUE; + private static final String FILE_NAME = "phone-account-registrar-test-1223.xml"; + private static final String TEST_LABEL = "right"; ++ private static final String TEST_ID = "123"; ++ private final String PACKAGE_1 = "PACKAGE_1"; ++ private final String PACKAGE_2 = "PACKAGE_2"; + private PhoneAccountRegistrar mRegistrar; + @Mock private TelecomManager mTelecomManager; + @Mock private DefaultDialerCache mDefaultDialerCache; +@@ -909,6 +924,92 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase { + assertEquals(account1, account2); + } + ++ /** ++ * Ensure an IllegalArgumentException is thrown when adding more than 10 schemes for a single ++ * account ++ */ ++ @Test ++ public void testLimitOnSchemeCount() { ++ PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID); ++ PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, TEST_LABEL); ++ for (int i = 0; i < PhoneAccountRegistrar.MAX_PHONE_ACCOUNT_REGISTRATIONS + 1; i++) { ++ builder.addSupportedUriScheme(Integer.toString(i)); ++ } ++ try { ++ mRegistrar.enforceLimitsOnSchemes(builder.build()); ++ fail("should have hit exception in enforceLimitOnSchemes"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ } ++ } ++ ++ /** ++ * Ensure an IllegalArgumentException is thrown when adding more 256 chars for a single ++ * account ++ */ ++ @Test ++ public void testLimitOnSchemeLength() { ++ PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID); ++ PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, TEST_LABEL); ++ builder.addSupportedUriScheme(generateStringOfLen(257)); ++ try { ++ mRegistrar.enforceLimitsOnSchemes(builder.build()); ++ fail("should have hit exception in enforceLimitOnSchemes"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ } ++ } ++ ++ /** ++ * Ensure an IllegalArgumentException is thrown when adding an address over the limit ++ */ ++ @Test ++ public void testLimitOnAddress() { ++ String text = generateStringOfLen(100); ++ PhoneAccountHandle handle = makeQuickAccountHandle(TEST_ID); ++ PhoneAccount.Builder builder = new PhoneAccount.Builder(handle,TEST_LABEL) ++ .setAddress(Uri.fromParts(text, text, text)); ++ try { ++ mRegistrar.enforceCharacterLimit(builder.build()); ++ fail("failed to throw IllegalArgumentException"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ } ++ finally { ++ mRegistrar.unregisterPhoneAccount(handle); ++ } ++ } ++ ++ /** ++ * Ensure an IllegalArgumentException is thrown when an Icon that throws an IOException is given ++ */ ++ @Test ++ public void testLimitOnIcon() throws Exception { ++ Icon mockIcon = mock(Icon.class); ++ // GIVEN ++ PhoneAccount.Builder builder = new PhoneAccount.Builder( ++ makeQuickAccountHandle(TEST_ID), TEST_LABEL).setIcon(mockIcon); ++ try { ++ // WHEN ++ Mockito.doThrow(new IOException()) ++ .when(mockIcon).writeToStream(any(OutputStream.class)); ++ //THEN ++ mRegistrar.enforceIconSizeLimit(builder.build()); ++ fail("failed to throw IllegalArgumentException"); ++ } catch (IllegalArgumentException e) { ++ // pass test ++ assertTrue(e.getMessage().contains(PhoneAccountRegistrar.ICON_ERROR_MSG)); ++ } ++ } ++ ++ private String generateStringOfLen(int len){ ++ StringBuilder sb = new StringBuilder(); ++ for(int i=0; i < len; i++){ ++ sb.append("a"); ++ } ++ return sb.toString(); ++ } ++ + private static ComponentName makeQuickConnectionServiceComponentName() { + return new ComponentName( + "com.android.server.telecom.tests", +diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +index 092227b47..521d05aae 100644 +--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java ++++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +@@ -362,7 +362,7 @@ public class TelecomServiceImplTest extends TelecomTestCase { + add(SIP_PA_HANDLE_17); + }}; + when(mFakePhoneAccountRegistrar +- .getPhoneAccountsForPackage(anyString(), any(UserHandle.class))) ++ .getAllPhoneAccountHandlesForPackage(any(UserHandle.class), anyString())) + .thenReturn(phoneAccountHandleList); + makeAccountsVisibleToAllUsers(TEL_PA_HANDLE_16, SIP_PA_HANDLE_17); + assertEquals(phoneAccountHandleList, diff --git a/Patches/LineageOS-17.1/android_frameworks_base/0014-Special_Permissions.patch b/Patches/LineageOS-17.1/android_frameworks_base/0014-Special_Permissions.patch index 9962288c..f37ef148 100644 --- a/Patches/LineageOS-17.1/android_frameworks_base/0014-Special_Permissions.patch +++ b/Patches/LineageOS-17.1/android_frameworks_base/0014-Special_Permissions.patch @@ -11,10 +11,10 @@ need to be granted by default for all apps to maintain compatibility. 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java -index 58a0fdbed498..e1c679a3698f 100644 +index 068cb345d463..94807b48eee9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java -@@ -20215,7 +20215,8 @@ public class PackageManagerService extends IPackageManager.Stub +@@ -20211,7 +20211,8 @@ public class PackageManagerService extends IPackageManager.Stub } // If this permission was granted by default, make sure it is. diff --git a/Patches/LineageOS-17.1/android_frameworks_base/355766-backport.patch b/Patches/LineageOS-17.1/android_frameworks_base/355766-backport.patch index c2768913..96f71262 100644 --- a/Patches/LineageOS-17.1/android_frameworks_base/355766-backport.patch +++ b/Patches/LineageOS-17.1/android_frameworks_base/355766-backport.patch @@ -22,7 +22,7 @@ Merged-In: I06981d1c6e387b16df792494523994518848db37 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java -index 8cf182b41566..06136a5e92bc 100644 +index 8cf182b41566..33acef7f9506 100644 --- a/core/java/android/net/Uri.java +++ b/core/java/android/net/Uri.java @@ -1194,13 +1194,16 @@ public abstract class Uri implements Parcelable, Comparable { @@ -62,7 +62,7 @@ index 8cf182b41566..06136a5e92bc 100644 * Creates a path from the encoded string. * diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java -index f20220c4ab9b..670aefd21d36 100644 +index f20220c4ab9b..73cfdc6d1e0f 100644 --- a/core/tests/coretests/src/android/net/UriTest.java +++ b/core/tests/coretests/src/android/net/UriTest.java @@ -48,6 +48,7 @@ public class UriTest extends TestCase { diff --git a/Scripts/LineageOS-15.1/Patch.sh b/Scripts/LineageOS-15.1/Patch.sh index 14131824..8edb3d5f 100644 --- a/Scripts/LineageOS-15.1/Patch.sh +++ b/Scripts/LineageOS-15.1/Patch.sh @@ -73,7 +73,7 @@ applyPatch "$DOS_PATCHES/android_build/0001-OTA_Keys.patch"; #Add correct keys t applyPatch "$DOS_PATCHES/android_build/0002-Enable_fwrapv.patch"; #Use -fwrapv at a minimum (GrapheneOS) sed -i '57i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches. awk -i inplace '!/Email/' target/product/core.mk; #Remove Email -sed -i 's/2021-10-05/2023-04-05/' core/version_defaults.mk; #Bump Security String #XXX +sed -i 's/2021-10-05/2023-05-05/' core/version_defaults.mk; #Bump Security String #XXX fi; if enterAndClear "build/soong"; then @@ -178,6 +178,9 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/354242-backport.patch"; #P_asb_ applyPatch "$DOS_PATCHES/android_frameworks_base/354243.patch"; #P_asb_2023-04 Checking if package belongs to UID before registering broadcast receiver applyPatch "$DOS_PATCHES/android_frameworks_base/354244-backport.patch"; #P_asb_2023-04 Fix checkKeyIntentParceledCorrectly's bypass applyPatch "$DOS_PATCHES/android_frameworks_base/354245.patch"; #P_asb_2023-04 Encode Intent scheme when serializing to URI string +applyPatch "$DOS_PATCHES/android_frameworks_base/355765-backport.patch"; #R_asb_2023-05 Checks if AccessibilityServiceInfo is within parcelable size. +applyPatch "$DOS_PATCHES/android_frameworks_base/355865.patch"; #n-asb-2023-05 Uri: check authority and scheme as part of determining URI path +applyPatch "$DOS_PATCHES/android_frameworks_base/355767.patch"; #R_asb_2023-05 Enforce stricter rules when registering phoneAccounts applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0001-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS) applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0003-SUPL_No_IMSI.patch"; #Don't send IMSI to SUPL (MSe1969) applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0004-Fingerprint_Lockout.patch"; #Enable fingerprint lockout after five failed attempts (GrapheneOS) @@ -202,6 +205,9 @@ fi; if enterAndClear "frameworks/native"; then applyPatch "$DOS_PATCHES/android_frameworks_native/326752.patch"; #P_asb_2022-03 Check if the window is partially obscured for slippery enters +applyPatch "$DOS_PATCHES/android_frameworks_native/355772.patch"; #R_asb_2023-05 Check for malformed Sensor Flattenable +applyPatch "$DOS_PATCHES/android_frameworks_native/355773-backport.patch"; #R_asb_2023-05 Remove some new memory leaks from SensorManager +applyPatch "$DOS_PATCHES/android_frameworks_native/355774-backport.patch"; #R_asb_2023-05 Add removeInstanceForPackageMethod to SensorManager if [ "$DOS_SENSORS_PERM" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_native/0001-Sensors.patch"; fi; #Permission for sensors access (MSe1969) fi; @@ -363,6 +369,7 @@ applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/332764.patch"; #P_as applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/344183.patch"; #P_asb_2022-11 switch TelecomManager List getters to ParceledListSlice applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/345913.patch"; #P_asb_2022-12 Hide overlay windows when showing phone account enable/disable screen. applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/347042.patch"; #P_asb_2023-01 Fix security vulnerability when register phone accounts. +applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/355777-backport.patch"; #R_asb_2023-05 enforce stricter rules when registering phoneAccount fi; if enterAndClear "packages/services/Telephony"; then diff --git a/Scripts/LineageOS-16.0/Patch.sh b/Scripts/LineageOS-16.0/Patch.sh index 0d886b7e..8edfaa78 100644 --- a/Scripts/LineageOS-16.0/Patch.sh +++ b/Scripts/LineageOS-16.0/Patch.sh @@ -97,7 +97,7 @@ applyPatch "$DOS_PATCHES/android_build/0002-Enable_fwrapv.patch"; #Use -fwrapv a sed -i '74i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches. sed -i 's/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 17/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 28/' core/version_defaults.mk; #Set the minimum supported target SDK to Pie (GrapheneOS) awk -i inplace '!/Email/' target/product/core.mk; #Remove Email -sed -i 's/2022-01-05/2023-04-05/' core/version_defaults.mk; #Bump Security String #P_asb_2023-04 #XXX +sed -i 's/2022-01-05/2023-05-05/' core/version_defaults.mk; #Bump Security String #P_asb_2023-05 #XXX fi; if enterAndClear "build/soong"; then @@ -151,6 +151,9 @@ if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_fram fi; if enterAndClear "frameworks/base"; then +applyPatch "$DOS_PATCHES/android_frameworks_base/355765-backport.patch"; #R_asb_2023-05 Checks if AccessibilityServiceInfo is within parcelable size. +applyPatch "$DOS_PATCHES/android_frameworks_base/355865.patch"; #n-asb-2023-05 Uri: check authority and scheme as part of determining URI path +applyPatch "$DOS_PATCHES/android_frameworks_base/355767.patch"; #R_asb_2023-05 Enforce stricter rules when registering phoneAccounts applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS) applyPatch "$DOS_PATCHES/android_frameworks_base/0008-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS) applyPatch "$DOS_PATCHES/android_frameworks_base/0009-SystemUI_No_Permission_Review.patch"; #Allow SystemUI to directly manage Bluetooth/WiFi (GrapheneOS) @@ -192,6 +195,9 @@ rm -rf packages/PrintRecommendationService; #Creates popups to install proprieta fi; if enterAndClear "frameworks/native"; then +applyPatch "$DOS_PATCHES/android_frameworks_native/355772.patch"; #R_asb_2023-05 Check for malformed Sensor Flattenable +applyPatch "$DOS_PATCHES/android_frameworks_native/355773-backport.patch"; #R_asb_2023-05 Remove some new memory leaks from SensorManager +applyPatch "$DOS_PATCHES/android_frameworks_native/355774-backport.patch"; #R_asb_2023-05 Add removeInstanceForPackageMethod to SensorManager applyPatch "$DOS_PATCHES/android_frameworks_native/0001-Sensors.patch"; #Require OTHER_SENSORS permission for sensors (GrapheneOS) fi; @@ -324,6 +330,10 @@ fi; #cp $DOS_PATCHES_COMMON/android_packages_providers_TelephonyProvider/carrier_list.* assets/; #fi; +if enterAndClear "packages/services/Telecomm"; then +applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/355777-backport.patch"; #R_asb_2023-05 enforce stricter rules when registering phoneAccount +fi; + if enterAndClear "packages/services/Telephony"; then git revert --no-edit 99564aaf0417c9ddf7d6aeb10d326e5b24fa8f55; applyPatch "$DOS_PATCHES/android_packages_services_Telephony/0001-PREREQ_Handle_All_Modes.patch"; #(DivestOS)