17.1: switch to flamefire's ASB topics

This gets us ~9 extra patches

Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
Tad 2023-06-17 14:22:37 -04:00
parent a07133a064
commit 41e2669884
No known key found for this signature in database
GPG Key ID: B286E9F57A07424B
74 changed files with 23 additions and 8185 deletions

View File

@ -1,75 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ray Essick <essick@google.com>
Date: Mon, 27 Mar 2023 18:16:46 -0500
Subject: [PATCH] Fix NuMediaExtractor::readSampleData buffer Handling
readSampleData() did not initialize buffer before filling it,
leading to OOB memory references. Correct and clarify the book
keeping around output buffer management.
Bug: 275418191
Test: CtsMediaExtractorTestCases w/debug messages
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:943fc12219b21d2a98f0ddc070b9b316a6f5d412)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:84c69bca81175feb2fd97ebb22e432ee41572786)
Merged-In: Ie744f118526f100d82a312c64f7c6fcf20773b6d
Change-Id: Ie744f118526f100d82a312c64f7c6fcf20773b6d
---
media/libstagefright/NuMediaExtractor.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index 680d426d96..ddab6d3923 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -595,9 +595,11 @@ status_t NuMediaExtractor::appendVorbisNumPageSamples(
numPageSamples = -1;
}
+ // insert, including accounting for the space used.
memcpy((uint8_t *)buffer->data() + mbuf->range_length(),
&numPageSamples,
sizeof(numPageSamples));
+ buffer->setRange(buffer->offset(), buffer->size() + sizeof(numPageSamples));
uint32_t type;
const void *data;
@@ -646,6 +648,8 @@ status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
ssize_t minIndex = fetchAllTrackSamples();
+ buffer->setRange(0, 0); // start with an empty buffer
+
if (minIndex < 0) {
return ERROR_END_OF_STREAM;
}
@@ -661,25 +665,25 @@ status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
sampleSize += sizeof(int32_t);
}
+ // capacity() is ok since we cleared out the buffer
if (buffer->capacity() < sampleSize) {
return -ENOMEM;
}
+ const size_t srclen = it->mBuffer->range_length();
const uint8_t *src =
(const uint8_t *)it->mBuffer->data()
+ it->mBuffer->range_offset();
- memcpy((uint8_t *)buffer->data(), src, it->mBuffer->range_length());
+ memcpy((uint8_t *)buffer->data(), src, srclen);
+ buffer->setRange(0, srclen);
status_t err = OK;
if (info->mTrackFlags & kIsVorbis) {
+ // adjusts range when it inserts the extra bits
err = appendVorbisNumPageSamples(it->mBuffer, buffer);
}
- if (err == OK) {
- buffer->setRange(0, sampleSize);
- }
-
return err;
}

View File

@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Julia Reynolds <juliacr@google.com>
Date: Mon, 16 May 2022 15:28:24 -0400
Subject: [PATCH] Move service initialization
Occasionally ILockSettings can fail to be initialized otherwise
Fixes: 232714129
Test: boot (and eventually bootstress/reboot-long)
Change-Id: I2f9f9bdba37f4ebfaea56c1a6662f0474ae8a002
Merged-In: I2f9f9bdba37f4ebfaea56c1a6662f0474ae8a002
(cherry picked from commit 8e278543bd290d4b6c417758554d6dee93a4fe74)
(cherry picked from commit caa5a22ea0c401c4eef548fb8161820beda3ff13)
Merged-In: I2f9f9bdba37f4ebfaea56c1a6662f0474ae8a002
---
.../server/notification/NotificationManagerService.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 347811d82862..c9831781b543 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1567,7 +1567,6 @@ public class NotificationManagerService extends SystemService {
}
}
- private LockPatternUtils mLockPatternUtils;
private StrongAuthTracker mStrongAuthTracker;
public NotificationManagerService(Context context) {
@@ -1761,7 +1760,6 @@ public class NotificationManagerService extends SystemService {
mHandler = new WorkerHandler(looper);
mRankingThread.start();
- mLockPatternUtils = new LockPatternUtils(getContext());
mStrongAuthTracker = new StrongAuthTracker(getContext());
String[] extractorNames;
try {
@@ -2059,7 +2057,7 @@ public class NotificationManagerService extends SystemService {
mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
mPackageManager, getContext().getMainExecutor());
mRoleObserver.init();
- mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
+ new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker);
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
// This observer will force an update when observe is called, causing us to
// bind to listener services.

View File

@ -1,38 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Johnston <acjohnston@google.com>
Date: Tue, 5 Oct 2021 11:44:37 +0000
Subject: [PATCH] Stop managed profile owner granting READ_SMS
Reason: There is only one telephony stack shared
between the personal and work profile.
Bug: 194382185
Bug: 189942529
Test: build
Change-Id: If0d27a317a7c0ee46af371b30208327e5636c7cf
(cherry picked from commit 87f37319bf7ee22c6e7c29432b6c9bbce0fdb591)
Merged-In: If0d27a317a7c0ee46af371b30208327e5636c7cf
---
core/java/android/app/admin/DevicePolicyManager.java | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 08e6ff318fbc..5e263b0d05b6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8836,6 +8836,15 @@ public class DevicePolicyManager {
* {@link android.os.Build.VERSION_CODES#M} the app-op matching the permission is set to
* {@link android.app.AppOpsManager#MODE_IGNORED}, but the permission stays granted.
*
+ * Control over the following permissions are restricted for managed profile owners:
+ * <ul>
+ * <li>Manifest.permission.READ_SMS</li>
+ * </ul>
+ * <p>
+ * A managed profile owner may not grant these permissions (i.e. call this method with any of
+ * the permissions listed above and {@code grantState} of
+ * {@code #PERMISSION_GRANT_STATE_GRANTED}), but may deny them.
+ *
* @param admin Which profile or device owner this request is associated with.
* @param packageName The application to grant or revoke a permission to.
* @param permission The permission to grant or revoke.

View File

@ -1,528 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wenhao Wang <wenhaowang@google.com>
Date: Tue, 30 Aug 2022 11:09:46 -0700
Subject: [PATCH] Enable user graularity for lockdown mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The NotificationManagerService registers a LockPatternUtils.StrongAuthTracker
to observe the StrongAuth changes of every user.
More specifically, its the STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN flag.
Via this flag, NotificationManagerService can perform the following operations
when the user enter or exit lockdown mode:
Enter lockdown:
1. Remove all the notifications belonging to the user.
2. Set the local flag to indicate the lockdown is on for the user.
The local flag will suppress the user's notifications on the
post, remove and update functions.
Exit lockdown:
1. Clear the local flag to indicate the lockdown is off for the user.
2. Repost the users notifications (suppressed during lockdown mode).
The CL also updates corresponding tests.
Bug: 173721373
Bug: 250743174
Test: atest NotificationManagerServiceTest
Test: atest NotificationListenersTest
Ignore-AOSP-First: pending fix for a security issue.
Change-Id: I4f30e56550729db7d673a92d2a1250509713f36d
Merged-In: I4f30e56550729db7d673a92d2a1250509713f36d
(cherry picked from commit de3b12fca23178d8c821058261572449b67d5967)
(cherry picked from commit 5e40f39f5bd4ae769d79ce022a64f1345512b65d)
Merged-In: I4f30e56550729db7d673a92d2a1250509713f36d
---
.../NotificationManagerService.java | 75 ++++++----
.../NotificationListenersTest.java | 132 +++++++++++-------
.../NotificationManagerServiceTest.java | 72 ++++++++--
3 files changed, 191 insertions(+), 88 deletions(-)
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c9831781b543..7ae80d927aaa 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1535,34 +1535,39 @@ public class NotificationManagerService extends SystemService {
return (haystack & needle) != 0;
}
- public boolean isInLockDownMode() {
- return mIsInLockDownMode;
+ // Return whether the user is in lockdown mode.
+ // If the flag is not set, we assume the user is not in lockdown.
+ public boolean isInLockDownMode(int userId) {
+ return mUserInLockDownMode.get(userId, false);
}
@Override
public synchronized void onStrongAuthRequiredChanged(int userId) {
boolean userInLockDownModeNext = containsFlag(getStrongAuthForUser(userId),
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
- mUserInLockDownMode.put(userId, userInLockDownModeNext);
- boolean isInLockDownModeNext = mUserInLockDownMode.indexOfValue(true) != -1;
- if (mIsInLockDownMode == isInLockDownModeNext) {
+ // Nothing happens if the lockdown mode of userId keeps the same.
+ if (userInLockDownModeNext == isInLockDownMode(userId)) {
return;
}
- if (isInLockDownModeNext) {
- cancelNotificationsWhenEnterLockDownMode();
+ // When the lockdown mode is changed, we perform the following steps.
+ // If the userInLockDownModeNext is true, all the function calls to
+ // notifyPostedLocked and notifyRemovedLocked will not be executed.
+ // The cancelNotificationsWhenEnterLockDownMode calls notifyRemovedLocked
+ // and postNotificationsWhenExitLockDownMode calls notifyPostedLocked.
+ // So we shall call cancelNotificationsWhenEnterLockDownMode before
+ // we set mUserInLockDownMode as true.
+ // On the other hand, if the userInLockDownModeNext is false, we shall call
+ // postNotificationsWhenExitLockDownMode after we put false into mUserInLockDownMode
+ if (userInLockDownModeNext) {
+ cancelNotificationsWhenEnterLockDownMode(userId);
}
- // When the mIsInLockDownMode is true, both notifyPostedLocked and
- // notifyRemovedLocked will be dismissed. So we shall call
- // cancelNotificationsWhenEnterLockDownMode before we set mIsInLockDownMode
- // as true and call postNotificationsWhenExitLockDownMode after we set
- // mIsInLockDownMode as false.
- mIsInLockDownMode = isInLockDownModeNext;
+ mUserInLockDownMode.put(userId, userInLockDownModeNext);
- if (!isInLockDownModeNext) {
- postNotificationsWhenExitLockDownMode();
+ if (!userInLockDownModeNext) {
+ postNotificationsWhenExitLockDownMode(userId);
}
}
}
@@ -7579,11 +7584,14 @@ public class NotificationManagerService extends SystemService {
}
}
- private void cancelNotificationsWhenEnterLockDownMode() {
+ private void cancelNotificationsWhenEnterLockDownMode(int userId) {
synchronized (mNotificationLock) {
int numNotifications = mNotificationList.size();
for (int i = 0; i < numNotifications; i++) {
NotificationRecord rec = mNotificationList.get(i);
+ if (rec.getUser().getIdentifier() != userId) {
+ continue;
+ }
mListeners.notifyRemovedLocked(rec, REASON_CANCEL_ALL,
rec.getStats());
}
@@ -7591,14 +7599,23 @@ public class NotificationManagerService extends SystemService {
}
}
- private void postNotificationsWhenExitLockDownMode() {
+ private void postNotificationsWhenExitLockDownMode(int userId) {
synchronized (mNotificationLock) {
int numNotifications = mNotificationList.size();
+ // Set the delay to spread out the burst of notifications.
+ long delay = 0;
for (int i = 0; i < numNotifications; i++) {
NotificationRecord rec = mNotificationList.get(i);
- mListeners.notifyPostedLocked(rec, rec);
+ if (rec.getUser().getIdentifier() != userId) {
+ continue;
+ }
+ mHandler.postDelayed(() -> {
+ synchronized (mNotificationLock) {
+ mListeners.notifyPostedLocked(rec, rec);
+ }
+ }, delay);
+ delay += 20;
}
-
}
}
@@ -7777,12 +7794,15 @@ public class NotificationManagerService extends SystemService {
* notifications visible to the given listener.
*/
@GuardedBy("mNotificationLock")
- private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
+ NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
final int N = mNotificationList.size();
final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
for (int i = 0; i < N; i++) {
NotificationRecord record = mNotificationList.get(i);
+ if (isInLockDownMode(record.getUser().getIdentifier())) {
+ continue;
+ }
if (!isVisibleToListener(record.sbn, info)) {
continue;
}
@@ -7818,8 +7838,8 @@ public class NotificationManagerService extends SystemService {
rankings.toArray(new NotificationListenerService.Ranking[0]));
}
- boolean isInLockDownMode() {
- return mStrongAuthTracker.isInLockDownMode();
+ boolean isInLockDownMode(int userId) {
+ return mStrongAuthTracker.isInLockDownMode(userId);
}
boolean hasCompanionDevice(ManagedServiceInfo info) {
@@ -7854,7 +7874,8 @@ public class NotificationManagerService extends SystemService {
ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
}
- private boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
+ @VisibleForTesting
+ boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
if (!listener.enabledAndUserMatches(sbn.getUserId())) {
return false;
}
@@ -8454,7 +8475,7 @@ public class NotificationManagerService extends SystemService {
@GuardedBy("mNotificationLock")
void notifyPostedLocked(NotificationRecord r, NotificationRecord old,
boolean notifyAllListeners) {
- if (isInLockDownMode()) {
+ if (isInLockDownMode(r.getUser().getIdentifier())) {
return;
}
@@ -8520,7 +8541,7 @@ public class NotificationManagerService extends SystemService {
@GuardedBy("mNotificationLock")
public void notifyRemovedLocked(NotificationRecord r, int reason,
NotificationStats notificationStats) {
- if (isInLockDownMode()) {
+ if (isInLockDownMode(r.getUser().getIdentifier())) {
return;
}
@@ -8575,10 +8596,6 @@ public class NotificationManagerService extends SystemService {
*/
@GuardedBy("mNotificationLock")
public void notifyRankingUpdateLocked(List<NotificationRecord> changedHiddenNotifications) {
- if (isInLockDownMode()) {
- return;
- }
-
boolean isHiddenRankingUpdate = changedHiddenNotifications != null
&& changedHiddenNotifications.size() > 0;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
index 793739bfe8f5..e04339fe5ee9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenersTest.java
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import android.app.INotificationManager;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
+import android.os.UserHandle;
import android.service.notification.NotificationStats;
import android.service.notification.StatusBarNotification;
import android.testing.TestableContext;
@@ -40,8 +41,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.util.reflection.FieldSetter;
-import java.util.List;
-
public class NotificationListenersTest extends UiServiceTestCase {
@Mock
@@ -70,46 +69,65 @@ public class NotificationListenersTest extends UiServiceTestCase {
@Test
public void testNotifyPostedLockedInLockdownMode() {
- NotificationRecord r = mock(NotificationRecord.class);
- NotificationRecord old = mock(NotificationRecord.class);
-
- // before the lockdown mode
- when(mNm.isInLockDownMode()).thenReturn(false);
- mListeners.notifyPostedLocked(r, old, true);
- mListeners.notifyPostedLocked(r, old, false);
- verify(mListeners, times(2)).getServices();
-
- // in the lockdown mode
- reset(r);
- reset(old);
- reset(mListeners);
- when(mNm.isInLockDownMode()).thenReturn(true);
- mListeners.notifyPostedLocked(r, old, true);
- mListeners.notifyPostedLocked(r, old, false);
- verify(mListeners, never()).getServices();
- }
-
- @Test
- public void testnotifyRankingUpdateLockedInLockdownMode() {
- List chn = mock(List.class);
-
- // before the lockdown mode
- when(mNm.isInLockDownMode()).thenReturn(false);
- mListeners.notifyRankingUpdateLocked(chn);
- verify(chn, times(1)).size();
-
- // in the lockdown mode
- reset(chn);
- when(mNm.isInLockDownMode()).thenReturn(true);
- mListeners.notifyRankingUpdateLocked(chn);
- verify(chn, never()).size();
+ NotificationRecord r0 = mock(NotificationRecord.class);
+ NotificationRecord old0 = mock(NotificationRecord.class);
+ UserHandle uh0 = mock(UserHandle.class);
+
+ NotificationRecord r1 = mock(NotificationRecord.class);
+ NotificationRecord old1 = mock(NotificationRecord.class);
+ UserHandle uh1 = mock(UserHandle.class);
+
+ // Neither user0 and user1 is in the lockdown mode
+ when(r0.getUser()).thenReturn(uh0);
+ when(uh0.getIdentifier()).thenReturn(0);
+ when(mNm.isInLockDownMode(0)).thenReturn(false);
+
+ when(r1.getUser()).thenReturn(uh1);
+ when(uh1.getIdentifier()).thenReturn(1);
+ when(mNm.isInLockDownMode(1)).thenReturn(false);
+
+ mListeners.notifyPostedLocked(r0, old0, true);
+ mListeners.notifyPostedLocked(r0, old0, false);
+ verify(r0, atLeast(2)).getSbn();
+
+ mListeners.notifyPostedLocked(r1, old1, true);
+ mListeners.notifyPostedLocked(r1, old1, false);
+ verify(r1, atLeast(2)).getSbn();
+
+ // Reset
+ reset(r0);
+ reset(old0);
+ reset(r1);
+ reset(old1);
+
+ // Only user 0 is in the lockdown mode
+ when(r0.getUser()).thenReturn(uh0);
+ when(uh0.getIdentifier()).thenReturn(0);
+ when(mNm.isInLockDownMode(0)).thenReturn(true);
+
+ when(r1.getUser()).thenReturn(uh1);
+ when(uh1.getIdentifier()).thenReturn(1);
+ when(mNm.isInLockDownMode(1)).thenReturn(false);
+
+ mListeners.notifyPostedLocked(r0, old0, true);
+ mListeners.notifyPostedLocked(r0, old0, false);
+ verify(r0, never()).getSbn();
+
+ mListeners.notifyPostedLocked(r1, old1, true);
+ mListeners.notifyPostedLocked(r1, old1, false);
+ verify(r1, atLeast(2)).getSbn();
}
@Test
public void testNotifyRemovedLockedInLockdownMode() throws NoSuchFieldException {
StatusBarNotification sbn = mock(StatusBarNotification.class);
- NotificationRecord r = mock(NotificationRecord.class);
- NotificationStats rs = mock(NotificationStats.class);
+ NotificationRecord r0 = mock(NotificationRecord.class);
+ NotificationStats rs0 = mock(NotificationStats.class);
+ UserHandle uh0 = mock(UserHandle.class);
+
+ NotificationRecord r1 = mock(NotificationRecord.class);
+ NotificationStats rs1 = mock(NotificationStats.class);
+ UserHandle uh1 = mock(UserHandle.class);
FieldSetter.setField(r,
NotificationRecord.class.getDeclaredField("sbn"),
sbn);
@@ -117,19 +135,31 @@ public class NotificationListenersTest extends UiServiceTestCase {
NotificationManagerService.class.getDeclaredField("mHandler"),
mock(NotificationManagerService.WorkerHandler.class));
- // before the lockdown mode
- when(mNm.isInLockDownMode()).thenReturn(false);
- mListeners.notifyRemovedLocked(r, 0, rs);
- mListeners.notifyRemovedLocked(r, 0, rs);
- verify(sbn, times(2)).cloneLight();
-
- // in the lockdown mode
- reset(sbn);
- reset(r);
- reset(rs);
- when(mNm.isInLockDownMode()).thenReturn(true);
- mListeners.notifyRemovedLocked(r, 0, rs);
- mListeners.notifyRemovedLocked(r, 0, rs);
- verify(sbn, never()).cloneLight();
+ // Neither user0 and user1 is in the lockdown mode
+ when(r0.getUser()).thenReturn(uh0);
+ when(uh0.getIdentifier()).thenReturn(0);
+ when(mNm.isInLockDownMode(0)).thenReturn(false);
+ when(r0.getSbn()).thenReturn(sbn);
+
+ when(r1.getUser()).thenReturn(uh1);
+ when(uh1.getIdentifier()).thenReturn(1);
+ when(mNm.isInLockDownMode(1)).thenReturn(false);
+ when(r1.getSbn()).thenReturn(sbn);
+
+ mListeners.notifyRemovedLocked(r0, 0, rs0);
+ mListeners.notifyRemovedLocked(r0, 0, rs0);
+ verify(r0, atLeast(2)).getSbn();
+
+ mListeners.notifyRemovedLocked(r1, 0, rs1);
+ mListeners.notifyRemovedLocked(r1, 0, rs1);
+ verify(r1, atLeast(2)).getSbn();
+
+ // Reset
+ reset(r0);
+ reset(rs0);
+ reset(r1);
+ reset(rs1);
+
+ // Only user 0 is in the lockdown mode
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 5030e124e4ce..7018b55b278d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -124,6 +124,7 @@ import android.provider.MediaStore;
import android.provider.Settings;
import android.service.notification.Adjustment;
import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationRankingUpdate;
import android.service.notification.NotificationStats;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenPolicy;
@@ -149,6 +150,7 @@ import com.android.server.SystemService;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
+import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
import com.android.server.pm.PackageManagerService;
@@ -255,6 +257,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Mock
AlarmManager mAlarmManager;
+ private NotificationManagerService.WorkerHandler mWorkerHandler;
+
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
int countSystemChecks = 0;
@@ -264,6 +268,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@Nullable
NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback;
+ @Nullable
+ Boolean mIsVisibleToListenerReturnValue = null;
+
TestableNotificationManagerService(Context context) {
super(context);
}
@@ -326,6 +333,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
void onGranted(ComponentName assistant, int userId, boolean granted);
}
+ protected void setIsVisibleToListenerReturnValue(boolean value) {
+ mIsVisibleToListenerReturnValue = value;
+ }
+
+ @Override
+ boolean isVisibleToListener(StatusBarNotification sbn, ManagedServiceInfo listener) {
+ if (mIsVisibleToListenerReturnValue != null) {
+ return mIsVisibleToListenerReturnValue;
+ }
+ return super.isVisibleToListener(sbn, listener);
+ }
+
@Override
protected boolean canLaunchInActivityView(Context context, PendingIntent pendingIntent,
String packageName) {
@@ -429,7 +448,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
- mService.init(mTestableLooper.getLooper(),
+ mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper()));
+ mService.init(mWorkerHandler,
mPackageManager, mPackageManagerClient, mockLightsManager,
mListeners, mAssistants, mConditionProviders,
mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
@@ -459,6 +479,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
clearDeviceConfig();
InstrumentationRegistry.getInstrumentation()
.getUiAutomation().dropShellPermissionIdentity();
+ mWorkerHandler.removeCallbacksAndMessages(null);
}
public void waitForIdle() {
@@ -5607,10 +5628,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
- assertTrue(mStrongAuthTracker.isInLockDownMode());
- mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
+ assertTrue(mStrongAuthTracker.isInLockDownMode(mContext.getUserId()));
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(mContext.getUserId());
mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
- assertFalse(mStrongAuthTracker.isInLockDownMode());
+ assertFalse(mStrongAuthTracker.isInLockDownMode(mContext.getUserId()));
}
@Test
@@ -5626,8 +5647,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// when entering the lockdown mode, cancel the 2 notifications.
mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
- mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
- assertTrue(mStrongAuthTracker.isInLockDownMode());
+ mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+ assertTrue(mStrongAuthTracker.isInLockDownMode(0));
// the notifyRemovedLocked function is called twice due to REASON_LOCKDOWN.
ArgumentCaptor<Integer> captor = ArgumentCaptor.forClass(Integer.class);
@@ -5636,9 +5657,44 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// exit lockdown mode.
mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
- mStrongAuthTracker.onStrongAuthRequiredChanged(mContext.getUserId());
+ mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+ assertFalse(mStrongAuthTracker.isInLockDownMode(0));
// the notifyPostedLocked function is called twice.
- verify(mListeners, times(2)).notifyPostedLocked(any(), any());
+ verify(mWorkerHandler, times(2)).postDelayed(any(Runnable.class), anyLong());
+ }
+
+ @Test
+ public void testMakeRankingUpdateLockedInLockDownMode() {
+ // post 2 notifications from a same package
+ NotificationRecord pkgA = new NotificationRecord(mContext,
+ generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
+ mService.addNotification(pkgA);
+ NotificationRecord pkgB = new NotificationRecord(mContext,
+ generateSbn("a", 1000, 9, 1), mTestNotificationChannel);
+ mService.addNotification(pkgB);
+
+ mService.setIsVisibleToListenerReturnValue(true);
+ NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(null);
+ assertEquals(2, nru.getRankingMap().getOrderedKeys().length);
+
+ // when only user 0 entering the lockdown mode, its notification will be suppressed.
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+ mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+ assertTrue(mStrongAuthTracker.isInLockDownMode(0));
+ assertFalse(mStrongAuthTracker.isInLockDownMode(1));
+
+ nru = mService.makeRankingUpdateLocked(null);
+ assertEquals(1, nru.getRankingMap().getOrderedKeys().length);
+
+ // User 0 exits lockdown mode. Its notification will be resumed.
+ mStrongAuthTracker.setGetStrongAuthForUserReturnValue(0);
+ mStrongAuthTracker.onStrongAuthRequiredChanged(0);
+ assertFalse(mStrongAuthTracker.isInLockDownMode(0));
+ assertFalse(mStrongAuthTracker.isInLockDownMode(1));
+
+ nru = mService.makeRankingUpdateLocked(null);
+ assertEquals(2, nru.getRankingMap().getOrderedKeys().length);
}
}

View File

@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nate Myren <ntmyren@google.com>
Date: Fri, 2 Dec 2022 09:44:31 -0800
Subject: [PATCH] RESTRICT AUTOMERGE Revoke dev perm if app is upgrading to
post 23 and perm has pre23 flag
If a permission has the "pre23" flag, and an app is upgrading past api
23, then we should not assume that a "development" permission remains
granted
Fixes: 259458532
Test: atest RevokeSawPermissionTest
Change-Id: I214396f455c5ed9e8bac2e50b1525b86475c81c7
(cherry picked from commit 2f30a63b11e59f9daf42f51eb85aa91c86f4baf4)
Merged-In: I214396f455c5ed9e8bac2e50b1525b86475c81c7
---
.../server/pm/permission/PermissionManagerService.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
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 23af4e6c1c3e..ae10b28cd8bb 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -671,7 +671,7 @@ public class PermissionManagerService {
}
final PackageSetting ps = (PackageSetting) newPackage.mExtras;
if (grantSignaturePermission(Manifest.permission.SYSTEM_ALERT_WINDOW, newPackage, saw,
- ps.getPermissionsState())) {
+ ps.getPermissionsState(), true)) {
return;
}
for (int userId: mUserManagerInt.getUserIds()) {
@@ -1836,6 +1836,11 @@ public class PermissionManagerService {
private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
BasePermission bp, PermissionsState origPermissions) {
+ return grantSignaturePermission(perm, pkg, bp, origPermissions, false);
+ }
+
+ private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
+ BasePermission bp, PermissionsState origPermissions, boolean isApi23Upgrade) {
boolean oemPermission = bp.isOEM();
boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
@@ -2022,7 +2027,7 @@ public class PermissionManagerService {
// Any pre-installed system app is allowed to get this permission.
allowed = true;
}
- if (!allowed && bp.isDevelopment()) {
+ if (!allowed && bp.isDevelopment() && !(bp.isPre23() && isApi23Upgrade)) {
// For development permissions, a development permission
// is granted only if it was already granted.
allowed = origPermissions.hasInstallPermission(perm);

View File

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Wright <michaelwr@google.com>
Date: Mon, 26 Sep 2022 20:37:33 +0100
Subject: [PATCH] Reconcile WorkSource parcel and unparcel code.
Prior to this CL, WorkSources would Parcel their list of WorkChains as
-1 if null, or the size of the list followed by the list itself if
non-null. When reading it back in, on the other hand, they would check
if the size was positive, and only then read the list from the Parcel.
This works for all cases except when the WorkSource has an empty but
non-null list of WorkChains as the list would get written to the parcel,
but then never read on the other side.
If parceling a list was a no-op when empty this wouldn't be an issue,
but it must write at least its size into the parcel to know how many
elements to extract. In the empty list case, this single element is left
unread as the size is not positive which essentially corrupts any future
items read from that same parcelable.
Bug: 220302519
Test: atest android.security.cts.WorkSourceTest#testWorkChainParceling
Change-Id: I2fec40dfced420ca38e717059b0e95ee8ef9946a
(cherry picked from commit 266b3bddcf14d448c0972db64b42950f76c759e3)
Merged-In: I2fec40dfced420ca38e717059b0e95ee8ef9946a
---
core/java/android/os/WorkSource.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 0b4a56121038..4e7a280aa2c1 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -114,7 +114,7 @@ public class WorkSource implements Parcelable {
mNames = in.createStringArray();
int numChains = in.readInt();
- if (numChains > 0) {
+ if (numChains >= 0) {
mChains = new ArrayList<>(numChains);
in.readParcelableList(mChains, WorkChain.class.getClassLoader());
} else {

View File

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Winson Chung <winsonc@google.com>
Date: Wed, 11 Jan 2023 18:58:41 +0000
Subject: [PATCH] Revert "Ensure that only SysUI can override pending intent
launch flags"
This reverts commit c4d3106e347922610f8c554de3ae238175ed393e.
Reason for revert: b/264884187, b/264885689
Change-Id: I9fb0d66327f3f872a92e6b9d682d58489e81e6ba
(cherry picked from commit 7bb933f48ff15d8f08d2185005b7b3e212915276)
Merged-In: I9fb0d66327f3f872a92e6b9d682d58489e81e6ba
---
.../com/android/server/am/PendingIntentRecord.java | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 44d67ed0d642..54504c3c1e24 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -317,16 +317,11 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
resolvedType = key.requestResolvedType;
}
- // Apply any launch flags from the ActivityOptions. This is used only by SystemUI
- // to ensure that we can launch the pending intent with a consistent launch mode even
- // if the provided PendingIntent is immutable (ie. to force an activity to launch into
- // a new task, or to launch multiple instances if supported by the app)
+ // Apply any launch flags from the ActivityOptions. This is to ensure that the caller
+ // can specify a consistent launch mode even if the PendingIntent is immutable
final ActivityOptions opts = ActivityOptions.fromBundle(options);
if (opts != null) {
- // TODO(b/254490217): Move this check into SafeActivityOptions
- if (controller.mAtmInternal.isCallerRecents(Binder.getCallingUid())) {
- finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
- }
+ finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
}
// Extract options before clearing calling identity

View File

@ -1,140 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexander Grund <flamefire89@gmail.com>
Date: Sun, 26 Mar 2023 17:36:03 +0200
Subject: [PATCH] Revert "[RESTRICT AUTOMERGE] Trim the activity info of
another uid if no privilege"
This reverts commit bff14ff38a014fc3059c6bfe8a16aec9f5447554.
Reason for revert: apps crashed due to the top activity info trimmed
Bug: 264269392 263434196 263438172
Change-Id: I078080b14b7cf7c6e605739f22f40f86802d3950
(cherry picked from commit 5caf2dde3d264966e1ba0dd3e18a0524858157ba)
Merged-In: I078080b14b7cf7c6e605739f22f40f86802d3950
---
.../com/android/server/wm/AppTaskImpl.java | 3 +-
.../com/android/server/wm/RecentTasks.java | 7 ++--
.../com/android/server/wm/RunningTasks.java | 8 ++---
.../com/android/server/wm/TaskRecord.java | 34 -------------------
4 files changed, 5 insertions(+), 47 deletions(-)
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 900b59e0a8a2..1eb7455135c7 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -84,8 +84,7 @@ class AppTaskImpl extends IAppTask.Stub {
if (tr == null) {
throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
}
- return mService.getRecentTasks().createRecentTaskInfo(tr,
- true /* getTasksAllowed */);
+ return mService.getRecentTasks().createRecentTaskInfo(tr);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 56367f42886d..541a8bbc8865 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -944,7 +944,7 @@ class RecentTasks {
continue;
}
- final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr, getTasksAllowed);
+ final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
if (!getDetailedTasks) {
rti.baseIntent.replaceExtras((Bundle) null);
}
@@ -1715,15 +1715,12 @@ class RecentTasks {
/**
* Creates a new RecentTaskInfo from a TaskRecord.
*/
- ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr, boolean getTasksAllowed) {
+ ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr) {
ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
tr.fillTaskInfo(rti);
// Fill in some deprecated values
rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
rti.persistentId = rti.taskId;
- if (!getTasksAllowed) {
- TaskRecord.trimIneffectiveInfo(tr, rti);
- }
return rti;
}
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 3c2e36cf245d..81a85476c53a 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -69,7 +69,7 @@ class RunningTasks {
}
final TaskRecord task = iter.next();
- list.add(createRunningTaskInfo(task, allowed));
+ list.add(createRunningTaskInfo(task));
maxNum--;
}
}
@@ -77,15 +77,11 @@ class RunningTasks {
/**
* Constructs a {@link RunningTaskInfo} from a given {@param task}.
*/
- private RunningTaskInfo createRunningTaskInfo(TaskRecord task, boolean allowed) {
+ private RunningTaskInfo createRunningTaskInfo(TaskRecord task) {
final RunningTaskInfo rti = new RunningTaskInfo();
task.fillTaskInfo(rti);
// Fill in some deprecated values
rti.id = rti.taskId;
-
- if (!allowed) {
- TaskRecord.trimIneffectiveInfo(task, rti);
- }
return rti;
}
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 9de4c8121e4d..361f66e3106a 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -2436,40 +2436,6 @@ class TaskRecord extends ConfigurationContainer {
info.configuration.setTo(getConfiguration());
}
- /**
- * Removes the activity info if the activity belongs to a different uid, which is
- * different from the app that hosts the task.
- */
- static void trimIneffectiveInfo(TaskRecord task, TaskInfo info) {
- int topActivityUid = task.effectiveUid;
- for (int i = task.mActivities.size() - 1; i >= 0; --i) {
- final ActivityRecord r = task.mActivities.get(i);
- if (r.finishing || r.isState(ActivityState.INITIALIZING)) {
- continue;
- }
- topActivityUid = r.info.applicationInfo.uid;
- break;
- }
-
- if (task.effectiveUid != topActivityUid) {
- info.topActivity = null;
- }
-
- int baseActivityUid = task.effectiveUid;
- for (int i = 0; i < task.mActivities.size(); ++i) {
- final ActivityRecord r = task.mActivities.get(i);
- if (r.finishing) {
- continue;
- }
- baseActivityUid = r.info.applicationInfo.uid;
- break;
- }
-
- if (task.effectiveUid != baseActivityUid) {
- info.baseActivity = null;
- }
- }
-
/**
* Returns a {@link TaskInfo} with information from this task.
*/

View File

@ -1,82 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Liahav Eitan <liahav@google.com>
Date: Tue, 11 Oct 2022 13:20:52 +0000
Subject: [PATCH] Fix sharing to another profile where an app has multiple
targets
Moves the fixUris call from onTargetSelected directly to the intent
launch to ensure the intent which is actually started is updated with
userId specific URIs.
This is a backport of ag/19657256 and ag/20063949.
Bug:242165528
Bug:244876518
Bug:242605257
Test: manually share image from personal profile to work gmail,
first with chat target then backing up and selecting the main target
Test: manually share image from work Photos app to personal WhatsApp's
frequent contact target.
Change-Id: Id815984e691bf962e19e30a54f7247d16060b3b8
Merged-In: Id815984e691bf962e19e30a54f7247d16060b3b8
Merged-In: Ib41c8a3c46afcc2d62a4c1a924212bcd98bcfbe4
Merged-In: Iabf5dcf2612fe718f2f0886e2e5e9b76f37af1e1
(cherry picked from commit f50ced5f1e619d7fa7858748d6a9dbe861354f04)
Merged-In: Id815984e691bf962e19e30a54f7247d16060b3b8
(cherry picked from commit 0b4cfaca78dfadd546adc47cbcbcdde5425cf17a)
---
.../com/android/internal/app/ChooserActivity.java | 1 +
.../com/android/internal/app/ResolverActivity.java | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 4d71911921a8..f43ff17ed7d0 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2455,6 +2455,7 @@ public class ChooserActivity extends ResolverActivity {
}
intent.setComponent(mChooserTarget.getComponentName());
intent.putExtras(mChooserTarget.getIntentExtras());
+ TargetInfo.prepareIntentForCrossProfileLaunch(intent, userId);
// Important: we will ignore the target security checks in ActivityManager
// if and only if the ChooserTarget's target package is the same package
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 070e3c101c8e..3de79838eaff 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1514,6 +1514,7 @@ public class ResolverActivity extends Activity {
if (mEnableChooserDelegate) {
return activity.startAsCallerImpl(mResolvedIntent, options, false, userId);
} else {
+ TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId);
activity.startActivityAsCaller(mResolvedIntent, options, null, false, userId);
return true;
}
@@ -1521,6 +1522,7 @@ public class ResolverActivity extends Activity {
@Override
public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
+ TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier());
activity.startActivityAsUser(mResolvedIntent, options, user);
return false;
}
@@ -1642,6 +1644,17 @@ public class ResolverActivity extends Activity {
* @return true if this target should be pinned to the front by the request of the user
*/
boolean isPinned();
+
+ /**
+ * Fix the URIs in {@code intent} if cross-profile sharing is required. This should be called
+ * before launching the intent as another user.
+ */
+ static void prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId) {
+ final int currentUserId = UserHandle.myUserId();
+ if (targetUserId != currentUserId) {
+ intent.fixUris(currentUserId);
+ }
+ }
}
public class ResolveListAdapter extends BaseAdapter {

View File

@ -1,76 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jing Ji <jji@google.com>
Date: Thu, 4 Aug 2022 11:36:26 -0700
Subject: [PATCH] DO NOT MERGE: Context#startInstrumentation could be started
from SHELL only now.
Or, if an instrumentation starts another instrumentation and so on,
and the original instrumentation is started from SHELL, allow all
Context#startInstrumentation calls in this chain.
Otherwise, it'll throw a SecurityException.
Bug: 237766679
Test: atest CtsAppTestCases:InstrumentationTest
Merged-In: Ia08f225c21a3933067d066a578ea4af9c23e7d4c
Merged-In: I1b76f61c5fd6c9f7e738978592260945a606f40c
Merged-In: I3ea7aa27bd776fec546908a37f667f680da9c892
Change-Id: I7ca7345b064e8e74f7037b8fa3ed45bb6423e406
(cherry picked from commit 8c90891a38ecb5047e115e13baf700a8b486a5d1)
Merged-In: I7ca7345b064e8e74f7037b8fa3ed45bb6423e406
---
.../server/am/ActivityManagerService.java | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bb78408617b8..efbccb3b8f94 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15761,6 +15761,17 @@ public class ActivityManagerService extends IActivityManager.Stub
reportStartInstrumentationFailureLocked(watcher, className, msg);
throw new SecurityException(msg);
}
+ if (!Build.IS_DEBUGGABLE && callingUid != ROOT_UID && callingUid != SHELL_UID
+ && callingUid != SYSTEM_UID && !hasActiveInstrumentationLocked(callingPid)) {
+ // If it's not debug build and not called from root/shell/system uid, reject it.
+ final String msg = "Permission Denial: instrumentation test "
+ + className + " from pid=" + callingPid + ", uid=" + callingUid
+ + ", pkgName=" + getPackageNameByPid(callingPid)
+ + " not allowed because it's not started from SHELL";
+ Slog.wtfQuiet(TAG, msg);
+ reportStartInstrumentationFailureLocked(watcher, className, msg);
+ throw new SecurityException(msg);
+ }
ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
activeInstr.mClass = className;
@@ -15817,6 +15828,29 @@ public class ActivityManagerService extends IActivityManager.Stub
return true;
}
+ @GuardedBy("this")
+ private boolean hasActiveInstrumentationLocked(int pid) {
+ if (pid == 0) {
+ return false;
+ }
+ synchronized (mPidsSelfLocked) {
+ ProcessRecord process = mPidsSelfLocked.get(pid);
+ return process != null && process.getActiveInstrumentation() != null;
+ }
+ }
+
+ private String getPackageNameByPid(int pid) {
+ synchronized (mPidsSelfLocked) {
+ final ProcessRecord app = mPidsSelfLocked.get(pid);
+
+ if (app != null && app.info != null) {
+ return app.info.packageName;
+ }
+
+ return null;
+ }
+ }
+
private boolean isCallerShell() {
final int callingUid = Binder.getCallingUid();
return callingUid == SHELL_UID || callingUid == ROOT_UID;

View File

@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kunal Malhotra <malhk@google.com>
Date: Mon, 7 Nov 2022 23:33:55 +0000
Subject: [PATCH] Checking if package belongs to UID before registering
broadcast receiver
Test: manual testing done on device by installing test APK and checking if receiver can register
Bug: 242040055
Change-Id: Ia525f218a46f8bf7fff660cec0d6432f09fdf24d
Merged-In: Ia525f218a46f8bf7fff660cec0d6432f09fdf24d
(cherry picked from commit 790a8d0dd329460bc60456681cb446accf2a27e0)
(cherry picked from commit 4f0dc37b896e06086391e71ce471e413215e1130)
Merged-In: Ia525f218a46f8bf7fff660cec0d6432f09fdf24d
---
services/core/java/com/android/server/am/ActiveServices.java | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 84702ddfe231..c6d94eb3b408 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2186,6 +2186,11 @@ public final class ActiveServices {
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
+ className + " is not an isolatedProcess");
}
+ if (AppGlobals.getPackageManager().getPackageUid(callingPackage,
+ 0, userId) != callingUid) {
+ throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
+ + "calling package not owned by calling UID ");
+ }
// Run the service under the calling package's application.
ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);

View File

@ -1,71 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hao Ke <haok@google.com>
Date: Mon, 12 Dec 2022 15:49:16 +0000
Subject: [PATCH] Fix checkKeyIntentParceledCorrectly's bypass
The checkKeyIntentParceledCorrectly method was added in checkKeyIntent, which was originaly only invoked when AccountManagerService deserializes the KEY_INTENT value as not NULL. However, due to the self-changing bundle technique in Parcel mismatch problems, the Intent value can change after reparceling; hence would bypass the added checkKeyIntentParceledCorrectly call.
This CL did the following:
- Ensure the checkKeyIntent method is also called when result.getParcelable(AccountManager.KEY_INTENT) == null.
Bug: 260567867
Bug: 262230405
Test: local test, see b/262230405
Test: atest CtsAccountManagerTestCases
Merged-In: I7b528f52c41767ae12731838fdd36aa26a8f3477
Change-Id: I7b528f52c41767ae12731838fdd36aa26a8f3477
(cherry picked from commit 9f623983a8d4ec48d58b0eda56fa461fc6748981)
Merged-In: I7b528f52c41767ae12731838fdd36aa26a8f3477
---
.../server/accounts/AccountManagerService.java | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 58978a55a32a..b4edf94927b2 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3434,8 +3434,7 @@ public class AccountManagerService
Bundle.setDefusable(result, true);
mNumResults++;
Intent intent = null;
- if (result != null
- && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+ if (result != null) {
if (!checkKeyIntent(
Binder.getCallingUid(),
result)) {
@@ -4800,8 +4799,10 @@ public class AccountManagerService
EventLog.writeEvent(0x534e4554, "250588548", authUid, "");
return false;
}
-
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
+ if (intent == null) {
+ return true;
+ }
// Explicitly set an empty ClipData to ensure that we don't offer to
// promote any Uris contained inside for granting purposes
if (intent.getClipData() == null) {
@@ -4854,7 +4855,10 @@ public class AccountManagerService
p.recycle();
Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT);
- return (intent.filterEquals(simulateIntent));
+ if (intent == null) {
+ return (simulateIntent == null);
+ }
+ return intent.filterEquals(simulateIntent);
}
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
@@ -4999,8 +5003,7 @@ public class AccountManagerService
}
}
}
- if (result != null
- && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
+ if (result != null) {
if (!checkKeyIntent(
Binder.getCallingUid(),
result)) {

View File

@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Winson Chiu <chiuwinson@google.com>
Date: Fri, 6 Jan 2023 21:26:24 +0000
Subject: [PATCH] Encode Intent scheme when serializing to URI string RESTRICT
AUTOMERGE
Avoids deserialization error when the scheme contains a
reserved character.
Bug: 261858325
Test: atest android.content.cts.IntentTest#testEncoding
Merged-In: Ic34b3f796b762763db5aa7b5d7c109ae70607470
Change-Id: Ic34b3f796b762763db5aa7b5d7c109ae70607470
(cherry picked from commit 43437b4ee6424933d4e403f0375ef8c1f07986f4)
Merged-In: Ic34b3f796b762763db5aa7b5d7c109ae70607470
---
core/java/android/content/Intent.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d7898776965e..72e0fa615b09 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -10393,7 +10393,7 @@ public class Intent implements Parcelable, Cloneable {
private void toUriInner(StringBuilder uri, String scheme, String defAction,
String defPackage, int flags) {
if (scheme != null) {
- uri.append("scheme=").append(scheme).append(';');
+ uri.append("scheme=").append(Uri.encode(scheme)).append(';');
}
if (mAction != null && !mAction.equals(defAction)) {
uri.append("action=").append(Uri.encode(mAction)).append(';');

View File

@ -1,430 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Pinelli <cpinelli@google.com>
Date: Tue, 27 Dec 2022 20:29:33 +0000
Subject: [PATCH] Backport BAL restrictions from S to R, this blocks apps from
using Alarm Manager to bypass BAL restrictions.
Test: atest BackgroundActivityLaunchTest
Bug: 195756028
Change-Id: Ifa3f79bc74c10d0ac8322079f2e6e3e0ba476b0f
(cherry picked from commit 1d737c2fbdc71570bbcaca0f44da4ee132fa545f)
Merged-In: Ifa3f79bc74c10d0ac8322079f2e6e3e0ba476b0f
---
core/java/android/app/ActivityOptions.java | 10 +--
core/java/android/app/BroadcastOptions.java | 25 +++++-
core/java/android/app/ComponentOptions.java | 84 +++++++++++++++++++
.../android/server/AlarmManagerService.java | 21 ++++-
.../server/am/PendingIntentRecord.java | 23 ++++-
.../android/server/wm/ActivityStarter.java | 22 +++--
.../server/wm/ActivityTaskManagerService.java | 2 +-
.../com/android/server/wm/AppTaskImpl.java | 2 +-
8 files changed, 169 insertions(+), 20 deletions(-)
create mode 100644 core/java/android/app/ComponentOptions.java
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 926044bffdd0..36ab62aedc09 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -59,7 +59,7 @@ import java.util.ArrayList;
* {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
* Context.startActivity(Intent, Bundle)} and related methods.
*/
-public class ActivityOptions {
+public class ActivityOptions extends ComponentOptions {
private static final String TAG = "ActivityOptions";
/**
@@ -881,13 +881,12 @@ public class ActivityOptions {
}
private ActivityOptions() {
+ super();
}
/** @hide */
public ActivityOptions(Bundle opts) {
- // If the remote side sent us bad parcelables, they won't get the
- // results they want, which is their loss.
- opts.setDefusable(true);
+ super(opts);
mPackageName = opts.getString(KEY_PACKAGE_NAME);
try {
@@ -1439,8 +1438,9 @@ public class ActivityOptions {
* object; you must not modify it, but can supply it to the startActivity
* methods that take an options Bundle.
*/
+ @Override
public Bundle toBundle() {
- Bundle b = new Bundle();
+ Bundle b = super.toBundle();
if (mPackageName != null) {
b.putString(KEY_PACKAGE_NAME, mPackageName);
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 161e2ad06ec0..8947fb44b07b 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -28,7 +28,7 @@ import android.os.Bundle;
* {@hide}
*/
@SystemApi
-public class BroadcastOptions {
+public class BroadcastOptions extends ComponentOptions {
private long mTemporaryAppWhitelistDuration;
private int mMinManifestReceiverApiLevel = 0;
private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
@@ -72,10 +72,12 @@ public class BroadcastOptions {
}
private BroadcastOptions() {
+ super();
}
/** @hide */
public BroadcastOptions(Bundle opts) {
+ super(opts);
mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION);
mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0);
mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL,
@@ -173,6 +175,24 @@ public class BroadcastOptions {
return mAllowBackgroundActivityStarts;
}
+ /**
+ * Set PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ * @hide
+ */
+ public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
+ super.setPendingIntentBackgroundActivityLaunchAllowed(allowed);
+ }
+
+ /**
+ * Get PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ * @hide
+ */
+ public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
+ return super.isPendingIntentBackgroundActivityLaunchAllowed();
+ }
+
/**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#sendBroadcast(android.content.Intent)
@@ -181,8 +201,9 @@ public class BroadcastOptions {
* object; you must not modify it, but can supply it to the sendBroadcast
* methods that take an options Bundle.
*/
+ @Override
public Bundle toBundle() {
- Bundle b = new Bundle();
+ Bundle b = super.toBundle();
if (mTemporaryAppWhitelistDuration > 0) {
b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration);
}
diff --git a/core/java/android/app/ComponentOptions.java b/core/java/android/app/ComponentOptions.java
new file mode 100644
index 000000000000..34ee9138a364
--- /dev/null
+++ b/core/java/android/app/ComponentOptions.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+public class ComponentOptions {
+
+ /**
+ * Default value for KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED.
+ * @hide
+ **/
+ public static final boolean PENDING_INTENT_BAL_ALLOWED_DEFAULT = true;
+
+ /**
+ * PendingIntent caller allows activity start even if PendingIntent creator is in background.
+ * This only works if the PendingIntent caller is allowed to start background activities,
+ * for example if it's in the foreground, or has BAL permission.
+ * @hide
+ */
+ public static final String KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED =
+ "android.pendingIntent.backgroundActivityAllowed";
+
+ private boolean mPendingIntentBalAllowed = PENDING_INTENT_BAL_ALLOWED_DEFAULT;
+
+ ComponentOptions() {
+ }
+
+ ComponentOptions(Bundle opts) {
+ // If the remote side sent us bad parcelables, they won't get the
+ // results they want, which is their loss.
+ opts.setDefusable(true);
+ setPendingIntentBackgroundActivityLaunchAllowed(
+ opts.getBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
+ PENDING_INTENT_BAL_ALLOWED_DEFAULT));
+ }
+
+ /**
+ * Set PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ *
+ * @hide
+ */
+ public void setPendingIntentBackgroundActivityLaunchAllowed(boolean allowed) {
+ mPendingIntentBalAllowed = allowed;
+ }
+
+ /**
+ * Get PendingIntent activity is allowed to be started in the background if the caller
+ * can start background activities.
+ *
+ * @hide
+ */
+ public boolean isPendingIntentBackgroundActivityLaunchAllowed() {
+ return mPendingIntentBalAllowed;
+ }
+
+ /**
+ * @hide
+ */
+ public Bundle toBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
+ mPendingIntentBalAllowed);
+ return bundle;
+ }
+}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a65603cb4020..d82b435b4612 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -26,6 +26,7 @@ import static android.app.AlarmManager.RTC_WAKEUP;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
@@ -272,6 +273,8 @@ class AlarmManagerService extends SystemService {
* Broadcast options to use for FLAG_ALLOW_WHILE_IDLE.
*/
Bundle mIdleOptions;
+ ActivityOptions mActivityOptsRestrictBal = ActivityOptions.makeBasic();
+ BroadcastOptions mBroadcastOptsRestrictBal = BroadcastOptions.makeBasic();
private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
new SparseArray<>();
@@ -497,6 +500,7 @@ class AlarmManagerService extends SystemService {
mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION;
BroadcastOptions opts = BroadcastOptions.makeBasic();
opts.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION);
+ opts.setPendingIntentBackgroundActivityLaunchAllowed(false);
mIdleOptions = opts.toBundle();
}
}
@@ -1495,6 +1499,8 @@ class AlarmManagerService extends SystemService {
@Override
public void onStart() {
mInjector.init();
+ mActivityOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mBroadcastOptsRestrictBal.setPendingIntentBackgroundActivityLaunchAllowed(false);
synchronized (mLock) {
mHandler = new AlarmHandler();
@@ -4143,6 +4149,13 @@ class AlarmManagerService extends SystemService {
return alarm.creatorUid;
}
+ private Bundle getAlarmOperationBundle(Alarm alarm) {
+ if (alarm.operation.isActivity()) {
+ return mActivityOptsRestrictBal.toBundle();
+ }
+ return mBroadcastOptsRestrictBal.toBundle();
+ }
+
@VisibleForTesting
class AlarmHandler extends Handler {
public static final int ALARM_EVENT = 1;
@@ -4181,7 +4194,11 @@ class AlarmManagerService extends SystemService {
for (int i=0; i<triggerList.size(); i++) {
Alarm alarm = triggerList.get(i);
try {
- alarm.operation.send();
+ // Disallow AlarmManager to start random background activity.
+ final Bundle bundle = getAlarmOperationBundle(alarm);
+ alarm.operation.send(/* context */ null, /* code */0, /* intent */
+ null, /* onFinished */null, /* handler */
+ null, /* requiredPermission */ null, bundle);
} catch (PendingIntent.CanceledException e) {
if (alarm.repeatInterval > 0) {
// This IntentSender is no longer valid, but this
@@ -4696,7 +4713,7 @@ class AlarmManagerService extends SystemService {
mBackgroundIntent.putExtra(
Intent.EXTRA_ALARM_COUNT, alarm.count),
mDeliveryTracker, mHandler, null,
- allowWhileIdle ? mIdleOptions : null);
+ allowWhileIdle ? mIdleOptions : getAlarmOperationBundle(alarm));
} catch (PendingIntent.CanceledException e) {
if (alarm.repeatInterval > 0) {
// This IntentSender is no longer valid, but this
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 54504c3c1e24..20d87e6882ac 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -20,6 +20,7 @@ import static android.app.ActivityManager.START_SUCCESS;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.IIntentSender;
@@ -277,6 +278,25 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
requiredPermission, null, null, 0, 0, 0, options);
}
+ /**
+ * Return true if the activity options allows PendingIntent to use caller's BAL permission.
+ */
+ public static boolean isPendingIntentBalAllowedByCaller(
+ @Nullable ActivityOptions activityOptions) {
+ if (activityOptions == null) {
+ return ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
+ }
+ return isPendingIntentBalAllowedByCaller(activityOptions.toBundle());
+ }
+
+ private static boolean isPendingIntentBalAllowedByCaller(@Nullable Bundle options) {
+ if (options == null) {
+ return ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT;
+ }
+ return options.getBoolean(ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED,
+ ActivityOptions.PENDING_INTENT_BAL_ALLOWED_DEFAULT);
+ }
+
public int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo,
String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) {
@@ -389,7 +409,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
// temporarily allow receivers and services to open activities from background if the
// PendingIntent.send() caller was foreground at the time of sendInner() call
final boolean allowTrampoline = uid != callingUid
- && controller.mAtmInternal.isUidForeground(callingUid);
+ && controller.mAtmInternal.isUidForeground(callingUid)
+ && isPendingIntentBalAllowedByCaller(options);
// note: we on purpose don't pass in the information about the PendingIntent's creator,
// like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index f37698de34d5..44fef5427cc3 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -767,6 +767,10 @@ class ActivityStarter {
abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
callingPackage);
+ // Merge the two options bundles, while realCallerOptions takes precedence.
+ ActivityOptions checkedOptions = options != null
+ ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
+
boolean restrictedBgActivity = false;
if (!abort) {
try {
@@ -774,15 +778,12 @@ class ActivityStarter {
"shouldAbortBackgroundActivityStart");
restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
- originatingPendingIntent, allowBackgroundActivityStart, intent);
+ originatingPendingIntent, allowBackgroundActivityStart, intent, checkedOptions);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
- // Merge the two options bundles, while realCallerOptions takes precedence.
- ActivityOptions checkedOptions = options != null
- ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
if (allowPendingRemoteAnimationRegistryLookup) {
checkedOptions = mService.getActivityStartController()
.getPendingRemoteAnimationRegistry()
@@ -941,7 +942,7 @@ class ActivityStarter {
boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
final String callingPackage, int realCallingUid, int realCallingPid,
WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
- boolean allowBackgroundActivityStart, Intent intent) {
+ boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) {
// don't abort for the most important UIDs
final int callingAppId = UserHandle.getAppId(callingUid);
if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
@@ -976,7 +977,11 @@ class ActivityStarter {
? isCallingUidPersistentSystemProcess
: (realCallingAppId == Process.SYSTEM_UID)
|| realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
- if (realCallingUid != callingUid) {
+ // Legacy behavior allows to use caller foreground state to bypass BAL restriction.
+ final boolean balAllowedByPiSender =
+ PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions);
+
+ if (balAllowedByPiSender && realCallingUid != callingUid) {
// don't abort if the realCallingUid has a visible window
if (realCallingUidHasAnyVisibleWindow) {
return false;
@@ -1013,9 +1018,10 @@ class ActivityStarter {
// If we don't have callerApp at this point, no caller was provided to startActivity().
// That's the case for PendingIntent-based starts, since the creator's process might not be
// up and alive. If that's the case, we retrieve the WindowProcessController for the send()
- // caller, so that we can make the decision based on its foreground/whitelisted state.
+ // caller if caller allows, so that we can make the decision
+ // based on its foreground/whitelisted state.
int callerAppUid = callingUid;
- if (callerApp == null) {
+ if (callerApp == null && balAllowedByPiSender) {
callerApp = mService.getProcessController(realCallingPid, realCallingUid);
callerAppUid = realCallingUid;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 5e2626b9a7dd..d0dad0a23729 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2398,7 +2398,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final ActivityStarter starter = getActivityStartController().obtainStarter(
null /* intent */, "moveTaskToFront");
if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1,
- -1, callerApp, null, false, null)) {
+ -1, callerApp, null, false, null, null)) {
if (!isBackgroundActivityStartsEnabled()) {
return;
}
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 1eb7455135c7..f221c3a4573f 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -117,7 +117,7 @@ class AppTaskImpl extends IAppTask.Stub {
final ActivityStarter starter = mService.getActivityStartController().obtainStarter(
null /* intent */, "moveToFront");
if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid,
- callingPackage, -1, -1, callerApp, null, false, null)) {
+ callingPackage, -1, -1, callerApp, null, false, null, null)) {
if (!mService.isBackgroundActivityStartsEnabled()) {
return;
}

View File

@ -1,152 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Louis Chang <louischang@google.com>
Date: Wed, 28 Sep 2022 06:46:29 +0000
Subject: [PATCH] Strip part of the activity info of another uid if no
privilege
The activity info could be from another uid which is different
from the app that hosts the task. The information should be
trimmed if the caller app doesn't have the privilege.
However, removing the entire info may result in app compatibility
issues. So, only swiping the info that are sensitive to empty
string.
Bug: 243130512
Test: verified market app locally
Test: atest RecentTasksTest
Change-Id: I5b6775dd3c4e2ccdacd30741884d336b2eaa70da
Merged-In: I5b6775dd3c4e2ccdacd30741884d336b2eaa70da
(cherry picked from commit 5ba72200f6a66b5da48c9c3abd103a73aea1ef95)
(cherry picked from commit e534fa2a7119f39cb76f1d08557b7dcae3b6d94e)
(cherry picked from commit 20fc1c7244cdf840e4a6cbfa71904b4d608bb093)
Merged-In: I5b6775dd3c4e2ccdacd30741884d336b2eaa70da
---
.../com/android/server/wm/AppTaskImpl.java | 3 +-
.../com/android/server/wm/RecentTasks.java | 8 +++--
.../com/android/server/wm/RunningTasks.java | 7 ++++
.../com/android/server/wm/TaskRecord.java | 34 +++++++++++++++++++
4 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index f221c3a4573f..e12c8259d8a7 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -84,7 +84,8 @@ class AppTaskImpl extends IAppTask.Stub {
if (tr == null) {
throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
}
- return mService.getRecentTasks().createRecentTaskInfo(tr);
+ return mService.getRecentTasks().createRecentTaskInfo(tr,
+ true /* getTasksAllowed */);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 541a8bbc8865..67fb4c28cf22 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -944,7 +944,7 @@ class RecentTasks {
continue;
}
- final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
+ final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr, getTasksAllowed);
if (!getDetailedTasks) {
rti.baseIntent.replaceExtras((Bundle) null);
}
@@ -1715,12 +1715,16 @@ class RecentTasks {
/**
* Creates a new RecentTaskInfo from a TaskRecord.
*/
- ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr) {
+ ActivityManager.RecentTaskInfo createRecentTaskInfo(TaskRecord tr,
+ boolean getTasksAllowed) {
ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
tr.fillTaskInfo(rti);
// Fill in some deprecated values
rti.id = rti.isRunning ? rti.taskId : INVALID_TASK_ID;
rti.persistentId = rti.taskId;
+ if (!getTasksAllowed) {
+ TaskRecord.trimIneffectiveInfo(tr, rti);
+ }
return rti;
}
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 81a85476c53a..16d041a7a1c0 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -39,6 +39,8 @@ class RunningTasks {
private final TreeSet<TaskRecord> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR);
private final ArrayList<TaskRecord> mTmpStackTasks = new ArrayList<>();
+ private boolean mAllowed;
+
void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
@WindowingMode int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
@@ -49,6 +51,7 @@ class RunningTasks {
// Gather all of the tasks across all of the tasks, and add them to the sorted set
mTmpSortedSet.clear();
+ mAllowed = allowed;
final int numDisplays = activityDisplays.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final ActivityDisplay display = activityDisplays.get(displayNdx);
@@ -82,6 +85,10 @@ class RunningTasks {
task.fillTaskInfo(rti);
// Fill in some deprecated values
rti.id = rti.taskId;
+
+ if (!mAllowed) {
+ TaskRecord.trimIneffectiveInfo(task, rti);
+ }
return rti;
}
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 361f66e3106a..78d13e95df81 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -2436,6 +2436,40 @@ class TaskRecord extends ConfigurationContainer {
info.configuration.setTo(getConfiguration());
}
+ /**
+ * Removes the activity info if the activity belongs to a different uid, which is
+ * different from the app that hosts the task.
+ */
+ static void trimIneffectiveInfo(TaskRecord task, TaskInfo info) {
+ int topActivityUid = task.effectiveUid;
+ for (int i = task.mActivities.size() - 1; i >= 0; --i) {
+ final ActivityRecord r = task.mActivities.get(i);
+ if (r.finishing || r.isState(ActivityState.INITIALIZING)) {
+ continue;
+ }
+ topActivityUid = r.info.applicationInfo.uid;
+ break;
+ }
+
+ if (task.effectiveUid != topActivityUid) {
+ info.topActivity = new ComponentName("", "");
+ }
+
+ int baseActivityUid = task.effectiveUid;
+ for (int i = 0; i < task.mActivities.size(); ++i) {
+ final ActivityRecord r = task.mActivities.get(i);
+ if (r.finishing) {
+ continue;
+ }
+ baseActivityUid = r.info.applicationInfo.uid;
+ break;
+ }
+
+ if (task.effectiveUid != baseActivityUid) {
+ info.baseActivity = new ComponentName("", "");
+ }
+ }
+
/**
* Returns a {@link TaskInfo} with information from this task.
*/

View File

@ -1,134 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Julia Reynolds <juliacr@google.com>
Date: Tue, 18 Jan 2022 11:59:54 -0500
Subject: [PATCH] Add a limit on channel group creation
Same as exists for channels
This is a backport of the fix in ag/16659457, including the adjustment from ag/20920023 (changed the max value from 50000 to 6000).
Test: PreferencesHelperTest
Bug: 210114537
Bug: 261723753
Change-Id: Ic27efba4c54e22eebca16fc948879e652df4467b
(cherry picked from commit 37b3549807d15452ac334fae316e615c3b9b8e8b & I3f3a99765c161369e1b026686a0e5f0c83ed839e)
Merged-In: I3f3a99765c161369e1b026686a0e5f0c83ed839e
Merged-In: Ic27efba4c54e22eebca16fc948879e652df4467b
(cherry picked from commit 0f29716ab6fbf236e5d8f688bcdfdadf32429545)
Merged-In: Ic27efba4c54e22eebca16fc948879e652df4467b
---
.../notification/PreferencesHelper.java | 16 ++++++-
.../notification/PreferencesHelperTest.java | 47 +++++++++++++++++++
2 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index d4ba51cc3146..1a3779f7c607 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -73,7 +73,9 @@ public class PreferencesHelper implements RankingConfig {
private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
@VisibleForTesting
- static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 50000;
+ static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000;
+ @VisibleForTesting
+ static final int NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT = 6000;
@VisibleForTesting
static final String TAG_RANKING = "ranking";
@@ -184,6 +186,7 @@ public class PreferencesHelper implements RankingConfig {
}
}
boolean skipWarningLogged = false;
+ boolean skipGroupWarningLogged = false;
PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid,
XmlUtils.readIntAttribute(
@@ -220,6 +223,14 @@ public class PreferencesHelper implements RankingConfig {
String tagName = parser.getName();
// Channel groups
if (TAG_GROUP.equals(tagName)) {
+ if (r.groups.size() >= NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT) {
+ if (!skipGroupWarningLogged) {
+ Slog.w(TAG, "Skipping further groups for " + r.pkg
+ + "; app has too many");
+ skipGroupWarningLogged = true;
+ }
+ continue;
+ }
String id = parser.getAttributeValue(null, ATT_ID);
CharSequence groupName = parser.getAttributeValue(null,
ATT_NAME);
@@ -610,6 +621,9 @@ public class PreferencesHelper implements RankingConfig {
}
if (fromTargetApp) {
group.setBlocked(false);
+ if (r.groups.size() >= NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT) {
+ throw new IllegalStateException("Limit exceed; cannot create more groups");
+ }
}
final NotificationChannelGroup oldGroup = r.groups.get(group.getId());
if (!group.equals(oldGroup)) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 2cede07de257..dfb62999be5f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -23,6 +23,7 @@ import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT;
+import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.fail;
@@ -2729,4 +2730,50 @@ public class PreferencesHelperTest extends UiServiceTestCase {
assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true));
assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true));
}
+
+ @Test
+ public void testTooManyGroups() {
+ for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) {
+ NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i),
+ String.valueOf(i));
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+ }
+ try {
+ NotificationChannelGroup group = new NotificationChannelGroup(
+ String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT),
+ String.valueOf(NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT));
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+ fail("Allowed to create too many notification channel groups");
+ } catch (IllegalStateException e) {
+ // great
+ }
+ }
+
+ @Test
+ public void testTooManyGroups_xml() throws Exception {
+ String extraGroup = "EXTRA";
+ String extraGroup1 = "EXTRA1";
+
+ // create first... many... directly so we don't need a big xml blob in this test
+ for (int i = 0; i < NOTIFICATION_CHANNEL_GROUP_COUNT_LIMIT; i++) {
+ NotificationChannelGroup group = new NotificationChannelGroup(String.valueOf(i),
+ String.valueOf(i));
+ mHelper.createNotificationChannelGroup(PKG_O, UID_O, group, true);
+ }
+
+ final String xml = "<ranking version=\"1\">\n"
+ + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+ + "<channelGroup id=\"" + extraGroup + "\" name=\"hi\"/>"
+ + "<channelGroup id=\"" + extraGroup1 + "\" name=\"hi2\"/>"
+ + "</package>"
+ + "</ranking>";
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+ null);
+ parser.nextTag();
+ mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+ assertNull(mHelper.getNotificationChannelGroup(extraGroup, PKG_O, UID_O));
+ assertNull(mHelper.getNotificationChannelGroup(extraGroup1, PKG_O, UID_O));
+ }
}

View File

@ -1,241 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rhed Jao <rhedjao@google.com>
Date: Wed, 11 Jan 2023 16:02:27 +0800
Subject: [PATCH] Fix bypass BG-FGS and BAL via package manager APIs
Opt-in for BAL of PendingIntent for following APIs:
* PackageInstaller.uninstall()
* PackageInstaller.installExistingPackage()
* PackageInstaller.uninstallExistingPackage()
* PackageInstaller.Session.commit()
* PackageInstaller.Session.commitTransferred()
* PackageManager.freeStorage()
Bug: 230492955
Bug: 243377226
Test: atest android.security.cts.PackageInstallerTest
Test: atest CtsStagedInstallHostTestCases
Change-Id: I9b6f801d69ea6d2244a38dbe689e81afa4e798bf
(cherry picked from commit b0b1ddb4b4ba5db27f5616b02ae2cdca8b63496f)
Merged-In: I9b6f801d69ea6d2244a38dbe689e81afa4e798bf
---
core/java/android/content/IntentSender.java | 42 ++++++++++++++++++-
.../server/pm/PackageInstallerService.java | 21 ++++++++--
.../server/pm/PackageInstallerSession.java | 19 +++++++--
.../server/pm/PackageManagerService.java | 10 ++++-
4 files changed, 81 insertions(+), 11 deletions(-)
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index ec0bac486c65..0ef0a71fffe0 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -16,8 +16,10 @@
package android.content;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.Handler;
@@ -154,7 +156,7 @@ public class IntentSender implements Parcelable {
*/
public void sendIntent(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler) throws SendIntentException {
- sendIntent(context, code, intent, onFinished, handler, null);
+ sendIntent(context, code, intent, onFinished, handler, null, null /* options */);
}
/**
@@ -186,6 +188,42 @@ public class IntentSender implements Parcelable {
public void sendIntent(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler, String requiredPermission)
throws SendIntentException {
+ sendIntent(context, code, intent, onFinished, handler, requiredPermission,
+ null /* options */);
+ }
+
+ /**
+ * Perform the operation associated with this IntentSender, allowing the
+ * caller to specify information about the Intent to use and be notified
+ * when the send has completed.
+ *
+ * @param context The Context of the caller. This may be null if
+ * <var>intent</var> is also null.
+ * @param code Result code to supply back to the IntentSender's target.
+ * @param intent Additional Intent data. See {@link Intent#fillIn
+ * Intent.fillIn()} for information on how this is applied to the
+ * original Intent. Use null to not modify the original Intent.
+ * @param onFinished The object to call back on when the send has
+ * completed, or null for no callback.
+ * @param handler Handler identifying the thread on which the callback
+ * should happen. If null, the callback will happen from the thread
+ * pool of the process.
+ * @param requiredPermission Name of permission that a recipient of the PendingIntent
+ * is required to hold. This is only valid for broadcast intents, and
+ * corresponds to the permission argument in
+ * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}.
+ * If null, no permission is required.
+ * @param options Additional options the caller would like to provide to modify the sending
+ * behavior. May be built from an {@link ActivityOptions} to apply to an activity start.
+ *
+ * @throws SendIntentException Throws CanceledIntentException if the IntentSender
+ * is no longer allowing more intents to be sent through it.
+ * @hide
+ */
+ public void sendIntent(Context context, int code, Intent intent,
+ OnFinished onFinished, Handler handler, String requiredPermission,
+ @Nullable Bundle options)
+ throws SendIntentException {
try {
String resolvedType = intent != null ?
intent.resolveTypeIfNeeded(context.getContentResolver())
@@ -195,7 +233,7 @@ public class IntentSender implements Parcelable {
onFinished != null
? new FinishedDispatcher(this, onFinished, handler)
: null,
- requiredPermission, null);
+ requiredPermission, options);
if (res < 0) {
throw new SendIntentException();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index c73f489cb143..ea144fd7c4d5 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -23,6 +23,7 @@ import android.Manifest;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PackageDeleteObserver;
@@ -1021,7 +1022,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
PackageInstaller.STATUS_PENDING_USER_ACTION);
fillIn.putExtra(Intent.EXTRA_INTENT, intent);
try {
- mTarget.sendIntent(mContext, 0, fillIn, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
+ null /* handler */, null /* requiredPermission */, options.toBundle());
} catch (SendIntentException ignored) {
}
}
@@ -1046,7 +1050,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
PackageManager.deleteStatusToString(returnCode, msg));
fillIn.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, returnCode);
try {
- mTarget.sendIntent(mContext, 0, fillIn, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
+ null /* handler */, null /* requiredPermission */, options.toBundle());
} catch (SendIntentException ignored) {
}
}
@@ -1076,7 +1083,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
PackageInstaller.STATUS_PENDING_USER_ACTION);
fillIn.putExtra(Intent.EXTRA_INTENT, intent);
try {
- mTarget.sendIntent(mContext, 0, fillIn, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
+ null /* handler */, null /* requiredPermission */, options.toBundle());
} catch (SendIntentException ignored) {
}
}
@@ -1116,7 +1126,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
}
}
try {
- mTarget.sendIntent(mContext, 0, fillIn, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mTarget.sendIntent(mContext, 0, fillIn, null /* onFinished*/,
+ null /* handler */, null /* requiredPermission */, options.toBundle());
} catch (SendIntentException ignored) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 5a880cb5fa52..71d06d8a2d03 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -44,6 +44,7 @@ import static com.android.server.pm.PackageInstallerService.prepareStageDir;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.BroadcastOptions;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
@@ -960,13 +961,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID,
PackageInstallerSession.this.sessionId);
- mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mStatusReceiver.sendIntent(mContext, 0, intent,
+ null /* onFinished*/, null /* handler */,
+ null /* requiredPermission */, options.toBundle());
} catch (IntentSender.SendIntentException ignore) {
}
}
} else if (PackageInstaller.STATUS_PENDING_USER_ACTION == status) {
try {
- mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mStatusReceiver.sendIntent(mContext, 0, intent,
+ null /* onFinished*/, null /* handler */,
+ null /* requiredPermission */, options.toBundle());
} catch (IntentSender.SendIntentException ignore) {
}
} else {
@@ -974,7 +983,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
PackageInstallerSession.this.sessionId);
mChildSessionsRemaining.clear(); // we're done. Don't send any more.
try {
- mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ mStatusReceiver.sendIntent(mContext, 0, intent,
+ null /* onFinished*/, null /* handler */,
+ null /* requiredPermission */, options.toBundle());
} catch (IntentSender.SendIntentException ignore) {
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 1bd1396c6d45..ef97d61d26d7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4893,7 +4893,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (pi != null) {
try {
- pi.sendIntent(null, success ? 1 : 0, null, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ pi.sendIntent(null, success ? 1 : 0, null /* intent */, null /* onFinished*/,
+ null /* handler */, null /* requiredPermission */, options.toBundle());
} catch (SendIntentException e) {
Slog.w(TAG, e);
}
@@ -13738,7 +13741,10 @@ public class PackageManagerService extends IPackageManager.Stub
fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
PackageManager.installStatusToPublicStatus(returnCode));
try {
- target.sendIntent(context, 0, fillIn, null, null);
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
+ target.sendIntent(context, 0, fillIn, null /* onFinished*/,
+ null /* handler */, null /* requiredPermission */, options.toBundle());
} catch (SendIntentException ignored) {
}
}

View File

@ -1,85 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Songchun Fan <schfan@google.com>
Date: Thu, 26 Jan 2023 17:43:24 -0800
Subject: [PATCH] prevent system app downgrades of versions lower than preload
Also remove misleading commandline output.
BUG: 256202273
Test: manual
1. Install preload system app v90, reboot
2. (W/O data, W/ Flag, 90->80 NOK) adb install -d ~/Downloads/PrivApplication_80.apk
Performing Streamed Install
adb: failed to install /usr/local/google/home/schfan/Downloads/PrivApplication_80.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE: System app: com.example.privapplication cannot be downgraded to older than its preloaded version on the system image. Update version code 80 is older than current 90]
3. (90->100) Install data app v100
4. (W/ data, W/O Flag, 100->90 NOK) adb install ~/Downloads/PrivApplication_90.apk
Performing Streamed Install
adb: failed to install /usr/local/google/home/schfan/Downloads/PrivApplication_90.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE: Downgrade detected: Update version code 90 is older than current 100]
5. (W/ data, W/ Flag, 100->90 downgrade OK) adb install -d ~/Downloads/PrivApplication_90.apk
Performing Streamed Install
Success
6. (90->100) Install v100
6. (W/data, W/ Flag, 100->80 NOK) adb install -d ~/Downloads/PrivApplication_80.apk
Performing Streamed Install
adb: failed to install /usr/local/google/home/schfan/Downloads/PrivApplication_80.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE: System app: com.example.privapplication cannot be downgraded to older than its preloaded version on the system image. Update version code 80 is older than current 90]
Change-Id: I5a8ee9e29a3a58f6e3fd188e0122355744b8b0ce
(cherry picked from commit a4484d7f1be1fa413258fe18644d61f85611f586)
(cherry picked from commit on googleplex-android-review.googlesource.com host: aec76152d65cfd5774f6c0dcf4cb6009ba48c1ee)
Merged-In: I5a8ee9e29a3a58f6e3fd188e0122355744b8b0ce
---
.../server/pm/PackageManagerService.java | 26 ++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ef97d61d26d7..068cb345d463 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15281,10 +15281,10 @@ public class PackageManagerService extends IPackageManager.Stub
// will be null whereas dataOwnerPkg will contain information about the package
// which was uninstalled while keeping its data.
PackageParser.Package dataOwnerPkg = installedPkg;
+ PackageSetting dataOwnerPs= mSettings.mPackages.get(packageName);
if (dataOwnerPkg == null) {
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- dataOwnerPkg = ps.pkg;
+ if (dataOwnerPs != null) {
+ dataOwnerPkg = dataOwnerPs.pkg;
}
}
@@ -15308,12 +15308,32 @@ public class PackageManagerService extends IPackageManager.Stub
if (dataOwnerPkg != null) {
if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
dataOwnerPkg.applicationInfo.flags)) {
+ // Downgrade is not permitted; a lower version of the app will not be
+ // allowed
try {
checkDowngrade(dataOwnerPkg, pkgLite);
} catch (PackageManagerException e) {
Slog.w(TAG, "Downgrade detected: " + e.getMessage());
return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
}
+ } else if (dataOwnerPs.isSystem()) {
+ // Downgrade is permitted, but system apps can't be downgraded below
+ // the version preloaded onto the system image
+ final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
+ dataOwnerPs);
+ if (disabledPs != null) {
+ dataOwnerPkg = disabledPs.pkg;
+ }
+ try {
+ checkDowngrade(dataOwnerPkg, pkgLite);
+ } catch (PackageManagerException e) {
+ String errorMsg = "System app: " + packageName
+ + " cannot be downgraded to"
+ + " older than its preloaded version on the system image. "
+ + e.getMessage();
+ Slog.w(TAG, errorMsg);
+ return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
+ }
}
}

View File

@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Songchun Fan <schfan@google.com>
Date: Thu, 2 Feb 2023 10:35:56 -0800
Subject: [PATCH] [RESTRICT AUTOMERGE][pm] still allow debuggable for system
app downgrades
Turns out we do have internal tests that downgrades system apps, so adding this exception to allow for that.
BUG: 267232653
BUG: 256202273
Test: manual
Change-Id: Ie281bbdc8788ee64ff99a7c5150da7ce7926235e
(cherry picked from commit ceeca68b8c3f0ed8427b0212f63defe2f075146e)
(cherry picked from commit on googleplex-android-review.googlesource.com host: 341669af524058dd4c64a176ddc54ada589591e1)
Merged-In: Ie281bbdc8788ee64ff99a7c5150da7ce7926235e
---
.../server/pm/PackageManagerService.java | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 37b85cf4fe79..27282c0a2dda 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -15324,15 +15324,19 @@ private int installLocationPolicy(PackageInfoLite pkgLite) {
if (disabledPs != null) {
dataOwnerPkg = disabledPs.pkg;
}
- try {
- checkDowngrade(dataOwnerPkg, pkgLite);
- } catch (PackageManagerException e) {
- String errorMsg = "System app: " + packageName
- + " cannot be downgraded to"
- + " older than its preloaded version on the system image. "
- + e.getMessage();
- Slog.w(TAG, errorMsg);
- return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
+ if (!Build.IS_DEBUGGABLE && (dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
+ // Only restrict non-debuggable builds and non-debuggable version of
+ // the app
+ try {
+ checkDowngrade(dataOwnerPkg, pkgLite);
+ } catch (PackageManagerException e) {
+ String errorMsg = "System app: " + packageName
+ + " cannot be downgraded to"
+ + " older than its preloaded version on the system image. "
+ + e.getMessage();
+ Slog.w(TAG, errorMsg);
+ return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
+ }
}
}
}

View File

@ -1,81 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Norman <danielnorman@google.com>
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 90b80e73c323..5820dbee7e87 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -1585,6 +1585,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 cf24b8e1ffa6..3cb35a8723ab 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -31,6 +31,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;
@@ -850,6 +851,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 457f27e679ef..194c90e125f9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1371,6 +1371,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);

View File

@ -1,138 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Orion Hodson <oth@google.com>
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 +++++---
.../coretests/src/android/net/UriTest.java | 54 +++++++++++++++++++
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..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<Uri> {
}
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() {
@@ -2263,6 +2266,11 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
}
}
+ 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/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
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 {
public void testParcelling() {
parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
+ parcelAndUnparcel(Uri.fromParts("https", "www.google.com", null));
parcelAndUnparcel(new Uri.Builder()
.scheme("http")
.authority("crazybob.org")
@@ -873,9 +874,62 @@ public class UriTest extends TestCase {
Throwable targetException = expected.getTargetException();
// Check that the exception was thrown for the correct reason.
assertEquals("Unknown representation: 0", targetException.getMessage());
+ } finally {
+ parcel.recycle();
}
}
+ private Uri buildUriFromRawParcel(boolean argumentsEncoded,
+ String scheme,
+ String authority,
+ String path,
+ String query,
+ String fragment) {
+ // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}).
+ final int representation = argumentsEncoded ? 1 : 2;
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeInt(3); // hierarchical
+ parcel.writeString(scheme);
+ parcel.writeInt(representation);
+ parcel.writeString(authority);
+ parcel.writeInt(representation);
+ parcel.writeString(path);
+ parcel.writeInt(representation);
+ parcel.writeString(query);
+ parcel.writeInt(representation);
+ parcel.writeString(fragment);
+ parcel.setDataPosition(0);
+ return Uri.CREATOR.createFromParcel(parcel);
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+ public void testUnparcelMalformedPath() {
+ // Regression tests for b/171966843.
+
+ // Test cases with arguments encoded (covering testing `scheme` * `authority` options).
+ Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null);
+ assertEquals("https://google.com/@evil.com", uri0.toString());
+ Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x");
+ assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString());
+ Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null);
+ assertEquals("http::/@evil.com", uri2.toString());
+ Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null);
+ assertEquals("@evil.com", uri3.toString());
+
+ // Test cases with arguments not encoded (covering testing `scheme` * `authority` options).
+ Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null);
+ assertEquals("https://google.com/%40evil.com", uriA.toString());
+ Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null);
+ assertEquals("//google.com/%40evil.com", uriB.toString());
+ Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null);
+ assertEquals("http::/%40evil.com", uriC.toString());
+ Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y");
+ assertEquals("%40evil.com?name%3Dspark#y", uriD.toString());
+ }
+
public void testToSafeString() {
checkToSafeString("tel:xxxxxx", "tel:Google");
checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");

View File

@ -1,74 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thomas Stuart <tjstuart@google.com>
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 1b783b7beb7f..d0e9a40a1a15 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -466,6 +466,11 @@ public final class PhoneAccount implements Parcelable {
/**
* Sets the address. See {@link PhoneAccount#getAddress}.
+ * <p>
+ * 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.
@@ -499,6 +504,10 @@ public final class PhoneAccount implements Parcelable {
/**
* Sets the icon. See {@link PhoneAccount#getIcon}.
+ * <p>
+ * 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.
*/
@@ -532,6 +541,10 @@ public final class PhoneAccount implements Parcelable {
/**
* Specifies an additional URI scheme supported by the {@link PhoneAccount}.
*
+ * <p>
+ * 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.
*/
@@ -545,6 +558,12 @@ public final class PhoneAccount implements Parcelable {
/**
* Specifies the URI schemes supported by the {@link PhoneAccount}.
*
+ * <p>
+ * 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.
*/

View File

@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hongwei Wang <hwwang@google.com>
Date: Thu, 23 Feb 2023 13:23:37 -0800
Subject: [PATCH] Remove Activity if it enters PiP without window
This is to prevent malicious app entering PiP without being visible
first, like blocking onResume from completion. Which in turn
leaves the PiP window in limbo and non-interactable.
Bug: 265293293
Test: atest PinnedStackTests
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4fad1456409b79d6e649a29d5116a4fe3160bd21)
Merged-In: I458a9508662e72a1adb9d9818105f2e9d7096d44
Change-Id: I458a9508662e72a1adb9d9818105f2e9d7096d44
---
.../core/java/com/android/server/wm/ActivityRecord.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 55e8e19fd278..ffd27481a280 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -781,6 +781,12 @@ final class ActivityRecord extends ConfigurationContainer {
}
schedulePictureInPictureModeChanged(newConfig);
scheduleMultiWindowModeChanged(newConfig);
+ if (inPictureInPictureMode && findMainWindow() == null) {
+ // Prevent malicious app entering PiP without valid WindowState, which can in turn
+ // result a non-touchable PiP window since the InputConsumer for PiP requires it.
+ EventLog.writeEvent(0x534e4554, "265293293", -1, "");
+ removeImmediately();
+ }
}
}

View File

@ -1,106 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mark Renouf <mrenouf@google.com>
Date: Wed, 22 Feb 2023 15:14:08 +0000
Subject: [PATCH] Prevent sharesheet from previewing unowned URIs
Bug: 261036568
Test: manually via supplied tool (see bug)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3062b80fb28014a7482d5fa8b2a5c852134a5845)
Merged-In: I21accf6f753d2f676f1602d6e1ce829c5ef29e9a
Change-Id: I21accf6f753d2f676f1602d6e1ce829c5ef29e9a
---
.../android/internal/app/ChooserActivity.java | 36 +++++++++++++++++--
1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index f43ff17ed7d0..2e17dce90240 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -16,6 +16,8 @@
package com.android.internal.app;
+import static android.content.ContentProvider.getUserIdFromUri;
+
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.animation.Animator;
@@ -140,6 +142,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* The Chooser Activity handles intent resolution specifically for sharing intents -
@@ -1082,7 +1085,7 @@ public class ChooserActivity extends ResolverActivity {
ImageView previewThumbnailView = contentPreviewLayout.findViewById(
R.id.content_preview_thumbnail);
- if (previewThumbnail == null) {
+ if (!validForContentPreview(previewThumbnail)) {
previewThumbnailView.setVisibility(View.GONE);
} else {
mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false);
@@ -1109,6 +1112,10 @@ public class ChooserActivity extends ResolverActivity {
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+ if (!validForContentPreview(uri)) {
+ contentPreviewLayout.setVisibility(View.GONE);
+ return contentPreviewLayout;
+ }
mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, uri, 0);
} else {
ContentResolver resolver = getContentResolver();
@@ -1116,7 +1123,7 @@ public class ChooserActivity extends ResolverActivity {
List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
List<Uri> imageUris = new ArrayList<>();
for (Uri uri : uris) {
- if (isImageType(resolver.getType(uri))) {
+ if (validForContentPreview(uri) && isImageType(resolver.getType(uri))) {
imageUris.add(uri);
}
}
@@ -1222,9 +1229,16 @@ public class ChooserActivity extends ResolverActivity {
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
+ if (!validForContentPreview(uri)) {
+ contentPreviewLayout.setVisibility(View.GONE);
+ return contentPreviewLayout;
+ }
loadFileUriIntoView(uri, contentPreviewLayout);
} else {
List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
+ uris = uris.stream()
+ .filter(ChooserActivity::validForContentPreview)
+ .collect(Collectors.toList());
int uriCount = uris.size();
if (uriCount == 0) {
@@ -1278,6 +1292,24 @@ public class ChooserActivity extends ResolverActivity {
}
}
+ /**
+ * Indicate if the incoming content URI should be allowed.
+ *
+ * @param uri the uri to test
+ * @return true if the URI is allowed for content preview
+ */
+ private static boolean validForContentPreview(Uri uri) throws SecurityException {
+ if (uri == null) {
+ return false;
+ }
+ int userId = getUserIdFromUri(uri, UserHandle.USER_CURRENT);
+ if (userId != UserHandle.USER_CURRENT && userId != UserHandle.myUserId()) {
+ Log.e(TAG, "dropped invalid content URI belonging to user " + userId);
+ return false;
+ }
+ return true;
+ }
+
@VisibleForTesting
protected boolean isImageType(String mimeType) {
return mimeType != null && mimeType.startsWith("image/");

View File

@ -1,167 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Lee <brnlee@google.com>
Date: Fri, 17 Feb 2023 16:05:17 -0800
Subject: [PATCH] Check key intent for selectors and prohibited flags
Bug: 265015796
Test: atest
FrameworksServicesTests: com.android.server.accounts.AccountManagerServiceTest
(cherry picked from commit e53a96304352e2965176c8d32ac1b504e52ef185)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:92114886bdce8467c52c655c186f3e7ab1e134d8)
Merged-In: Ie16f8654337bd75eaad3156817470674b4f0cee3
Change-Id: Ie16f8654337bd75eaad3156817470674b4f0cee3
---
.../accounts/AccountManagerService.java | 18 +++++++---
.../accounts/AccountManagerServiceTest.java | 36 +++++++++++++++++++
.../AccountManagerServiceTestFixtures.java | 5 ++-
.../TestAccountType1Authenticator.java | 5 +--
4 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index b4edf94927b2..a9c7b0c6a3f1 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4808,10 +4808,6 @@ public class AccountManagerService
if (intent.getClipData() == null) {
intent.setClipData(ClipData.newPlainText(null, null));
}
- intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
- | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION));
long bid = Binder.clearCallingIdentity();
try {
PackageManager pm = mContext.getPackageManager();
@@ -4858,7 +4854,19 @@ public class AccountManagerService
if (intent == null) {
return (simulateIntent == null);
}
- return intent.filterEquals(simulateIntent);
+ if (!intent.filterEquals(simulateIntent)) {
+ return false;
+ }
+
+ if (intent.getSelector() != simulateIntent.getSelector()) {
+ return false;
+ }
+
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
+ return (simulateIntent.getFlags() & prohibitedFlags) == 0;
}
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 215f1e8e2a9e..d379e8131268 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -18,6 +18,7 @@ package com.android.server.accounts;
import static android.database.sqlite.SQLiteDatabase.deleteDatabase;
+import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -686,6 +687,41 @@ public class AccountManagerServiceTest extends AndroidTestCase {
assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
}
+ @SmallTest
+ public void testStartAddAccountSessionWhereAuthenticatorReturnsIntentWithProhibitedFlags()
+ throws Exception {
+ unlockSystemUser();
+ ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.activityInfo = new ActivityInfo();
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
+ when(mMockPackageManager.resolveActivityAsUser(
+ any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
+ when(mMockPackageManager.checkSignatures(
+ anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ Response response = new Response(latch, mMockAccountManagerResponse);
+ Bundle options = createOptionsWithAccountName(
+ AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
+ options.putInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, prohibitedFlags);
+
+ mAms.startAddAccountSession(
+ response, // response
+ AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
+ "authTokenType",
+ null, // requiredFeatures
+ true, // expectActivityLaunch
+ options); // optionsIn
+ waitForLatch(latch);
+
+ verify(mMockAccountManagerResponse).onError(
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), contains("invalid intent"));
+ }
+
@SmallTest
public void testStartAddAccountSessionError() throws Exception {
unlockSystemUser();
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
index 73f30d9f9e79..b98a6a891d55 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
@@ -17,9 +17,6 @@ package com.android.server.accounts;
import android.accounts.Account;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Constants shared between test AccountAuthenticators and AccountManagerServiceTest.
*/
@@ -31,6 +28,8 @@ public final class AccountManagerServiceTestFixtures {
"account_manager_service_test:account_status_token_key";
public static final String KEY_ACCOUNT_PASSWORD =
"account_manager_service_test:account_password_key";
+ public static final String KEY_INTENT_FLAGS =
+ "account_manager_service_test:intent_flags_key";
public static final String KEY_OPTIONS_BUNDLE =
"account_manager_service_test:option_bundle_key";
public static final String ACCOUNT_NAME_SUCCESS = "success_on_return@fixture.com";
diff --git a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
index 8106364477d9..924443e9d5cf 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
@@ -24,8 +24,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import com.android.frameworks.servicestests.R;
-
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -270,11 +268,13 @@ public class TestAccountType1Authenticator extends AbstractAccountAuthenticator
String accountName = null;
Bundle sessionBundle = null;
String password = null;
+ int intentFlags = 0;
if (options != null) {
accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME);
sessionBundle = options.getBundle(
AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE);
password = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD);
+ intentFlags = options.getInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, 0);
}
Bundle result = new Bundle();
@@ -302,6 +302,7 @@ public class TestAccountType1Authenticator extends AbstractAccountAuthenticator
intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT,
eventualActivityResultData);
intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response);
+ intent.setFlags(intentFlags);
result.putParcelable(AccountManager.KEY_INTENT, intent);
} else {

View File

@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kweku Adams <kwekua@google.com>
Date: Wed, 21 Sep 2022 22:13:01 +0000
Subject: [PATCH] Handle invalid data during job loading.
Catch exceptions that may be thrown if invalid data ended up in the
persisted job file.
Bug: 246541702
Bug: 246542132
Bug: 246542285
Bug: 246542330
Test: install test app with invalid job config, start app to schedule job, then reboot device
(cherry picked from commit c98fb42b480b3beedc2d94de6110f50212c4aa0b)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df1ba00dd9f64a3ae9a9e05979dfae6a15c7e203)
Merged-In: Id0ceba345942baf21177f687b8dd85ef001c0a9e
Change-Id: Id0ceba345942baf21177f687b8dd85ef001c0a9e
---
.../java/com/android/server/job/JobStore.java | 26 ++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 4ef37a2e484d..1f2772571e71 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -677,6 +677,10 @@ public final class JobStore {
}
} catch (XmlPullParserException | IOException e) {
Slog.wtf(TAG, "Error jobstore xml.", e);
+ } catch (Exception e) {
+ // Crashing at this point would result in a boot loop, so live with a general
+ // Exception for system stability's sake.
+ Slog.wtf(TAG, "Unexpected exception", e);
} finally {
if (mPersistInfo.countAllJobsLoaded < 0) { // Only set them once.
mPersistInfo.countAllJobsLoaded = numJobs;
@@ -807,6 +811,15 @@ public final class JobStore {
} catch (NumberFormatException e) {
Slog.d(TAG, "Error reading constraints, skipping.");
return null;
+ } catch (XmlPullParserException e) {
+ Slog.d(TAG, "Error Parser Exception.", e);
+ return null;
+ } catch (IOException e) {
+ Slog.d(TAG, "Error I/O Exception.", e);
+ return null;
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Constraints contained invalid data", e);
+ return null;
}
parser.next(); // Consume </constraints>
@@ -902,8 +915,14 @@ public final class JobStore {
return null;
}
- PersistableBundle extras = PersistableBundle.restoreFromXml(parser);
- jobBuilder.setExtras(extras);
+ final PersistableBundle extras;
+ try {
+ extras = PersistableBundle.restoreFromXml(parser);
+ jobBuilder.setExtras(extras);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Persisted extras contained invalid data", e);
+ return null;
+ }
parser.nextTag(); // Consume </extras>
final JobInfo builtJob;
@@ -950,7 +969,8 @@ public final class JobStore {
return new JobInfo.Builder(jobId, cname);
}
- private void buildConstraintsFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser) {
+ private void buildConstraintsFromXml(JobInfo.Builder jobBuilder, XmlPullParser parser)
+ throws XmlPullParserException, IOException {
String val;
final String netCapabilities = parser.getAttributeValue(null, "net-capabilities");

View File

@ -1,231 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Julia Reynolds <juliacr@google.com>
Date: Tue, 7 Mar 2023 15:44:49 -0500
Subject: [PATCH] Allow filtering of services
Test: ServiceListingTest
Bug: 260570119
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:44dcb8351e61f4b3a63ec68fa5d8490501e8a823)
Merged-In: Ib4740ba401667de62fa1a33334c2c1fbee25b760
Change-Id: Ib4740ba401667de62fa1a33334c2c1fbee25b760
---
.../applications/ServiceListing.java | 19 +++-
.../applications/ServiceListingTest.java | 98 ++++++++++++++++++-
2 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
index 454d1dce0b2f..6ed7b5065175 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
@@ -35,6 +35,7 @@ import android.util.Slog;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.function.Predicate;
/**
* Class for managing services matching a given intent and requesting a given permission.
@@ -50,11 +51,13 @@ public class ServiceListing {
private final HashSet<ComponentName> mEnabledServices = new HashSet<>();
private final List<ServiceInfo> mServices = new ArrayList<>();
private final List<Callback> mCallbacks = new ArrayList<>();
+ private final Predicate mValidator;
private boolean mListening;
private ServiceListing(Context context, String tag,
- String setting, String intentAction, String permission, String noun) {
+ String setting, String intentAction, String permission, String noun,
+ Predicate validator) {
mContentResolver = context.getContentResolver();
mContext = context;
mTag = tag;
@@ -62,6 +65,7 @@ public class ServiceListing {
mIntentAction = intentAction;
mPermission = permission;
mNoun = noun;
+ mValidator = validator;
}
public void addCallback(Callback callback) {
@@ -130,7 +134,6 @@ public class ServiceListing {
new Intent(mIntentAction),
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
user);
-
for (ResolveInfo resolveInfo : installedServices) {
ServiceInfo info = resolveInfo.serviceInfo;
@@ -141,6 +144,9 @@ public class ServiceListing {
+ mPermission);
continue;
}
+ if (mValidator != null && !mValidator.test(info)) {
+ continue;
+ }
mServices.add(info);
}
for (Callback callback : mCallbacks) {
@@ -186,6 +192,7 @@ public class ServiceListing {
private String mIntentAction;
private String mPermission;
private String mNoun;
+ private Predicate mValidator;
public Builder(Context context) {
mContext = context;
@@ -216,8 +223,14 @@ public class ServiceListing {
return this;
}
+ public Builder setValidator(Predicate<ServiceInfo> validator) {
+ mValidator = validator;
+ return this;
+ }
+
public ServiceListing build() {
- return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun);
+ return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun,
+ mValidator);
}
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
index f7fd25b9fb7d..7ff0988c494d 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
@@ -18,20 +18,35 @@ package com.android.settingslib.applications;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.provider.Settings;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.google.common.collect.ImmutableList;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.List;
+
@RunWith(RobolectricTestRunner.class)
public class ServiceListingTest {
@@ -39,16 +54,97 @@ public class ServiceListingTest {
private static final String TEST_INTENT = "com.example.intent";
private ServiceListing mServiceListing;
+ private Context mContext;
+ private PackageManager mPm;
@Before
public void setUp() {
- mServiceListing = new ServiceListing.Builder(RuntimeEnvironment.application)
+ mPm = mock(PackageManager.class);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getPackageManager()).thenReturn(mPm);
+
+ mServiceListing = new ServiceListing.Builder(mContext)
+ .setTag("testTag")
+ .setSetting(TEST_SETTING)
+ .setNoun("testNoun")
+ .setIntentAction(TEST_INTENT)
+ .setPermission("testPermission")
+ .build();
+ }
+
+ @Test
+ public void testValidator() {
+ ServiceInfo s1 = new ServiceInfo();
+ s1.permission = "testPermission";
+ s1.packageName = "pkg";
+ ServiceInfo s2 = new ServiceInfo();
+ s2.permission = "testPermission";
+ s2.packageName = "pkg2";
+ ResolveInfo r1 = new ResolveInfo();
+ r1.serviceInfo = s1;
+ ResolveInfo r2 = new ResolveInfo();
+ r2.serviceInfo = s2;
+
+ when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
+ ImmutableList.of(r1, r2));
+
+ mServiceListing = new ServiceListing.Builder(mContext)
+ .setTag("testTag")
+ .setSetting(TEST_SETTING)
+ .setNoun("testNoun")
+ .setIntentAction(TEST_INTENT)
+ .setValidator(info -> {
+ if (info.packageName.equals("pkg")) {
+ return true;
+ }
+ return false;
+ })
+ .setPermission("testPermission")
+ .build();
+ ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
+ mServiceListing.addCallback(callback);
+ mServiceListing.reload();
+
+ verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
+ ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onServicesReloaded(captor.capture());
+
+ assertThat(captor.getValue().size()).isEqualTo(1);
+ assertThat(captor.getValue().get(0)).isEqualTo(s1);
+ }
+
+ @Test
+ public void testNoValidator() {
+ ServiceInfo s1 = new ServiceInfo();
+ s1.permission = "testPermission";
+ s1.packageName = "pkg";
+ ServiceInfo s2 = new ServiceInfo();
+ s2.permission = "testPermission";
+ s2.packageName = "pkg2";
+ ResolveInfo r1 = new ResolveInfo();
+ r1.serviceInfo = s1;
+ ResolveInfo r2 = new ResolveInfo();
+ r2.serviceInfo = s2;
+
+ when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
+ ImmutableList.of(r1, r2));
+
+ mServiceListing = new ServiceListing.Builder(mContext)
.setTag("testTag")
.setSetting(TEST_SETTING)
.setNoun("testNoun")
.setIntentAction(TEST_INTENT)
.setPermission("testPermission")
.build();
+ ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
+ mServiceListing.addCallback(callback);
+ mServiceListing.reload();
+
+ verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
+ ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
+ verify(callback, times(1)).onServicesReloaded(captor.capture());
+
+ assertThat(captor.getValue().size()).isEqualTo(2);
}
@Test

View File

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jeff DeCew <jeffdq@google.com>
Date: Fri, 24 Mar 2023 16:15:24 +0000
Subject: [PATCH] Add BubbleMetadata detection to block FSI
Bug: 274759612
Test: atest NotificationInterruptStateProviderImplTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c60e264a551df9f880fd73683321b7e821429da7)
Merged-In: I40e1aa6377b8a60d91cb2f4189df1e9a4a4578a2
Change-Id: I40e1aa6377b8a60d91cb2f4189df1e9a4a4578a2
---
.../NotificationInterruptionStateProvider.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
index ff71db4dc3b5..336c65b3c7d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
@@ -461,6 +461,20 @@ public class NotificationInterruptionStateProvider {
return false;
}
+ // If the notification has suppressive BubbleMetadata, block FSI and warn.
+ Notification.BubbleMetadata bubbleMetadata = sbn.getNotification().getBubbleMetadata();
+ if (bubbleMetadata != null && bubbleMetadata.isNotificationSuppressed()) {
+ // b/274759612: Detect and report an event when a notification has both an FSI and a
+ // suppressive BubbleMetadata, and now correctly block the FSI from firing.
+ final int uid = entry.getSbn().getUid();
+ android.util.EventLog.writeEvent(0x534e4554, "274759612", uid, "bubbleMetadata");
+ if (DEBUG) {
+ Log.w(TAG, "No FullScreenIntent: WARNING: BubbleMetadata may prevent HUN: "
+ + entry.getKey());
+ }
+ return false;
+ }
+
// If the screen is off, then launch the FullScreenIntent
if (!mPowerManager.isInteractive()) {
if (DEBUG) {

View File

@ -1,85 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Valentin Iftime <valiiftime@google.com>
Date: Wed, 22 Feb 2023 09:38:55 +0100
Subject: [PATCH] Prevent RemoteViews crashing SystemUi
Catch canvas drawing exceptions caused by unsuported image sizes.
Test: 1. Post a custom view notification with a layout
containing an ImageView that references a 5k x 5k image
2. Add an App Widget to the home screen with that has the
layout mentioned above as preview/initial layout.
Bug: 268193777
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:cfc0b34432ab54e3fa472db5c43e620293f64a5d)
Merged-In: Ib3bda769c499b4069b49c566b1b227f98f707a8a
Change-Id: Ib3bda769c499b4069b49c566b1b227f98f707a8a
---
.../android/appwidget/AppWidgetHostView.java | 39 ++++++++++++++-----
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 85f0e2342412..eafb631216e5 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -28,6 +28,7 @@ import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
@@ -250,19 +251,26 @@ public class AppWidgetHostView extends FrameLayout {
super.onLayout(changed, left, top, right, bottom);
} catch (final RuntimeException e) {
Log.e(TAG, "Remote provider threw runtime exception, using error view instead.", e);
- removeViewInLayout(mView);
- View child = getErrorView();
- prepareView(child);
- addViewInLayout(child, 0, child.getLayoutParams());
- measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
- child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
- child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
- mView = child;
- mViewMode = VIEW_MODE_ERROR;
+ handleViewError();
}
}
+ /**
+ * Remove bad view and replace with error message view
+ */
+ private void handleViewError() {
+ removeViewInLayout(mView);
+ View child = getErrorView();
+ prepareView(child);
+ addViewInLayout(child, 0, child.getLayoutParams());
+ measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
+ child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
+ child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
+ mView = child;
+ mViewMode = VIEW_MODE_ERROR;
+ }
+
/**
* Provide guidance about the size of this widget to the AppWidgetManager. The widths and
* heights should correspond to the full area the AppWidgetHostView is given. Padding added by
@@ -711,4 +719,15 @@ public class AppWidgetHostView extends FrameLayout {
}
return null;
}
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ try {
+ super.dispatchDraw(canvas);
+ } catch (Exception e) {
+ // Catch draw exceptions that may be caused by RemoteViews
+ Log.e(TAG, "Drawing view failed: " + e);
+ post(this::handleViewError);
+ }
+ }
}

View File

@ -1,138 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sally Qi <sallyqi@google.com>
Date: Wed, 5 Oct 2022 11:42:30 -0700
Subject: [PATCH] Mitigate the security vulnerability by sanitizing the
transaction flags.
- This is part of fix of commit
Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df for backporting.
- Part of commit Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df which
sanitizes the transaction flags from DisplayState instead.
- In rvc, we only have ACCESS_SURFACE_FLINGER permission check passed as
`privileged` argument in SF::applyTransactionState. We can directly
utilize it for sanitization in DiaplyState.
- In rvc code base, SF::setTransactionState pass a const array of
displayState objects and then call SF::applyTransactionState. To
successfully sanitize the flags for each displayState object, we
convert this const array into non-const one before calling
SF::applyTransactionState.
Bug: 248031255
Test: test using displaytoken app manually on the phone, test shell
screenrecord during using displaytoken; atest
android.hardware.camera2.cts.FastBasicsTest
Change-Id: Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df
Merged-In: Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df
(cherry picked from commit 03d4458ea0cb00c28f695d99aae5e4c6b15fc237)
Merged-In: Id9d9012d4ede9c8330f0ce1096bcb78e51b7c5df
---
libs/gui/LayerState.cpp | 21 +++++++++++++++++++++
libs/gui/include/gui/LayerState.h | 1 +
services/surfaceflinger/SurfaceFlinger.cpp | 14 ++++++++++----
services/surfaceflinger/SurfaceFlinger.h | 5 ++---
4 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 6066421faf..293f042de2 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -237,6 +237,27 @@ void DisplayState::merge(const DisplayState& other) {
}
}
+void DisplayState::sanitize(bool privileged) {
+ if (what & DisplayState::eLayerStackChanged) {
+ if (!privileged) {
+ what &= ~DisplayState::eLayerStackChanged;
+ ALOGE("Stripped attempt to set eLayerStackChanged in sanitize");
+ }
+ }
+ if (what & DisplayState::eDisplayProjectionChanged) {
+ if (!privileged) {
+ what &= ~DisplayState::eDisplayProjectionChanged;
+ ALOGE("Stripped attempt to set eDisplayProjectionChanged in sanitize");
+ }
+ }
+ if (what & DisplayState::eSurfaceChanged) {
+ if (!privileged) {
+ what &= ~DisplayState::eSurfaceChanged;
+ ALOGE("Stripped attempt to set eSurfaceChanged in sanitize");
+ }
+ }
+}
+
void layer_state_t::merge(const layer_state_t& other) {
if (other.what & ePositionChanged) {
what |= ePositionChanged;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index f438eb3d01..8a07602e41 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -231,6 +231,7 @@ struct DisplayState {
DisplayState();
void merge(const DisplayState& other);
+ void sanitize(bool privileged);
uint32_t what;
sp<IBinder> token;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index db26808cc2..21e9e8eb96 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3675,7 +3675,7 @@ bool SurfaceFlinger::flushTransactionQueues() {
auto& [applyToken, transactionQueue] = *it;
while (!transactionQueue.empty()) {
- const auto& transaction = transactionQueue.front();
+ auto& transaction = transactionQueue.front();
if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime,
transaction.states)) {
setTransactionFlags(eTransactionFlushNeeded);
@@ -3794,12 +3794,17 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states,
return;
}
- applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime,
+ Vector<DisplayState> displaysList;
+ for (auto& d : displays) {
+ displaysList.add(d);
+ }
+
+ applyTransactionState(states, displaysList, flags, inputWindowCommands, desiredPresentTime,
uncacheBuffer, listenerCallbacks, postTime, privileged);
}
void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
- const Vector<DisplayState>& displays, uint32_t flags,
+ Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime,
const client_cache_t& uncacheBuffer,
@@ -3824,7 +3829,8 @@ void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
}
}
- for (const DisplayState& display : displays) {
+ for (DisplayState& display : displays) {
+ display.sanitize(privileged);
transactionFlags |= setDisplayStateLocked(display);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e58caa63b3..c4578d0dbb 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -568,9 +568,8 @@ private:
/* ------------------------------------------------------------------------
* Transactions
*/
- void applyTransactionState(const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays, uint32_t flags,
- const InputWindowCommands& inputWindowCommands,
+ void applyTransactionState(const Vector<ComposerState>& state, Vector<DisplayState>& displays,
+ uint32_t flags, const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime,
const client_cache_t& uncacheBuffer,
const std::vector<ListenerCallbacks>& listenerCallbacks,

View File

@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Devin Moore <devinmoore@google.com>
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 abc910302c..9d8c6c34e3 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -591,7 +591,13 @@ bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& output
return false;
}
outputString8.setTo(static_cast<char const*>(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;
}

View File

@ -1,67 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Devin Moore <devinmoore@google.com>
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 96d5eb9d1f..e09672c9a4 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<Sensor const**>(malloc(count * sizeof(Sensor*)));
LOG_ALWAYS_FATAL_IF(mSensorList == nullptr, "mSensorList NULL");

View File

@ -1,71 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Anthony Stange <stange@google.com>
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 e09672c9a4..180a0ebd85 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(nullptr), 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 f09c9c67b4..127f74f4b2 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 938060063f..0a4e68412d 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.

View File

@ -1,250 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tad <tad@spotco.us>
Date: Tue, 21 Mar 2023 13:01:30 -0400
Subject: [PATCH] Revert "[DO NOT MERGE] wifi: remove certificates for network
factory reset"
This reverts commit 5aa2d76b9d820ebe175a5f4c416a873352000c71.
Change-Id: I3ae8d2ae65006560bd2b5b44a6075ba207707e1b
---
.../server/wifi/WifiConfigManager.java | 2 +-
.../com/android/server/wifi/WifiKeyStore.java | 7 ++---
.../wifi/WifiNetworkSuggestionsManager.java | 2 +-
.../android/server/wifi/WifiServiceImpl.java | 6 ----
.../server/wifi/WifiConfigManagerTest.java | 6 ++--
.../android/server/wifi/WifiKeyStoreTest.java | 28 +++----------------
.../WifiNetworkSuggestionsManagerTest.java | 2 +-
.../server/wifi/WifiServiceImplTest.java | 16 ++++-------
8 files changed, 18 insertions(+), 51 deletions(-)
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index fce5758e1..393a5c395 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -1359,7 +1359,7 @@ public class WifiConfigManager {
// will remove the enterprise keys when provider is uninstalled. Suggestion enterprise
// networks will remove the enterprise keys when suggestion is removed.
if (!config.isPasspoint() && !config.fromWifiNetworkSuggestion && config.isEnterprise()) {
- mWifiKeyStore.removeKeys(config.enterpriseConfig, false);
+ mWifiKeyStore.removeKeys(config.enterpriseConfig);
}
removeConnectChoiceFromAllNetworks(config.configKey());
diff --git a/service/java/com/android/server/wifi/WifiKeyStore.java b/service/java/com/android/server/wifi/WifiKeyStore.java
index 8e82f4720..c1706a20d 100644
--- a/service/java/com/android/server/wifi/WifiKeyStore.java
+++ b/service/java/com/android/server/wifi/WifiKeyStore.java
@@ -221,11 +221,10 @@ public class WifiKeyStore {
* Remove enterprise keys from the network config.
*
* @param config Config corresponding to the network.
- * @param forceRemove remove keys regardless of the key installer.
*/
- public void removeKeys(WifiEnterpriseConfig config, boolean forceRemove) {
+ public void removeKeys(WifiEnterpriseConfig config) {
// Do not remove keys that were manually installed by the user
- if (forceRemove || config.isAppInstalledDeviceKeyAndCert()) {
+ if (config.isAppInstalledDeviceKeyAndCert()) {
String client = config.getClientCertificateAlias();
// a valid client certificate is configured
if (!TextUtils.isEmpty(client)) {
@@ -238,7 +237,7 @@ public class WifiKeyStore {
}
// Do not remove CA certs that were manually installed by the user
- if (forceRemove || config.isAppInstalledCaCert()) {
+ if (config.isAppInstalledCaCert()) {
String[] aliases = config.getCaCertificateAliases();
// a valid ca certificate is configured
if (aliases != null) {
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index ae7892cd2..031aec603 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -668,7 +668,7 @@ public class WifiNetworkSuggestionsManager {
if (!config.isEnterprise()) {
continue;
}
- mWifiKeyStore.removeKeys(config.enterpriseConfig, false);
+ mWifiKeyStore.removeKeys(config.enterpriseConfig);
}
// Clear the scan cache.
removeFromScanResultMatchInfoMap(removingSuggestions);
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 0d6732dd7..d375ba4c8 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -3002,13 +3002,7 @@ public class WifiServiceImpl extends BaseWifiService {
List<WifiConfiguration> networks = mClientModeImpl.syncGetConfiguredNetworks(
Binder.getCallingUid(), mClientModeImplChannel, Process.WIFI_UID);
if (networks != null) {
- EventLog.writeEvent(0x534e4554, "231985227", -1,
- "Remove certs for factory reset");
for (WifiConfiguration config : networks) {
- if (config.isEnterprise()) {
- mWifiInjector.getWifiKeyStore().removeKeys(
- config.enterpriseConfig, true);
- }
removeNetwork(config.networkId, packageName);
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 71d06fb7e..f5ad049dd 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -703,7 +703,7 @@ public class WifiConfigManagerTest {
verify(mWcmListener, never()).onSavedNetworkAdded(suggestionNetwork.networkId);
assertTrue(mWifiConfigManager
.removeNetwork(suggestionNetwork.networkId, TEST_CREATOR_UID));
- verify(mWifiKeyStore, never()).removeKeys(any(), eq(false));
+ verify(mWifiKeyStore, never()).removeKeys(any());
}
/**
@@ -947,7 +947,7 @@ public class WifiConfigManagerTest {
assertTrue(mWifiConfigManager.removeNetwork(passpointNetwork.networkId, Process.WIFI_UID));
// Verify keys are not being removed.
- verify(mWifiKeyStore, never()).removeKeys(any(WifiEnterpriseConfig.class), eq(false));
+ verify(mWifiKeyStore, never()).removeKeys(any(WifiEnterpriseConfig.class));
verifyNetworkRemoveBroadcast(passpointNetwork);
// Ensure that the write was not invoked for Passpoint network remove.
mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).write(anyBoolean());
@@ -5169,7 +5169,7 @@ public class WifiConfigManagerTest {
assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
// Verify keys are not being removed.
- verify(mWifiKeyStore, never()).removeKeys(any(WifiEnterpriseConfig.class), eq(false));
+ verify(mWifiKeyStore, never()).removeKeys(any(WifiEnterpriseConfig.class));
verifyNetworkRemoveBroadcast(configuration);
// Ensure that the write was not invoked for Passpoint network remove.
mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).write(anyBoolean());
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java
index 3f54c3f85..7649d1ba4 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java
@@ -96,7 +96,7 @@ public class WifiKeyStoreTest {
public void testRemoveKeysForAppInstalledCerts() {
when(mWifiEnterpriseConfig.isAppInstalledDeviceKeyAndCert()).thenReturn(true);
when(mWifiEnterpriseConfig.isAppInstalledCaCert()).thenReturn(true);
- mWifiKeyStore.removeKeys(mWifiEnterpriseConfig, false);
+ mWifiKeyStore.removeKeys(mWifiEnterpriseConfig);
// Method calls the KeyStore#delete method 4 times, user key, user cert, and 2 CA cert
verify(mKeyStore).delete(Credentials.USER_PRIVATE_KEY + USER_CERT_ALIAS, Process.WIFI_UID);
@@ -115,7 +115,7 @@ public class WifiKeyStoreTest {
public void testRemoveKeysForMixedInstalledCerts1() {
when(mWifiEnterpriseConfig.isAppInstalledDeviceKeyAndCert()).thenReturn(true);
when(mWifiEnterpriseConfig.isAppInstalledCaCert()).thenReturn(false);
- mWifiKeyStore.removeKeys(mWifiEnterpriseConfig, false);
+ mWifiKeyStore.removeKeys(mWifiEnterpriseConfig);
// Method calls the KeyStore#delete method 2 times: user key and user cert
verify(mKeyStore).delete(Credentials.USER_PRIVATE_KEY + USER_CERT_ALIAS, Process.WIFI_UID);
@@ -131,7 +131,7 @@ public class WifiKeyStoreTest {
public void testRemoveKeysForMixedInstalledCerts2() {
when(mWifiEnterpriseConfig.isAppInstalledDeviceKeyAndCert()).thenReturn(false);
when(mWifiEnterpriseConfig.isAppInstalledCaCert()).thenReturn(true);
- mWifiKeyStore.removeKeys(mWifiEnterpriseConfig, false);
+ mWifiKeyStore.removeKeys(mWifiEnterpriseConfig);
// Method calls the KeyStore#delete method 2 times: 2 CA certs
verify(mKeyStore).delete(Credentials.CA_CERTIFICATE + USER_CA_CERT_ALIAS[0],
@@ -148,27 +148,7 @@ public class WifiKeyStoreTest {
public void testRemoveKeysForUserInstalledCerts() {
when(mWifiEnterpriseConfig.isAppInstalledDeviceKeyAndCert()).thenReturn(false);
when(mWifiEnterpriseConfig.isAppInstalledCaCert()).thenReturn(false);
- mWifiKeyStore.removeKeys(mWifiEnterpriseConfig, false);
- verifyNoMoreInteractions(mKeyStore);
- }
-
- /**
- * Verifies that keys and certs are removed when they were not installed by the user
- * when forceRemove is true.
- */
- @Test
- public void testForceRemoveKeysForUserInstalledCerts() throws Exception {
- when(mWifiEnterpriseConfig.isAppInstalledDeviceKeyAndCert()).thenReturn(false);
- when(mWifiEnterpriseConfig.isAppInstalledCaCert()).thenReturn(false);
- mWifiKeyStore.removeKeys(mWifiEnterpriseConfig, true);
-
- // KeyStore#delete() is called three time for user cert, user key, and 2 CA cert.
- verify(mKeyStore).delete(Credentials.USER_PRIVATE_KEY + USER_CERT_ALIAS, Process.WIFI_UID);
- verify(mKeyStore).delete(Credentials.USER_CERTIFICATE + USER_CERT_ALIAS, Process.WIFI_UID);
- verify(mKeyStore).delete(Credentials.CA_CERTIFICATE + USER_CA_CERT_ALIAS[0],
- Process.WIFI_UID);
- verify(mKeyStore).delete(Credentials.CA_CERTIFICATE + USER_CA_CERT_ALIAS[1],
- Process.WIFI_UID);
+ mWifiKeyStore.removeKeys(mWifiEnterpriseConfig);
verifyNoMoreInteractions(mKeyStore);
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
index 60dcf153c..ed5bb39ab 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java
@@ -344,7 +344,7 @@ public class WifiNetworkSuggestionsManagerTest {
assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS,
mWifiNetworkSuggestionsManager.remove(new ArrayList<>(),
TEST_UID_1, TEST_PACKAGE_1));
- verify(mWifiKeyStore).removeKeys(any(), eq(false));
+ verify(mWifiKeyStore).removeKeys(any());
}
/**
* Verify successful replace (add,remove, add) of network suggestions.
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 53d6d7815..fab326858 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -260,7 +260,6 @@ public class WifiServiceImplTest {
@Mock WifiScoreCard mWifiScoreCard;
@Mock PasspointManager mPasspointManager;
@Mock IDppCallback mDppCallback;
- @Mock WifiKeyStore mWifiKeyStore;
@Spy FakeWifiLog mLog;
@@ -402,7 +401,6 @@ public class WifiServiceImplTest {
when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_MANAGED_PROVISIONING),
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true);
- when(mWifiInjector.getWifiKeyStore()).thenReturn(mWifiKeyStore);
ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
ArgumentCaptor.forClass(SoftApCallback.class);
@@ -3643,11 +3641,7 @@ public class WifiServiceImplTest {
anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true);
final String fqdn = "example.com";
- WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
- openNetwork.networkId = TEST_NETWORK_ID;
- WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork(
- WifiEnterpriseConfig.Eap.TLS, WifiEnterpriseConfig.Phase2.NONE);
- eapNetwork.networkId = TEST_NETWORK_ID + 1;
+ WifiConfiguration network = WifiConfigurationTestUtil.createOpenNetwork();
PasspointConfiguration config = new PasspointConfiguration();
HomeSp homeSp = new HomeSp();
homeSp.setFqdn(fqdn);
@@ -3655,17 +3649,17 @@ public class WifiServiceImplTest {
mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel;
when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt()))
- .thenReturn(Arrays.asList(openNetwork, eapNetwork));
+ .thenReturn(Arrays.asList(network));
when(mClientModeImpl.syncGetPasspointConfigs(any(), anyBoolean()))
.thenReturn(Arrays.asList(config));
+ when(mClientModeImpl.syncGetPasspointConfigs(any())).thenReturn(Arrays.asList(config));
+
mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME);
mLooper.dispatchAll();
verify(mWifiApConfigStore).setApConfiguration(null);
- verify(mClientModeImpl).syncRemoveNetwork(mAsyncChannel, openNetwork.networkId);
- verify(mClientModeImpl).syncRemoveNetwork(mAsyncChannel, eapNetwork.networkId);
- verify(mWifiKeyStore).removeKeys(eapNetwork.enterpriseConfig, true);
+ verify(mClientModeImpl).syncRemoveNetwork(mAsyncChannel, network.networkId);
verify(mClientModeImpl).syncRemovePasspointConfig(mAsyncChannel, true, fqdn);
verify(mWifiConfigManager).clearDeletedEphemeralNetworks();
verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints();

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Dementyev <dementyev@google.com>
Date: Tue, 7 Mar 2023 10:59:38 -0800
Subject: [PATCH] Convert argument to Intent in car settings
AddAccountActivity.
Bug: 265798353
Test: manual
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3195c559667939b458445b7e133fb4a7c76aaead)
Merged-In: I4b035fd370197b7f4838af5fb6e4d0ce27a5f3e7
Change-Id: I4b035fd370197b7f4838af5fb6e4d0ce27a5f3e7
---
src/com/android/car/settings/accounts/AddAccountActivity.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/com/android/car/settings/accounts/AddAccountActivity.java b/src/com/android/car/settings/accounts/AddAccountActivity.java
index d5ce57142..69ada037f 100644
--- a/src/com/android/car/settings/accounts/AddAccountActivity.java
+++ b/src/com/android/car/settings/accounts/AddAccountActivity.java
@@ -94,7 +94,7 @@ public class AddAccountActivity extends Activity {
intent.putExtras(addAccountOptions);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResultAsUser(
- intent, ADD_ACCOUNT_REQUEST, mUserHandle);
+ new Intent(intent), ADD_ACCOUNT_REQUEST, mUserHandle);
LOG.v("account added: " + result);
} catch (OperationCanceledException | IOException | AuthenticatorException e) {
LOG.v("addAccount error: " + e);

View File

@ -1,120 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Johnston <acjohnston@google.com>
Date: Wed, 14 Sep 2022 08:02:27 +0000
Subject: [PATCH] DO NOT MERGE Stop managed profile owner granting READ_SMS
Reason: There is only one telephony stack shared
between the personal and work profile.
This change is a partial cherry-pick of ag/15371816.
DPM.canAdminGrantSensorsPermissions did not exist pre-S. Pre-S,
the admin was always able to grant permissions incl sensor permissions. The change here will continue to allow granting of permissions unless the admin is on a managed profile and the permission is READ_SMS.
Bug: 194382185
Bug: 189942529
Test: manual testing with TestDPC
Change-Id: Icc1e59a18c4786635cbc651aefc2561fbbddfdb1
(cherry picked from commit 7cd8e7f00cf2d921a2d9b2999cfc85a148c781b9)
Merged-In: Icc1e59a18c4786635cbc651aefc2561fbbddfdb1
---
.../PermissionControllerServiceImpl.java | 14 +++++-
.../AdminRestrictedPermissionsUtils.java | 44 +++++++++++++++++++
2 files changed, 56 insertions(+), 2 deletions(-)
create mode 100644 src/com/android/packageinstaller/permission/utils/AdminRestrictedPermissionsUtils.java
diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java
index 57f399275..2121d6e5d 100644
--- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java
+++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java
@@ -35,6 +35,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.UserHandle;
+import android.os.UserManager;
import android.permission.PermissionControllerService;
import android.permission.PermissionManager;
import android.permission.RuntimePermissionPresentationInfo;
@@ -52,6 +53,7 @@ import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsa
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.model.Permission;
import com.android.packageinstaller.permission.model.PermissionUsages;
+import com.android.packageinstaller.permission.utils.AdminRestrictedPermissionsUtils;
import com.android.packageinstaller.permission.utils.Utils;
import org.xmlpull.v1.XmlPullParser;
@@ -576,6 +578,8 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS
AppPermissions app = new AppPermissions(this, pkgInfo, false, true, null);
+ final boolean isManagedProfile = getSystemService(UserManager.class).isManagedProfile();
+
int numPerms = expandedPermissions.size();
for (int i = 0; i < numPerms; i++) {
String permName = expandedPermissions.get(i);
@@ -591,8 +595,14 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS
switch (grantState) {
case PERMISSION_GRANT_STATE_GRANTED:
- perm.setPolicyFixed(true);
- group.grantRuntimePermissions(false, new String[]{permName});
+ if (AdminRestrictedPermissionsUtils.mayAdminGrantPermission(perm.getName(),
+ isManagedProfile)) {
+ perm.setPolicyFixed(true);
+ group.grantRuntimePermissions(false, new String[]{permName});
+ } else {
+ // similar to PERMISSION_GRANT_STATE_DEFAULT
+ perm.setPolicyFixed(false);
+ }
break;
case PERMISSION_GRANT_STATE_DENIED:
perm.setPolicyFixed(true);
diff --git a/src/com/android/packageinstaller/permission/utils/AdminRestrictedPermissionsUtils.java b/src/com/android/packageinstaller/permission/utils/AdminRestrictedPermissionsUtils.java
new file mode 100644
index 000000000..5bbb37837
--- /dev/null
+++ b/src/com/android/packageinstaller/permission/utils/AdminRestrictedPermissionsUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller.permission.utils;
+
+import android.Manifest;
+import android.util.ArraySet;
+
+/**
+ * A class for dealing with permissions that the admin may not grant in certain configurations.
+ */
+public final class AdminRestrictedPermissionsUtils {
+
+ /**
+ * A set of permissions that the managed Profile Owner cannot grant.
+ */
+ private static final ArraySet<String> MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS =
+ new ArraySet<>();
+
+ static {
+ MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS.add(Manifest.permission.READ_SMS);
+ }
+
+ /**
+ * Returns true if the admin may grant this permission, false otherwise.
+ */
+ public static boolean mayAdminGrantPermission(String permission, boolean isManagedProfile) {
+ return !isManagedProfile
+ || !MANAGED_PROFILE_OWNER_RESTRICTED_PERMISSIONS.contains(permission);
+ }
+}

View File

@ -1,378 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tsung-Mao Fang <tmfang@google.com>
Date: Mon, 3 Jan 2022 18:25:04 +0800
Subject: [PATCH] FRP bypass defense in the settings app
Over the last few years, there have been a number of
Factory Reset Protection bypass bugs in the SUW flow.
It's unlikely to defense all points from individual apps.
Therefore, we decide to block some critical pages when
user doesn't complete the SUW flow.
Test: Can't open the certain pages in the suw flow.
Bug: 258422561
Fix: 200746457
Bug: 202975040
Fix: 213091525
Fix: 213090835
Fix: 201561699
Fix: 213090827
Fix: 213090875
Change-Id: Ia18f367109df5af7da0a5acad7702898a459d32e
Merged-In: Ia18f367109df5af7da0a5acad7702898a459d32e
(cherry picked from commit ff5bfb40c8b09ab477efaae6a0199911a0d703dd)
Merged-In: Ia18f367109df5af7da0a5acad7702898a459d32e
---
.../settings/SettingsPreferenceFragment.java | 23 +++++-
.../accounts/AccountDashboardFragment.java | 5 ++
.../appinfo/AppInfoDashboardFragment.java | 5 ++
.../DevelopmentSettingsDashboardFragment.java | 5 ++
.../system/ResetDashboardFragment.java | 5 ++
.../SettingsPreferenceFragmentTest.java | 74 +++++++++++++++++++
.../AccountDashboardFragmentTest.java | 5 ++
.../appinfo/AppInfoDashboardFragmentTest.java | 5 ++
...elopmentSettingsDashboardFragmentTest.java | 5 ++
.../system/ResetDashboardFragmentTest.java | 40 ++++++++++
10 files changed, 171 insertions(+), 1 deletion(-)
create mode 100644 tests/robotests/src/com/android/settings/system/ResetDashboardFragmentTest.java
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 6b29b2e1e4..0c537534df 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -56,6 +56,8 @@ import com.android.settingslib.core.instrumentation.Instrumentable;
import com.android.settingslib.widget.FooterPreferenceMixinCompat;
import com.android.settingslib.widget.LayoutPreference;
+import com.google.android.setupcompat.util.WizardManagerHelper;
+
import java.util.UUID;
/**
@@ -64,7 +66,7 @@ import java.util.UUID;
public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceFragment
implements DialogCreatable, HelpResourceProvider, Indexable {
- private static final String TAG = "SettingsPreference";
+ private static final String TAG = "SettingsPreferenceFragment";
private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
@@ -128,6 +130,15 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
@VisibleForTesting
public boolean mPreferenceHighlighted = false;
+ @Override
+ public void onAttach(Context context) {
+ if (shouldSkipForInitialSUW() && !WizardManagerHelper.isDeviceProvisioned(getContext())) {
+ Log.w(TAG, "Skip " + getClass().getSimpleName() + " before SUW completed.");
+ finish();
+ }
+ super.onAttach(context);
+ }
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -264,6 +275,16 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
return 0;
}
+ /**
+ * Whether UI should be skipped in the initial SUW flow.
+ *
+ * @return {@code true} when UI should be skipped in the initial SUW flow.
+ * {@code false} when UI should not be skipped in the initial SUW flow.
+ */
+ protected boolean shouldSkipForInitialSUW() {
+ return false;
+ }
+
protected void onDataSetChanged() {
highlightPreferenceIfNeeded();
updateEmptyView();
diff --git a/src/com/android/settings/accounts/AccountDashboardFragment.java b/src/com/android/settings/accounts/AccountDashboardFragment.java
index 515008af59..627a3177d2 100644
--- a/src/com/android/settings/accounts/AccountDashboardFragment.java
+++ b/src/com/android/settings/accounts/AccountDashboardFragment.java
@@ -67,6 +67,11 @@ public class AccountDashboardFragment extends DashboardFragment {
return buildPreferenceControllers(context, this /* parent */, authorities);
}
+ @Override
+ protected boolean shouldSkipForInitialSUW() {
+ return true;
+ }
+
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
SettingsPreferenceFragment parent, String[] authorities) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 9917d352e8..b757380c5d 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -473,6 +473,11 @@ public class AppInfoDashboardFragment extends DashboardFragment
return true;
}
+ @Override
+ protected boolean shouldSkipForInitialSUW() {
+ return true;
+ }
+
private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
stopListeningToPackageRemove();
// Create new intent to launch Uninstaller activity
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index f18225e8fb..ca46b24a31 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -181,6 +181,11 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
}
}
+ @Override
+ protected boolean shouldSkipForInitialSUW() {
+ return true;
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
diff --git a/src/com/android/settings/system/ResetDashboardFragment.java b/src/com/android/settings/system/ResetDashboardFragment.java
index 5243d6a393..aa06691d67 100644
--- a/src/com/android/settings/system/ResetDashboardFragment.java
+++ b/src/com/android/settings/system/ResetDashboardFragment.java
@@ -58,6 +58,11 @@ public class ResetDashboardFragment extends DashboardFragment {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
+ @Override
+ protected boolean shouldSkipForInitialSUW() {
+ return true;
+ }
+
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
diff --git a/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
index cce01550a7..71c531a4c9 100644
--- a/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsPreferenceFragmentTest.java
@@ -23,11 +23,13 @@ import static org.mockito.Mockito.doReturn;
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;
import android.content.Context;
import android.os.Bundle;
+import android.provider.Settings;
import android.view.View;
import androidx.fragment.app.FragmentActivity;
@@ -39,6 +41,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.widget.WorkOnlyCategory;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -61,7 +64,9 @@ public class SettingsPreferenceFragmentTest {
private PreferenceScreen mPreferenceScreen;
private Context mContext;
private TestFragment mFragment;
+ private TestFragment2 mFragment2;
private View mEmptyView;
+ private int mInitDeviceProvisionedValue;
@Before
public void setUp() {
@@ -69,13 +74,24 @@ public class SettingsPreferenceFragmentTest {
FakeFeatureFactory.setupForTest();
mContext = RuntimeEnvironment.application;
mFragment = spy(new TestFragment());
+ mFragment2 = spy(new TestFragment2());
doReturn(mActivity).when(mFragment).getActivity();
when(mFragment.getContext()).thenReturn(mContext);
+ when(mFragment2.getContext()).thenReturn(mContext);
mEmptyView = new View(mContext);
ReflectionHelpers.setField(mFragment, "mEmptyView", mEmptyView);
doReturn(ITEM_COUNT).when(mPreferenceScreen).getPreferenceCount();
+
+ mInitDeviceProvisionedValue = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0);
+ }
+
+ @After
+ public void tearDown() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, mInitDeviceProvisionedValue);
}
@Test
@@ -187,8 +203,66 @@ public class SettingsPreferenceFragmentTest {
verify(workOnlyCategory).setVisible(false);
}
+ @Test
+ public void onAttach_shouldNotSkipForSUWAndDeviceIsProvisioned_notCallFinish() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 1);
+
+ mFragment.onAttach(mContext);
+
+ verify(mFragment, never()).finish();
+ }
+
+ @Test
+ public void onAttach_shouldNotSkipForSUWAndDeviceIsNotProvisioned_notCallFinish() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0);
+
+ mFragment.onAttach(mContext);
+
+ verify(mFragment, never()).finish();
+ }
+
+ @Test
+ public void onAttach_shouldSkipForSUWAndDeviceIsDeviceProvisioned_notCallFinish() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 1);
+
+ mFragment2.onAttach(mContext);
+
+ verify(mFragment2, never()).finish();
+ }
+
+ @Test
+ public void onAttach_shouldSkipForSUWAndDeviceProvisioned_notCallFinish() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONED, 0);
+
+ mFragment2.onAttach(mContext);
+
+ verify(mFragment2, times(1)).finish();
+ }
+
public static class TestFragment extends SettingsPreferenceFragment {
+ @Override
+ protected boolean shouldSkipForInitialSUW() {
+ return false;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 0;
+ }
+ }
+
+ public static class TestFragment2 extends SettingsPreferenceFragment {
+
+ @Override
+ protected boolean shouldSkipForInitialSUW() {
+ return true;
+ }
+
@Override
public int getMetricsCategory() {
return 0;
diff --git a/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java
index 006087516c..b04d5c7637 100644
--- a/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/AccountDashboardFragmentTest.java
@@ -53,4 +53,9 @@ public class AccountDashboardFragmentTest {
assertThat(indexRes).isNotNull();
assertThat(indexRes.get(0).xmlResId).isEqualTo(mFragment.getPreferenceScreenResId());
}
+
+ @Test
+ public void shouldSkipForInitialSUW_returnTrue() {
+ assertThat(mFragment.shouldSkipForInitialSUW()).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
index e46cd06afe..5292c60f86 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java
@@ -384,6 +384,11 @@ public final class AppInfoDashboardFragmentTest {
.isTrue();
}
+ @Test
+ public void shouldSkipForInitialSUW_returnTrue() {
+ assertThat(mFragment.shouldSkipForInitialSUW()).isTrue();
+ }
+
@Implements(AppUtils.class)
public static class ShadowAppUtils {
diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
index 83a4880968..d460d13e9e 100644
--- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java
@@ -275,6 +275,11 @@ public class DevelopmentSettingsDashboardFragmentTest {
verify(controller).onDisableLogPersistDialogRejected();
}
+ @Test
+ public void shouldSkipForInitialSUW_returnTrue() {
+ assertThat(mDashboard.shouldSkipForInitialSUW()).isTrue();
+ }
+
@Implements(EnableDevelopmentSettingWarningDialog.class)
public static class ShadowEnableDevelopmentSettingWarningDialog {
diff --git a/tests/robotests/src/com/android/settings/system/ResetDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/system/ResetDashboardFragmentTest.java
new file mode 100644
index 0000000000..c1d47887a7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/system/ResetDashboardFragmentTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.system;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class ResetDashboardFragmentTest {
+
+ private ResetDashboardFragment mFragment;
+
+ @Before
+ public void setup() {
+ mFragment = new ResetDashboardFragment();
+ }
+
+ @Test
+ public void shouldSkipForInitialSUW_returnTrue() {
+ assertThat(mFragment.shouldSkipForInitialSUW()).isTrue();
+ }
+}

View File

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yanting Yang <yantingyang@google.com>
Date: Wed, 4 Jan 2023 09:40:38 +0000
Subject: [PATCH] Add DISALLOW_APPS_CONTROL check into uninstall app for all
users
Settings App info page supports a "Uninstall for all users" function
when multiple users are enabled. It bypasses the restriction of
DISALLOW_APPS_CONTROL which breaks the user isolation guideline.
To fix this vulnerability, we should check the DISALLOW_APPS_CONTROL
restriction to provide the "Uninstall for all users" function.
Bug: 258653813
Test: manual & robotests
Change-Id: I5d3bbcbaac439c4f7a1e6a9ade7775ff4f2f2ec6
Merged-In: I5d3bbcbaac439c4f7a1e6a9ade7775ff4f2f2ec6
(cherry picked from commit 86914bedc84474c152e4536fb3cfa2fb488030b8)
Merged-In: I5d3bbcbaac439c4f7a1e6a9ade7775ff4f2f2ec6
---
.../applications/appinfo/AppInfoDashboardFragment.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
mode change 100755 => 100644 src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
old mode 100755
new mode 100644
index b757380c5d..bbbb7113d5
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -355,7 +355,13 @@ public class AppInfoDashboardFragment extends DashboardFragment
return;
}
super.onPrepareOptionsMenu(menu);
- menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
+ final MenuItem uninstallAllUsersItem = menu.findItem(UNINSTALL_ALL_USERS_MENU);
+ uninstallAllUsersItem.setVisible(
+ shouldShowUninstallForAll(mAppEntry) && !mAppsControlDisallowedBySystem);
+ if (uninstallAllUsersItem.isVisible()) {
+ RestrictedLockUtilsInternal.setMenuItemAsDisabledByAdmin(getActivity(),
+ uninstallAllUsersItem, mAppsControlDisallowedAdmin);
+ }
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
final MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
final boolean uninstallUpdateDisabled = getContext().getResources().getBoolean(

View File

@ -1,42 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jack Yu <jackcwyu@google.com>
Date: Thu, 28 Jul 2022 19:42:27 +0800
Subject: [PATCH] Only primary user is allowed to control secure nfc
Bug: 238298970
Test: manual
Merged-In: I945490ef1e62af479a732c9a260ed94bdd8bc313
Change-Id: I945490ef1e62af479a732c9a260ed94bdd8bc313
(cherry picked from commit 0e57ff90cdae3575c243d21d490e2b6384d33397)
Merged-In: I945490ef1e62af479a732c9a260ed94bdd8bc313
---
src/com/android/settings/nfc/SecureNfcEnabler.java | 2 +-
src/com/android/settings/nfc/SecureNfcPreferenceController.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/com/android/settings/nfc/SecureNfcEnabler.java b/src/com/android/settings/nfc/SecureNfcEnabler.java
index f31a382a57..ad5c4ab7e8 100644
--- a/src/com/android/settings/nfc/SecureNfcEnabler.java
+++ b/src/com/android/settings/nfc/SecureNfcEnabler.java
@@ -61,7 +61,7 @@ public class SecureNfcEnabler extends BaseNfcEnabler {
}
private boolean isToggleable() {
- if (mUserManager.isGuestUser()) {
+ if (!mUserManager.isPrimaryUser()) {
return false;
}
return true;
diff --git a/src/com/android/settings/nfc/SecureNfcPreferenceController.java b/src/com/android/settings/nfc/SecureNfcPreferenceController.java
index 2ff685e5a0..ab87ddba34 100644
--- a/src/com/android/settings/nfc/SecureNfcPreferenceController.java
+++ b/src/com/android/settings/nfc/SecureNfcPreferenceController.java
@@ -104,7 +104,7 @@ public class SecureNfcPreferenceController extends TogglePreferenceController
}
private boolean isToggleable() {
- if (mUserManager.isGuestUser()) {
+ if (!mUserManager.isPrimaryUser()) {
return false;
}
return true;

View File

@ -1,190 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bonian Chen <bonianchen@google.com>
Date: Thu, 18 Nov 2021 10:27:34 +0800
Subject: [PATCH] Move display of VPN version into summary text
Move the display of version text within VPN into summary part of the
display, and limit the height of summary area.
Bug: 205460459
Test: install apk from b/205460459#comment3 and verify
(cherry picked from commit 144f295d7aa66bae8556ba030553a49615eab0b2)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:dddd74a491a206178feb10d5ef983d5cd273504d)
Merged-In: I666b9db356feeebf04e3be688897c2d9110a5275
Change-Id: I666b9db356feeebf04e3be688897c2d9110a5275
---
res/values/strings.xml | 2 +-
res/values/styles.xml | 10 ++++
res/xml/vpn_app_management.xml | 14 ++++-
.../settings/vpn2/AppManagementFragment.java | 51 +++++++++++++++++--
4 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2180ea45f6..f6e3b0f62d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6613,7 +6613,7 @@
<!-- Button label to disconnect from a VPN profile. [CHAR LIMIT=40] -->
<string name="vpn_disconnect">Disconnect</string>
<!-- Field label to show the version number for a VPN app. [CHAR LIMIT=40] -->
- <string name="vpn_version">Version <xliff:g id="version" example="3.3.0">%s</xliff:g></string>
+ <string name="vpn_version">Version</string>
<!-- Button label to forget a VPN profile [CHAR LIMIT=40] -->
<string name="vpn_forget_long">Forget VPN</string>
<!-- Dialog message title to set another VPN app to be always-on [CHAR LIMIT=40] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d3d3199f62..ec66bc8d1b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -197,6 +197,16 @@
<item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Small</item>
</style>
+ <style name="vpn_app_management_version_title">
+ <item name="android:textAppearance">?android:attr/textAppearanceListItem</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="vpn_app_management_version_summary">
+ <item name="android:textAppearance">?android:attr/textAppearanceListItemSecondary</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ </style>
+
<style name="TextAppearance" parent="android:TextAppearance.DeviceDefault"/>
<style name="TextAppearance.info_label">
diff --git a/res/xml/vpn_app_management.xml b/res/xml/vpn_app_management.xml
index bcaa6b0a62..adc441d846 100644
--- a/res/xml/vpn_app_management.xml
+++ b/res/xml/vpn_app_management.xml
@@ -15,14 +15,24 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:settings="http://schemas.android.com/apk/res-auto">
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ orderingFromXml="false"
+ >
+
+ <!-- To limit the size (in height) of version Preference displayed here,
+ maximum height of TextView need to be set programmingly.
+ Therefore, this Preference got removed from here and will be added
+ dynamically through source code.
<Preference
+ android:order="0"
android:key="version"
android:textColor="?android:attr/textColorSecondary"
android:selectable="false"/>
+ -->
<com.android.settingslib.RestrictedSwitchPreference
+ android:order="10"
android:key="always_on_vpn"
android:title="@string/vpn_menu_lockdown"
android:defaultValue="false"
@@ -32,6 +42,7 @@
settings:restrictedSwitchSummary="@string/disabled_by_admin_summary_text" />
<com.android.settingslib.RestrictedSwitchPreference
+ android:order="20"
android:key="lockdown_vpn"
android:title="@string/vpn_require_connection"
android:defaultValue="false"
@@ -41,6 +52,7 @@
settings:restrictedSwitchSummary="@string/disabled_by_admin_summary_text" />
<com.android.settingslib.RestrictedPreference
+ android:order="30"
android:key="forget_vpn"
android:title="@string/vpn_forget_long"
android:icon="@drawable/ic_delete"
diff --git a/src/com/android/settings/vpn2/AppManagementFragment.java b/src/com/android/settings/vpn2/AppManagementFragment.java
index 5f4644614c..805ffb2854 100644
--- a/src/com/android/settings/vpn2/AppManagementFragment.java
+++ b/src/com/android/settings/vpn2/AppManagementFragment.java
@@ -35,11 +35,13 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
+import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
import com.android.internal.net.VpnConfig;
import com.android.internal.util.ArrayUtils;
@@ -76,7 +78,6 @@ public class AppManagementFragment extends SettingsPreferenceFragment
private String mVpnLabel;
// UI preference
- private Preference mPreferenceVersion;
private RestrictedSwitchPreference mPreferenceAlwaysOn;
private RestrictedSwitchPreference mPreferenceLockdown;
private RestrictedPreference mPreferenceForget;
@@ -122,7 +123,6 @@ public class AppManagementFragment extends SettingsPreferenceFragment
mConnectivityService = IConnectivityManager.Stub
.asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
- mPreferenceVersion = findPreference(KEY_VERSION);
mPreferenceAlwaysOn = (RestrictedSwitchPreference) findPreference(KEY_ALWAYS_ON_VPN);
mPreferenceLockdown = (RestrictedSwitchPreference) findPreference(KEY_LOCKDOWN_VPN);
mPreferenceForget = (RestrictedPreference) findPreference(KEY_FORGET_VPN);
@@ -138,9 +138,52 @@ public class AppManagementFragment extends SettingsPreferenceFragment
boolean isInfoLoaded = loadInfo();
if (isInfoLoaded) {
- mPreferenceVersion.setTitle(
- getPrefContext().getString(R.string.vpn_version, mPackageInfo.versionName));
updateUI();
+
+ Preference version = getPreferenceScreen().findPreference(KEY_VERSION);
+ if (version != null) {
+ // Version field has been added.
+ return;
+ }
+
+ /**
+ * Create version field at runtime, and set max height on the display area.
+ *
+ * When long length of text given within version field, a large text area
+ * might be created and inconvenient to the user (User need to scroll
+ * for a long time in order to get to the Preferences after this field.)
+ */
+ version = new Preference(getPrefContext()) {
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ TextView titleView =
+ (TextView) holder.findViewById(android.R.id.title);
+ if (titleView != null) {
+ titleView.setTextAppearance(R.style.vpn_app_management_version_title);
+ }
+
+ TextView summaryView =
+ (TextView) holder.findViewById(android.R.id.summary);
+ if (summaryView != null) {
+ summaryView.setTextAppearance(R.style.vpn_app_management_version_summary);
+
+ // Set max height in summary area.
+ int versionMaxHeight = getListView().getHeight();
+ summaryView.setMaxHeight(versionMaxHeight);
+ summaryView.setVerticalScrollBarEnabled(false);
+ summaryView.setHorizontallyScrolling(false);
+ }
+ }
+ };
+ version.setOrder(0); // Set order to 0 in order to be placed
+ // in front of other Preference(s).
+ version.setKey(KEY_VERSION); // Set key to avoid from creating multi instance.
+ version.setTitle(R.string.vpn_version);
+ version.setSummary(mPackageInfo.versionName);
+ version.setSelectable(false);
+ getPreferenceScreen().addPreference(version);
} else {
finish();
}

View File

@ -1,28 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Dementyev <dementyev@google.com>
Date: Tue, 7 Mar 2023 10:36:41 -0800
Subject: [PATCH] Convert argument to intent in AddAccountSettings.
Bug: 265798353
Test: manual
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c7e8052b527434ed8660e3babdab718f7f3cd7da)
Merged-In: I0051e5d5fc9fd3691504cb5fbb959f701e0bce6a
Change-Id: I0051e5d5fc9fd3691504cb5fbb959f701e0bce6a
---
src/com/android/settings/accounts/AddAccountSettings.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/com/android/settings/accounts/AddAccountSettings.java b/src/com/android/settings/accounts/AddAccountSettings.java
index cca15c96d3..2e23e93124 100644
--- a/src/com/android/settings/accounts/AddAccountSettings.java
+++ b/src/com/android/settings/accounts/AddAccountSettings.java
@@ -102,7 +102,8 @@ public class AddAccountSettings extends Activity {
addAccountOptions.putParcelable(EXTRA_USER, mUserHandle);
intent.putExtras(addAccountOptions);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivityForResultAsUser(intent, ADD_ACCOUNT_REQUEST, mUserHandle);
+ startActivityForResultAsUser(
+ new Intent(intent), ADD_ACCOUNT_REQUEST, mUserHandle);
} else {
setResult(RESULT_OK);
if (mPendingIntent != null) {

View File

@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Dementyev <dementyev@google.com>
Date: Tue, 7 Mar 2023 10:55:07 -0800
Subject: [PATCH] Convert argument to intent in addAccount TvSettings.
Bug: 265798353
Test: manual
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:706edcb7532d74788f899968016b7a6273bfbcac)
Merged-In: I06a63078f55ee8169123b1dfcf1811e682e0776e
Change-Id: I06a63078f55ee8169123b1dfcf1811e682e0776e
---
.../tv/settings/accounts/AddAccountWithTypeActivity.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java b/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java
index a608bc4fa..ff71ac93b 100644
--- a/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java
+++ b/Settings/src/com/android/tv/settings/accounts/AddAccountWithTypeActivity.java
@@ -52,7 +52,7 @@ public class AddAccountWithTypeActivity extends Activity {
Log.e(TAG, "Failed to retrieve add account intent from authenticator");
setResultAndFinish(Activity.RESULT_CANCELED);
} else {
- startActivityForResult(addAccountIntent, REQUEST_ADD_ACCOUNT);
+ startActivityForResult(new Intent(addAccountIntent), REQUEST_ADD_ACCOUNT);
}
} catch (IOException|AuthenticatorException|OperationCanceledException e) {
Log.e(TAG, "Failed to get add account intent: ", e);

View File

@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Abhijeet Kaur <abkaur@google.com>
Date: Wed, 23 Nov 2022 08:47:27 +0000
Subject: [PATCH] Canonicalise path before extracting relative path
This helps us make accurate access checks on the given path.
Bug: 228833816
Bug: 228450832
Test: atest FileUtilsTest
Test: atest LegacyStorageHostTest
Change-Id: Id620644ffdfe20e9281773e2e23851c56732dd11
Merged-In: Id620644ffdfe20e9281773e2e23851c56732dd11
(cherry picked from commit 93f5186e4b4a044e00a168c55e05fd3835033221)
(cherry picked from commit 0f59f42685f186fd207355c01c580038436713ba)
Merged-In: Id620644ffdfe20e9281773e2e23851c56732dd11
---
src/com/android/providers/media/MediaProvider.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 9032644e7..f9ea135fd 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -2308,8 +2308,22 @@ public class MediaProvider extends ContentProvider {
}
}
+ @Nullable
+ private static String getCanonicalPath(@Nullable String path) {
+ if (path == null) return null;
+
+ try {
+ return new File(path).getCanonicalPath();
+ } catch (IOException e) {
+ Log.d(TAG, "Unable to get canonical path from invalid data path: " + path, e);
+ return null;
+ }
+ }
+
private static @Nullable String extractRelativePath(@Nullable String data) {
+ data = getCanonicalPath(data);
if (data == null) return null;
+
final Matcher matcher = PATTERN_RELATIVE_PATH.matcher(data);
if (matcher.find()) {
final int lastSlash = data.lastIndexOf('/');

View File

@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Pranav Madapurmath <pmadapurmath@google.com>
Date: Wed, 1 Feb 2023 21:33:16 +0000
Subject: [PATCH] Ensure service unbind when receiving a null call screening
service in onBind.
Currently, we do not unbind the call screening service when a null
service is returned from onBind when placing MO calls.
CallScreeningServiceHelper (MO) now overrides onNullBinding to ensure
future completion and that we unbind the service after. Similarly, we
need to unbind the service in onServiceDisconnected.
CallScreeningServiceFilter (MT) has also been updated to ensure we
unbind in places when we know that the connection should not exist.
Also, there is a timeout in CallScreeningServiceHelper. This does not
require a call to unbind the service because CallScreeningAdapter also
places a call to unbind the service in onScreeningResponse. We would
risk having duplicate calls to unbind the service, which would cause a
fatal exception. This is demonstrated by the existing CTS tests, namely,
ThirdPartyCallScreeningServiceTest.java.
Bug: 252762941
Test: Manual (no breakage in existing flow), CTS for MO/MT cases
Change-Id: Ia5b62bb93dc666b6b8b8daccb8ef41eb55dde7ea
Merged-In: Ia5b62bb93dc666b6b8b8daccb8ef41eb55dde7ea
(cherry picked from commit 14927c6f0b4154ee31dc4e339ea4a692f73ad2e0)
(cherry picked from commit 60f4ee794adbac4950ab22b44c4630edf7239e12)
Merged-In: Ia5b62bb93dc666b6b8b8daccb8ef41eb55dde7ea
---
.../telecom/CallScreeningServiceHelper.java | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/com/android/server/telecom/CallScreeningServiceHelper.java b/src/com/android/server/telecom/CallScreeningServiceHelper.java
index a9341ab82..89778e43a 100644
--- a/src/com/android/server/telecom/CallScreeningServiceHelper.java
+++ b/src/com/android/server/telecom/CallScreeningServiceHelper.java
@@ -146,6 +146,23 @@ public class CallScreeningServiceHelper {
"Cancelling outgoing call screen due to service disconnect.");
}
mFuture.complete(null);
+ mContext.unbindService(this);
+ } finally {
+ Log.endSession();
+ }
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ // No locking needed -- CompletableFuture only lets one thread call complete.
+ Log.continueSession(mLoggingSession, "CSSH.oNB");
+ try {
+ if (!mFuture.isDone()) {
+ Log.w(CallScreeningServiceHelper.this,
+ "Cancelling outgoing call screen due to null binding.");
+ }
+ mFuture.complete(null);
+ mContext.unbindService(this);
} finally {
Log.endSession();
}

View File

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chinmay Dhodapkar <chinmayd@google.com>
Date: Sun, 4 Dec 2022 09:46:34 -0800
Subject: [PATCH] DO NOT MERGE do not process content uri in call Intents
Add checks in Telecom so content uris are not processed
Bug: 257030107
Test: atest NewOutgoingCallIntentBroadcasterTest
Test: adb shell am start -a android.intent.action.CALL -d tel:xxx
Change-Id: Ic2c3014cecfd5db84dc2023b4c247d96ad1c3414
Merged-In: Ic2c3014cecfd5db84dc2023b4c247d96ad1c3414
(cherry picked from commit 9636518478fb887dd1834c0433eb3a71eb72faaf)
Merged-In: Ic2c3014cecfd5db84dc2023b4c247d96ad1c3414
---
.../telecom/NewOutgoingCallIntentBroadcaster.java | 14 ++++++++++++--
.../NewOutgoingCallIntentBroadcasterTest.java | 13 +++++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
index 7a641af3c..960be80a3 100644
--- a/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
+++ b/src/com/android/server/telecom/NewOutgoingCallIntentBroadcaster.java
@@ -313,8 +313,18 @@ public class NewOutgoingCallIntentBroadcaster {
}
private String getNumberFromCallIntent(Intent intent) {
- String number;
- number = mPhoneNumberUtilsAdapter.getNumberFromIntent(intent, mContext);
+ String number = null;
+
+ Uri uri = intent.getData();
+ if (uri != null) {
+ String scheme = uri.getScheme();
+ if (scheme != null) {
+ if (scheme.equals("tel") || scheme.equals("sip")) {
+ number = uri.getSchemeSpecificPart();
+ }
+ }
+ }
+
if (TextUtils.isEmpty(number)) {
Log.w(this, "Empty number obtained from the call intent.");
return null;
diff --git a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
index 81b43265f..b618bba1e 100644
--- a/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
+++ b/tests/src/com/android/server/telecom/tests/NewOutgoingCallIntentBroadcasterTest.java
@@ -186,6 +186,19 @@ public class NewOutgoingCallIntentBroadcasterTest extends TelecomTestCase {
verifyNoCallPlaced();
}
+ @Test
+ public void testNoCallsPlacedWithContentUri() {
+ Uri handle = Uri.parse("content://com.android.contacts/data/1");
+ Intent intent = new Intent(Intent.ACTION_CALL, handle);
+
+ int result = processIntent(intent, true).disconnectCause;
+
+ assertEquals(DisconnectCause.NO_PHONE_NUMBER_SUPPLIED, result);
+ verify(mContext, never()).getContentResolver();
+ verifyNoBroadcastSent();
+ verifyNoCallPlaced();
+ }
+
@SmallTest
@Test
public void testEmergencyCallWithNonDefaultDialer() {

View File

@ -1,443 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Thomas Stuart <tjstuart@google.com>
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 | 183 ++++++++++++++++--
.../server/telecom/TelecomServiceImpl.java | 4 +-
.../tests/PhoneAccountRegistrarTest.java | 101 ++++++++++
.../telecom/tests/TelecomServiceImplTest.java | 2 +-
4 files changed, 274 insertions(+), 16 deletions(-)
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index 13b176c25..219de7d03 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -29,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;
@@ -140,9 +141,14 @@ public class PhoneAccountRegistrar {
}
public 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";
@@ -722,6 +728,15 @@ public class PhoneAccountRegistrar {
return getPhoneAccountHandles(0, null, packageName, false, userHandle);
}
+
+ /**
+ * includes disabled, includes crossUserAccess
+ */
+ public List<PhoneAccountHandle> getAllPhoneAccountHandlesForPackage(UserHandle userHandle,
+ String packageName) {
+ return getPhoneAccountHandles(0, null, packageName, true /* includeDisabled */, userHandle);
+ }
+
/**
* Determines if a {@link PhoneAccountHandle} is for a self-managed {@link ConnectionService}.
* @param handle The handle.
@@ -741,8 +756,11 @@ public class PhoneAccountRegistrar {
* 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
@@ -754,21 +772,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<String> 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");
+ }
+ }
}
/**
@@ -1489,17 +1641,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 d3bbab232..8c498fc55 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -63,7 +63,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;
@@ -292,7 +294,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 a978cfd24..f14a3f74e 100644
--- a/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
+++ b/tests/src/com/android/server/telecom/tests/PhoneAccountRegistrarTest.java
@@ -22,8 +22,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;
import android.content.ComponentName;
@@ -69,6 +79,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;
@@ -80,6 +92,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;
@@ -942,6 +957,92 @@ public class PhoneAccountRegistrarTest extends TelecomTestCase {
assertFalse(PhoneAccountHandle.areFromSamePackage(null, d));
}
+ /**
+ * 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 2130121ac..00d8000e4 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -392,7 +392,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,

View File

@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Pranav Madapurmath <pmadapurmath@google.com>
Date: Tue, 21 Mar 2023 23:28:56 +0000
Subject: [PATCH] Call Redirection: unbind service when onBind returns null
The call redirection service does not handle the corner case of
onNullBinding (occurs when onBind returns null). This vulnerability
would give the app that has the call redirection role unintentional
access to launch background activities outside the scope of a call
lifecycle.
Fixes: 273260090
Test: Unit test to ensure we unbind the service on null onBind
Test: CTS for similar assertion
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c3580d96071a7232ce11ad83848d6394b93121d8)
Merged-In: Ib9d44d239833131eb055e83801cb635e8efe0b81
Change-Id: Ib9d44d239833131eb055e83801cb635e8efe0b81
---
.../CallRedirectionProcessor.java | 13 ++++++++++
.../tests/CallRedirectionProcessorTest.java | 25 +++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java b/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
index 7a54118f8..9ddc4ab6c 100644
--- a/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
+++ b/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
@@ -151,6 +151,19 @@ public class CallRedirectionProcessor implements CallRedirectionCallback {
Log.endSession();
}
}
+
+ @Override
+ public void onNullBinding(ComponentName componentName) {
+ // Make sure we unbind the service if onBind returns null
+ Log.startSession("CRSC.oNB");
+ try {
+ synchronized (mTelecomLock) {
+ finishCallRedirection();
+ }
+ } finally {
+ Log.endSession();
+ }
+ }
}
private class CallRedirectionAdapter extends ICallRedirectionAdapter.Stub {
diff --git a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
index 169c56acf..44d2b8956 100644
--- a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
@@ -280,4 +280,29 @@ public class CallRedirectionProcessorTest extends TelecomTestCase {
eq(mPhoneAccountHandle), eq(mGatewayInfo), eq(SPEAKER_PHONE_ON), eq(VIDEO_STATE),
eq(false), eq(CallRedirectionProcessor.UI_TYPE_NO_ACTION));
}
+
+
+ @Test
+ public void testUnbindOnNullBind() throws Exception {
+ startProcessWithNoGateWayInfo();
+ // To make sure tests are not flaky, clean all the previous handler messages
+ waitForHandlerAction(mProcessor.getHandler(), HANDLER_TIMEOUT_DELAY);
+ enableUserDefinedCallRedirectionService();
+ disableCarrierCallRedirectionService();
+
+ mProcessor.performCallRedirection();
+
+ // Capture the binder
+ ArgumentCaptor<ServiceConnection> serviceConnectionCaptor = ArgumentCaptor.forClass(
+ ServiceConnection.class);
+ // Verify binding occurred
+ verify(mContext, times(1)).bindServiceAsUser(any(Intent.class),
+ serviceConnectionCaptor.capture(), anyInt(), eq(UserHandle.CURRENT));
+ // Simulate null return from onBind
+ serviceConnectionCaptor.getValue().onNullBinding(USER_DEFINED_SERVICE_TEST_COMPONENT_NAME);
+
+ // Verify service was unbound
+ verify(mContext, times(1)).
+ unbindService(any(ServiceConnection.class));
+ }
}

View File

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Wed, 28 Dec 2022 00:32:37 +0000
Subject: [PATCH] Fix an OOB Write bug in gatt_check_write_long_terminate
this is the backport of Ifffa2c7f679c4ef72dbdb6b1f3378ca506680084
Bug: 258652631
Test: manual
Tag: #security
Ignore-AOSP-First: security
Change-Id: Ic84122f07cbc198c676d366e39606621b7cb4e66
(cherry picked from commit 9b17660bfd6f0f41cb9400ce0236d76c83605e03)
Merged-In: Ic84122f07cbc198c676d366e39606621b7cb4e66
---
stack/gatt/gatt_cl.cc | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index 3115317da..db41c5f9f 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -572,7 +572,8 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
LOG(ERROR) << StringPrintf("value resp op_code = %s len = %d",
gatt_dbg_op_name(op_code), len);
- if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
+ if (len < GATT_PREP_WRITE_RSP_MIN_LEN ||
+ len > GATT_PREP_WRITE_RSP_MIN_LEN + sizeof(value.value)) {
LOG(ERROR) << "illegal prepare write response length, discard";
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
return;
@@ -581,7 +582,7 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
STREAM_TO_UINT16(value.handle, p);
STREAM_TO_UINT16(value.offset, p);
- value.len = len - 4;
+ value.len = len - GATT_PREP_WRITE_RSP_MIN_LEN;
memcpy(value.value, p, value.len);

View File

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Mon, 2 Jan 2023 22:05:45 +0000
Subject: [PATCH] Fix an OOB access bug in A2DP_BuildMediaPayloadHeaderSbc
In A2DP_BuildCodecHeaderSbc when p_buf->offset is 0, the
`-=` operation on it may result in integer underflow and
OOB write with the computed pointer passed to
A2DP_BuildMediaPayloadHeaderSbc.
This is a backport of I45320085b1e458d3b0e0d86162a35aaaae7b34cb
Test: atest net_test_stack_a2dp_codecs_native
Ignore-AOSP-First: security
Tag:#security
Bug: 186803518
Change-Id: I4ff1a1de71884b8de23008b2569fdea3650e85ec
(cherry picked from commit a710300216be4a86373a65c6a685aeef8509cfa7)
Merged-In: I4ff1a1de71884b8de23008b2569fdea3650e85ec
---
stack/a2dp/a2dp_sbc.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc
index 4c48993c4..5036eec2e 100644
--- a/stack/a2dp/a2dp_sbc.cc
+++ b/stack/a2dp/a2dp_sbc.cc
@@ -704,6 +704,11 @@ bool A2DP_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t* p_codec_info,
BT_HDR* p_buf, uint16_t frames_per_packet) {
uint8_t* p;
+ // there is a timestamp right following p_buf
+ if (p_buf->offset < 4 + A2DP_SBC_MPL_HDR_LEN) {
+ return false;
+ }
+
p_buf->offset -= A2DP_SBC_MPL_HDR_LEN;
p = (uint8_t*)(p_buf + 1) + p_buf->offset;
p_buf->len += A2DP_SBC_MPL_HDR_LEN;

View File

@ -1,75 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Wed, 4 Jan 2023 22:45:13 +0000
Subject: [PATCH] Fix an OOB write in SDP_AddAttribute
When the `attr_pad` becomes full, it is possible
that un index of `-1` is computed write
a zero byte to `p_val`, rusulting OOB write.
```
p_val[SDP_MAX_PAD_LEN - p_rec->free_pad_ptr - 1] = '\0';
```
This is a backport of I937d22a2df26fca1d7f06b10182c4e713ddfed1b
Bug: 261867748
Test: manual
Tag: #security
Ignore-AOSP-First: security
Change-Id: Ibdda754e628cfc9d1706c14db114919a15d8d6b1
(cherry picked from commit cc527a97f78a2999a0156a579e488afe9e3675b2)
Merged-In: Ibdda754e628cfc9d1706c14db114919a15d8d6b1
---
stack/sdp/sdp_db.cc | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/stack/sdp/sdp_db.cc b/stack/sdp/sdp_db.cc
index ea5b84d23..4130ae71a 100644
--- a/stack/sdp/sdp_db.cc
+++ b/stack/sdp/sdp_db.cc
@@ -362,6 +362,11 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
uint16_t xx, yy, zz;
tSDP_RECORD* p_rec = &sdp_cb.server_db.record[0];
+ if (p_val == nullptr) {
+ SDP_TRACE_WARNING("Trying to add attribute with p_val == nullptr, skipped");
+ return (false);
+ }
+
if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) {
if ((attr_type == UINT_DESC_TYPE) ||
(attr_type == TWO_COMP_INT_DESC_TYPE) ||
@@ -398,6 +403,13 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
if (p_rec->record_handle == handle) {
tSDP_ATTRIBUTE* p_attr = &p_rec->attribute[0];
+ // error out early, no need to look up
+ if (p_rec->free_pad_ptr >= SDP_MAX_PAD_LEN) {
+ SDP_TRACE_ERROR("the free pad for SDP record with handle %d is "
+ "full, skip adding the attribute", handle);
+ return (false);
+ }
+
/* Found the record. Now, see if the attribute already exists */
for (xx = 0; xx < p_rec->num_attributes; xx++, p_attr++) {
/* The attribute exists. replace it */
@@ -437,15 +449,13 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
attr_len = 0;
}
- if ((attr_len > 0) && (p_val != 0)) {
+ if (attr_len > 0) {
p_attr->len = attr_len;
memcpy(&p_rec->attr_pad[p_rec->free_pad_ptr], p_val, (size_t)attr_len);
p_attr->value_ptr = &p_rec->attr_pad[p_rec->free_pad_ptr];
p_rec->free_pad_ptr += attr_len;
- } else if ((attr_len == 0 &&
- p_attr->len !=
- 0) || /* if truncate to 0 length, simply don't add */
- p_val == 0) {
+ } else if (attr_len == 0 && p_attr->len != 0) {
+ /* if truncate to 0 length, simply don't add */
SDP_TRACE_ERROR(
"SDP_AddAttribute fail, length exceed maximum: ID %d: attr_len:%d ",
attr_id, attr_len);

View File

@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Thu, 8 Dec 2022 01:08:11 +0000
Subject: [PATCH] Fix OOB access in avdt_scb_hdl_pkt_no_frag
This is a back port of the following 2 CLs:
- Id13b1ebde8f603123c8b7a49922b2f1378ab788f
- If0c7b25f2e6cb4531bbb6254e176e8ad1b5c5fb4
Regression test: I9c87e30ed58e7ad6a34ab7c96b0a8fb06324ad54
Bug: 142546355 258057241
Test: atest net_test_stack_avdtp
Ignore-AOSP-First: security
Change-Id: Ie1707385d6452ece47915c153f4faaa1c8a287c9
(cherry picked from commit b0b968e8c6214e20a5dc3617d66567225df0884f)
Merged-In: Ie1707385d6452ece47915c153f4faaa1c8a287c9
---
stack/avdt/avdt_scb_act.cc | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/stack/avdt/avdt_scb_act.cc b/stack/avdt/avdt_scb_act.cc
index ce53c45eb..f2de4ba35 100644
--- a/stack/avdt/avdt_scb_act.cc
+++ b/stack/avdt/avdt_scb_act.cc
@@ -255,19 +255,24 @@ void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
if (offset > len) goto length_error;
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
- offset += ex_len * 4;
p += ex_len * 4;
}
+ if ((p - p_start) >= len) {
+ AVDT_TRACE_WARNING("%s: handling malformatted packet: ex_len too large", __func__);
+ osi_free_and_reset((void**)&p_data->p_pkt);
+ return;
+ }
+ offset = p - p_start;
+
/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
- pad_len = *(p_start + p_data->p_pkt->len);
+ pad_len = *(p_start + len - 1);
}
/* do sanity check */
- if ((offset > p_data->p_pkt->len) ||
- ((pad_len + offset) > p_data->p_pkt->len)) {
+ if (pad_len >= (len - offset)) {
AVDT_TRACE_WARNING("Got bad media packet");
osi_free_and_reset((void**)&p_data->p_pkt);
}

View File

@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Fri, 20 Jan 2023 19:39:30 +0000
Subject: [PATCH] Fix an OOB bug in register_notification_rsp
This is a backport of I901d973a736678d7f3cc816ddf0cbbcbbd1fe93f
to rvc-dev.
Bug: 245916076
Test: manual
Ignore-AOSP-First: security
Change-Id: I37a9f45e707702b2ec52b5a2d572f177f2911765
(cherry picked from commit 901e34203c6280d414cbfa3978de04fd6515ffdf)
Merged-In: I37a9f45e707702b2ec52b5a2d572f177f2911765
---
btif/src/btif_rc.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index 575d83e37..be29e559b 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -1892,6 +1892,11 @@ static bt_status_t register_notification_rsp(
dump_rc_notification_event_id(event_id));
std::unique_lock<std::mutex> lock(btif_rc_cb.lock);
+ if (event_id > MAX_RC_NOTIFICATIONS) {
+ BTIF_TRACE_ERROR("Invalid event id");
+ return BT_STATUS_PARM_INVALID;
+ }
+
memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
avrc_rsp.reg_notif.event_id = event_id;

View File

@ -1,107 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Tue, 11 Oct 2022 21:23:22 +0000
Subject: [PATCH] Prevent use-after-free of HID reports
BTA sends the the HID report pointer to BTIF and deallocates it immediately.
This is now prevented by providing a deep copy callback function for HID
reports when tranferring context from BTA to BTIF.
This is a backport of change Icef7a7ed1185b4283ee4fe4f812ca154d8f1b825,
already merged on T for b/227620181.
Bug: 228837201
Test: Validated against researcher POC, ran BT unit tests, played audio
manually.
Tag: #security
Ignore-AOSP-First: Security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:874c495c886cd8722625756dc5fd0634b16b4f42)
Merged-In: Ib837f395883de2369207f1b3b974d6bff02dcb19
Change-Id: Ib837f395883de2369207f1b3b974d6bff02dcb19
---
btif/src/btif_hh.cc | 50 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)
diff --git a/btif/src/btif_hh.cc b/btif/src/btif_hh.cc
index 650923a3c..5c57ee80c 100644
--- a/btif/src/btif_hh.cc
+++ b/btif/src/btif_hh.cc
@@ -1096,6 +1096,38 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
}
}
+/*******************************************************************************
+ *
+ * Function btif_hh_hsdata_rpt_copy_cb
+ *
+ * Description Deep copies the tBTA_HH_HSDATA structure
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+
+static void btif_hh_hsdata_rpt_copy_cb(uint16_t event, char* p_dest,
+ char* p_src) {
+ tBTA_HH_HSDATA* p_dst_data = (tBTA_HH_HSDATA*)p_dest;
+ tBTA_HH_HSDATA* p_src_data = (tBTA_HH_HSDATA*)p_src;
+ BT_HDR* hdr;
+
+ if (!p_src) {
+ BTIF_TRACE_ERROR("%s: Nothing to copy", __func__);
+ return;
+ }
+
+ memcpy(p_dst_data, p_src_data, sizeof(tBTA_HH_HSDATA));
+
+ hdr = p_src_data->rsp_data.p_rpt_data;
+ if (hdr != NULL) {
+ uint8_t* p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HH_HSDATA);
+ memcpy(p_data, hdr, BT_HDR_SIZE + hdr->offset + hdr->len);
+
+ p_dst_data->rsp_data.p_rpt_data = (BT_HDR*)p_data;
+ }
+}
+
/*******************************************************************************
*
* Function bte_hh_evt
@@ -1109,6 +1141,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
bt_status_t status;
int param_len = 0;
+ tBTIF_COPY_CBACK* p_copy_cback = NULL;
if (BTA_HH_ENABLE_EVT == event)
param_len = sizeof(tBTA_HH_STATUS);
@@ -1120,11 +1153,18 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
param_len = sizeof(tBTA_HH_CBDATA);
else if (BTA_HH_GET_DSCP_EVT == event)
param_len = sizeof(tBTA_HH_DEV_DSCP_INFO);
- else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
- (BTA_HH_GET_IDLE_EVT == event))
+ else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_IDLE_EVT == event))
+ param_len = sizeof(tBTA_HH_HSDATA);
+ else if (BTA_HH_GET_RPT_EVT == event) {
+ BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
param_len = sizeof(tBTA_HH_HSDATA);
- else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
- (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
+
+ if (hdr != NULL) {
+ p_copy_cback = btif_hh_hsdata_rpt_copy_cb;
+ param_len += BT_HDR_SIZE + hdr->offset + hdr->len;
+ }
+ } else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
+ (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
param_len = sizeof(tBTA_HH_CBDATA);
else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
param_len = sizeof(tBTA_HH_DEV_INFO);
@@ -1133,7 +1173,7 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
/* switch context to btif task context (copy full union size for convenience)
*/
status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
- (char*)p_data, param_len, NULL);
+ (char*)p_data, param_len, p_copy_cback);
/* catch any failed context transfers */
ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);

View File

@ -1,141 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Tue, 21 Mar 2023 22:35:35 +0000
Subject: [PATCH] Revert "Revert "[RESTRICT AUTOMERGE] Validate buffer length
in sdpu_build_uuid_seq""
This reverts commit 487a1079078f3717fdc4665c19a45eca5b3ec5e6.
Reason for revert: Reinstate original change for QPR
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a681067af2ea4565543238db3025d749923f63ec)
Merged-In: If0528519a29dc73ff99163098da2a05592ab15d8
Change-Id: If0528519a29dc73ff99163098da2a05592ab15d8
---
stack/sdp/sdp_discovery.cc | 65 ++++++++++++++++++++++++++++++++++----
1 file changed, 58 insertions(+), 7 deletions(-)
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index f5938e423..553e068f5 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -70,10 +70,15 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db,
*
******************************************************************************/
static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
- Uuid* p_uuid_list) {
+ Uuid* p_uuid_list, uint16_t& bytes_left) {
uint16_t xx;
uint8_t* p_len;
+ if (bytes_left < 2) {
+ DCHECK(0) << "SDP: No space for data element header";
+ return (p_out);
+ }
+
/* First thing is the data element header */
UINT8_TO_BE_STREAM(p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
@@ -81,9 +86,20 @@ static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
p_len = p_out;
p_out += 1;
+ /* Account for data element header and length */
+ bytes_left -= 2;
+
/* Now, loop through and put in all the UUID(s) */
for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
int len = p_uuid_list->GetShortestRepresentationSize();
+
+ if (len + 1 > bytes_left) {
+ DCHECK(0) << "SDP: Too many UUIDs for internal buffer";
+ break;
+ } else {
+ bytes_left -= (len + 1);
+ }
+
if (len == Uuid::kNumBytes16) {
UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
UINT16_TO_BE_STREAM(p_out, p_uuid_list->As16Bit());
@@ -120,6 +136,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
uint8_t *p, *p_start, *p_param_len;
BT_HDR* p_cmd = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
uint16_t param_len;
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
/* Prepare the buffer for sending the packet to L2CAP */
p_cmd->offset = L2CAP_MIN_OFFSET;
@@ -134,13 +151,30 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
p_param_len = p;
p += 2;
-/* Build the UID sequence. */
+ /* Account for header size, max service record count and
+ * continuation state */
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
+ 3u + /* service search request header */
+ 2u + /* param len */
+ 3u + ((p_cont) ? cont_len : 0));
+
+ if (base_bytes > bytes_left) {
+ DCHECK(0) << "SDP: Overran SDP data buffer";
+ osi_free(p_cmd);
+ return;
+ }
+
+ bytes_left -= base_bytes;
+
+ /* Build the UID sequence. */
#if (SDP_BROWSE_PLUS == TRUE)
p = sdpu_build_uuid_seq(p, 1,
- &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx]);
+ &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx],
+ bytes_left);
#else
+ /* Build the UID sequence. */
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
- p_ccb->p_db->uuid_filters);
+ p_ccb->p_db->uuid_filters, bytes_left);
#endif
/* Set max service record count */
@@ -575,6 +609,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
if ((cont_request_needed) || (!p_reply)) {
BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
uint8_t* p;
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
p_msg->offset = L2CAP_MIN_OFFSET;
p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
@@ -588,13 +623,29 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
p_param_len = p;
p += 2;
-/* Build the UID sequence. */
+ /* Account for header size, max service record count and
+ * continuation state */
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
+ 3u + /* service search request header */
+ 2u + /* param len */
+ 3u + /* max service record count */
+ ((p_reply) ? (*p_reply) : 0));
+
+ if (base_bytes > bytes_left) {
+ sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
+ return;
+ }
+
+ bytes_left -= base_bytes;
+
+ /* Build the UID sequence. */
#if (SDP_BROWSE_PLUS == TRUE)
p = sdpu_build_uuid_seq(p, 1,
- &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx]);
+ &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx],
+ bytes_left);
#else
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
- p_ccb->p_db->uuid_filters);
+ p_ccb->p_db->uuid_filters, bytes_left);
#endif
/* Max attribute byte count */

View File

@ -1,82 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Tue, 21 Mar 2023 22:39:16 +0000
Subject: [PATCH] Revert "Revert "Fix wrong BR/EDR link key downgrades
(P_256->P_192)""
This reverts commit d733c86cbc06ce0ec72216b9d41e172d1939c46f.
Function btm_sec_encrypt_change() is called at most places
with argument "encr_enable" treated as bool and not as per
(tHCI_ENCRYPT_MODE = 0/1/2) expected by the function. The
function has special handling for "encr_enable=1" to downgrade
the link key type for BR/EDR case. This gets executed even
when the caller/context did not mean/expect so. It appears
this handling in btm_sec_encrypt_change() is not necessary and
is removed by this commit to prevent accidental execution of it.
Test: Verified re-pairing with an iPhone works fine now
Issue Reproduction Steps:
1. Enable Bluetooth Hotspot on Android device (DUT).
2. Pair and connect an iPhone to DUT.
3. Forget this pairing on DUT.
4. On iPhone settings, click on old DUT's paired entry to connect.
5. iPhone notifies to click 'Forget Device' and try fresh pairing.
6. On iPhone, after doing 'Forget Device', discover DUT again.
7. Attempt pairing to DUT by clicking on discovered DUT entry.
Pairing will be unsuccessful.
Issue Cause:
During re-pairing, DUT is seen to downgrade
BR/EDR link key unexpectedly from link key type 0x8
(BTM_LKEY_TYPE_AUTH_COMB_P_256) to 0x5 (BTM_LKEY_TYPE_AUTH_COMB).
Log snippet (re-pairing time):
btm_sec_link_key_notification set new_encr_key_256 to 1
btif_dm_auth_cmpl_evt: Storing link key. key_type=0x8, bond_type=1
btm_sec_encrypt_change new_encr_key_256 is 1
--On DUT, HCI_Encryption_Key_Refresh_Complete event noticed---
btm_sec_encrypt_change new_encr_key_256 is 0
updated link key type to 5
btif_dm_auth_cmpl_evt: Storing link key. key_type=0x5, bond_type=1
This is a backport of the following patch: aosp/1890096
Bug: 258834033
Reason for revert: Reinstate original change for QPR
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:56891eedc68c86b40977191dad28d65ebf86a94f)
Merged-In: Iba0c220b82bcf6b15368762b7052a3987ccbc0c6
Change-Id: Iba0c220b82bcf6b15368762b7052a3987ccbc0c6
---
stack/btm/btm_sec.cc | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 277e01dc1..3ba1a6023 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -4035,22 +4035,6 @@ void btm_sec_encrypt_change(uint16_t handle, uint8_t status,
SMP_BR_PairWith(p_dev_rec->bd_addr);
}
}
- } else {
- // BR/EDR is successfully encrypted. Correct LK type if needed
- // (BR/EDR LK derived from LE LTK was used for encryption)
- if ((encr_enable == 1) && /* encryption is ON for SSP */
- /* LK type is for BR/EDR SC */
- (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256 ||
- p_dev_rec->link_key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256)) {
- if (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256)
- p_dev_rec->link_key_type = BTM_LKEY_TYPE_UNAUTH_COMB;
- else /* BTM_LKEY_TYPE_AUTH_COMB_P_256 */
- p_dev_rec->link_key_type = BTM_LKEY_TYPE_AUTH_COMB;
-
- BTM_TRACE_DEBUG("updated link key type to %d",
- p_dev_rec->link_key_type);
- btm_send_link_key_notif(p_dev_rec);
- }
}
}

View File

@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alisher Alikhodjaev <alisher@google.com>
Date: Tue, 31 Jan 2023 19:04:09 -0800
Subject: [PATCH] OOBW in nci_snd_set_routing_cmd()
Bug: 264879662
Test: read a tag, nfc on/off
Change-Id: I408cf611fb35e9467d7484165ce48759970b158a
(cherry picked from commit 1dd4d2e1b481dd83ca2b222993fdb74ae5306c78)
Merged-In: I408cf611fb35e9467d7484165ce48759970b158a
---
src/nfc/nci/nci_hmsgs.cc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/nfc/nci/nci_hmsgs.cc b/src/nfc/nci/nci_hmsgs.cc
index 885ebaa..c191c26 100644
--- a/src/nfc/nci/nci_hmsgs.cc
+++ b/src/nfc/nci/nci_hmsgs.cc
@@ -630,6 +630,10 @@ uint8_t nci_snd_set_routing_cmd(bool more, uint8_t num_tlv, uint8_t tlv_size,
uint8_t* pp;
uint8_t size = tlv_size + 2;
+ if (size < tlv_size) {
+ return (NCI_STATUS_FAILED);
+ }
+
if (tlv_size == 0) {
/* just to terminate routing table
* 2 bytes (more=FALSE and num routing entries=0) */

View File

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alisher Alikhodjaev <alisher@google.com>
Date: Tue, 31 Jan 2023 19:04:09 -0800
Subject: [PATCH] OOBW in nci_snd_set_routing_cmd()
Bug: 264879662
Test: read a tag, nfc on/off
Change-Id: I408cf611fb35e9467d7484165ce48759970b158a
(cherry picked from commit 1dd4d2e1b481dd83ca2b222993fdb74ae5306c78)
Merged-In: I408cf611fb35e9467d7484165ce48759970b158a
---
SN100x/src/nfc/nci/nci_hmsgs.cc | 4 ++++
src/nfc/nci/nci_hmsgs.cc | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/SN100x/src/nfc/nci/nci_hmsgs.cc b/SN100x/src/nfc/nci/nci_hmsgs.cc
index 99a40a1f..e37a82b6 100755
--- a/SN100x/src/nfc/nci/nci_hmsgs.cc
+++ b/SN100x/src/nfc/nci/nci_hmsgs.cc
@@ -673,6 +673,10 @@ uint8_t nci_snd_set_routing_cmd(bool more, uint8_t num_tlv, uint8_t tlv_size,
uint8_t* pp;
uint8_t size = tlv_size + 2;
+ if (size < tlv_size) {
+ return (NCI_STATUS_FAILED);
+ }
+
if (tlv_size == 0) {
/* just to terminate routing table
* 2 bytes (more=FALSE and num routing entries=0) */
diff --git a/src/nfc/nci/nci_hmsgs.cc b/src/nfc/nci/nci_hmsgs.cc
index eedfc084..898d1446 100755
--- a/src/nfc/nci/nci_hmsgs.cc
+++ b/src/nfc/nci/nci_hmsgs.cc
@@ -727,6 +727,10 @@ uint8_t nci_snd_set_routing_cmd(bool more, uint8_t num_tlv, uint8_t tlv_size,
uint8_t* pp;
uint8_t size = tlv_size + 2;
+ if (size < tlv_size) {
+ return (NCI_STATUS_FAILED);
+ }
+
if (tlv_size == 0) {
/* just to terminate routing table
* 2 bytes (more=false and num routing entries=0) */

View File

@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alisher Alikhodjaev <alisher@google.com>
Date: Tue, 31 Jan 2023 19:04:09 -0800
Subject: [PATCH] OOBW in nci_snd_set_routing_cmd()
Bug: 264879662
Test: read a tag, nfc on/off
Change-Id: I408cf611fb35e9467d7484165ce48759970b158a
(cherry picked from commit 1dd4d2e1b481dd83ca2b222993fdb74ae5306c78)
Merged-In: I408cf611fb35e9467d7484165ce48759970b158a
---
halimpl/src/halLibnfc/src/nfc/nci/nci_hmsgs.cc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/halimpl/src/halLibnfc/src/nfc/nci/nci_hmsgs.cc b/halimpl/src/halLibnfc/src/nfc/nci/nci_hmsgs.cc
index a76ba5a..34d1d07 100755
--- a/halimpl/src/halLibnfc/src/nfc/nci/nci_hmsgs.cc
+++ b/halimpl/src/halLibnfc/src/nfc/nci/nci_hmsgs.cc
@@ -672,6 +672,10 @@ uint8_t nci_snd_set_routing_cmd(bool more, uint8_t num_tlv, uint8_t tlv_size,
uint8_t *pp;
uint8_t size = tlv_size + 2;
+ if (size < tlv_size) {
+ return (NCI_STATUS_FAILED);
+ }
+
if (tlv_size == 0) {
/* just to terminate routing table
* 2 bytes (more=false and num routing entries=0) */

View File

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Wed, 28 Dec 2022 00:32:37 +0000
Subject: [PATCH] Fix an OOB Write bug in gatt_check_write_long_terminate
this is the backport of Ifffa2c7f679c4ef72dbdb6b1f3378ca506680084
Bug: 258652631
Test: manual
Tag: #security
Ignore-AOSP-First: security
Change-Id: Ic84122f07cbc198c676d366e39606621b7cb4e66
(cherry picked from commit 9b17660bfd6f0f41cb9400ce0236d76c83605e03)
Merged-In: Ic84122f07cbc198c676d366e39606621b7cb4e66
---
stack/gatt/gatt_cl.cc | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/stack/gatt/gatt_cl.cc b/stack/gatt/gatt_cl.cc
index 73a338b6d..98186daed 100644
--- a/stack/gatt/gatt_cl.cc
+++ b/stack/gatt/gatt_cl.cc
@@ -578,7 +578,8 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
LOG(ERROR) << StringPrintf("value resp op_code = %s len = %d",
gatt_dbg_op_name(op_code), len);
- if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
+ if (len < GATT_PREP_WRITE_RSP_MIN_LEN ||
+ len > GATT_PREP_WRITE_RSP_MIN_LEN + sizeof(value.value)) {
LOG(ERROR) << "illegal prepare write response length, discard";
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
return;
@@ -587,7 +588,7 @@ void gatt_process_prep_write_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
STREAM_TO_UINT16(value.handle, p);
STREAM_TO_UINT16(value.offset, p);
- value.len = len - 4;
+ value.len = len - GATT_PREP_WRITE_RSP_MIN_LEN;
memcpy(value.value, p, value.len);

View File

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Mon, 2 Jan 2023 22:05:45 +0000
Subject: [PATCH] Fix an OOB access bug in A2DP_BuildMediaPayloadHeaderSbc
In A2DP_BuildCodecHeaderSbc when p_buf->offset is 0, the
`-=` operation on it may result in integer underflow and
OOB write with the computed pointer passed to
A2DP_BuildMediaPayloadHeaderSbc.
This is a backport of I45320085b1e458d3b0e0d86162a35aaaae7b34cb
Test: atest net_test_stack_a2dp_codecs_native
Ignore-AOSP-First: security
Tag:#security
Bug: 186803518
Change-Id: I4ff1a1de71884b8de23008b2569fdea3650e85ec
(cherry picked from commit a710300216be4a86373a65c6a685aeef8509cfa7)
Merged-In: I4ff1a1de71884b8de23008b2569fdea3650e85ec
---
stack/a2dp/a2dp_sbc.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc
index 623ecfac1..393a17ee5 100644
--- a/stack/a2dp/a2dp_sbc.cc
+++ b/stack/a2dp/a2dp_sbc.cc
@@ -881,6 +881,11 @@ bool A2DP_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t* p_codec_info,
BT_HDR* p_buf, uint16_t frames_per_packet) {
uint8_t* p;
+ // there is a timestamp right following p_buf
+ if (p_buf->offset < 4 + A2DP_SBC_MPL_HDR_LEN) {
+ return false;
+ }
+
p_buf->offset -= A2DP_SBC_MPL_HDR_LEN;
p = (uint8_t*)(p_buf + 1) + p_buf->offset;
p_buf->len += A2DP_SBC_MPL_HDR_LEN;

View File

@ -1,78 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Wed, 4 Jan 2023 22:45:13 +0000
Subject: [PATCH] Fix an OOB write in SDP_AddAttribute
When the `attr_pad` becomes full, it is possible
that un index of `-1` is computed write
a zero byte to `p_val`, rusulting OOB write.
```
p_val[SDP_MAX_PAD_LEN - p_rec->free_pad_ptr - 1] = '\0';
```
This is a backport of I937d22a2df26fca1d7f06b10182c4e713ddfed1b
Bug: 261867748
Test: manual
Tag: #security
Ignore-AOSP-First: security
Change-Id: Ibdda754e628cfc9d1706c14db114919a15d8d6b1
(cherry picked from commit cc527a97f78a2999a0156a579e488afe9e3675b2)
Merged-In: Ibdda754e628cfc9d1706c14db114919a15d8d6b1
---
stack/sdp/sdp_db.cc | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/stack/sdp/sdp_db.cc b/stack/sdp/sdp_db.cc
index 65ed52fd9..23e5b53ff 100644
--- a/stack/sdp/sdp_db.cc
+++ b/stack/sdp/sdp_db.cc
@@ -399,6 +399,11 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
uint16_t xx;
tSDP_RECORD* p_rec = &sdp_cb.server_db.record[0];
+ if (p_val == nullptr) {
+ SDP_TRACE_WARNING("Trying to add attribute with p_val == nullptr, skipped");
+ return (false);
+ }
+
if (sdp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG) {
if ((attr_type == UINT_DESC_TYPE) ||
(attr_type == TWO_COMP_INT_DESC_TYPE) ||
@@ -433,7 +438,15 @@ bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type,
/* Find the record in the database */
for (xx = 0; xx < sdp_cb.server_db.num_records; xx++, p_rec++) {
if (p_rec->record_handle == handle) {
- return SDP_AddAttributeToRecord (p_rec, attr_id, attr_type, attr_len, p_val);
+
+ // error out early, no need to look up
+ if (p_rec->free_pad_ptr >= SDP_MAX_PAD_LEN) {
+ SDP_TRACE_ERROR("the free pad for SDP record with handle %d is "
+ "full, skip adding the attribute", handle);
+ return (false);
+ } else {
+ return SDP_AddAttributeToRecord (p_rec, attr_id, attr_type, attr_len, p_val);
+ }
}
}
#endif
@@ -500,15 +513,13 @@ bool SDP_AddAttributeToRecord (tSDP_RECORD *p_rec, uint16_t attr_id,
attr_len = 0;
}
- if ((attr_len > 0) && (p_val != 0)) {
+ if (attr_len > 0) {
p_attr->len = attr_len;
memcpy(&p_rec->attr_pad[p_rec->free_pad_ptr], p_val, (size_t)attr_len);
p_attr->value_ptr = &p_rec->attr_pad[p_rec->free_pad_ptr];
p_rec->free_pad_ptr += attr_len;
- } else if ((attr_len == 0 &&
- p_attr->len !=
- 0) || /* if truncate to 0 length, simply don't add */
- p_val == 0) {
+ } else if (attr_len == 0 && p_attr->len != 0) {
+ /* if truncate to 0 length, simply don't add */
SDP_TRACE_ERROR(
"SDP_AddAttributeToRecord fail, length exceed maximum: ID %d: attr_len:%d ",
attr_id, attr_len);

View File

@ -1,100 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rocky Liao <quic_rjliao@quicinc.com>
Date: Mon, 19 Sep 2022 17:39:42 +0800
Subject: [PATCH] AVRCP: Fix potential buffer overflow
There will be buffer overflow if remote response exceeds
AVRC_MAX_APP_ATTR_SIZE, add array index check to avoid
buffer overflow issue.
CRs-fixed: 3278869
Change-Id: Ia93690e0dc4b28fd01af3a406678d43d426d3be8
---
btif/src/btif_rc.cc | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index 0b34f7c36..a0e38998f 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -5067,13 +5067,13 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
* for standard attributes.
*/
p_app_settings->num_ext_attrs = 0;
- for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
+ for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
}
p_app_settings->ext_attr_index = 0;
if (p_dev) {
- for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
+ for (xx = 0; xx < p_app_settings->num_attrs && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
attrs[xx] = p_app_settings->attrs[xx].attr_id;
}
@@ -5086,7 +5086,7 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
for (xx = 0; xx < p_rsp->num_attr; xx++) {
uint8_t x;
- for (x = 0; x < p_app_settings->num_ext_attrs; x++) {
+ for (x = 0; x < p_app_settings->num_ext_attrs && x < AVRC_MAX_APP_ATTR_SIZE; x++) {
if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) {
p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
@@ -5096,7 +5096,7 @@ static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
}
}
- for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++) {
+ for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val && xx < BTRC_MAX_APP_ATTR_SIZE; xx++) {
vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
}
get_player_app_setting_value_text_cmd(vals, xx, p_dev);
@@ -5141,11 +5141,11 @@ static void handle_app_attr_val_txt_response(
* for standard attributes.
*/
p_app_settings->num_ext_attrs = 0;
- for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
+ for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
int x;
btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
- for (x = 0; x < p_ext_attr->num_val; x++)
+ for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++)
osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
p_ext_attr->num_val = 0;
osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
@@ -5162,11 +5162,17 @@ static void handle_app_attr_val_txt_response(
return;
}
+ if (p_app_settings->ext_val_index >= AVRC_MAX_APP_ATTR_SIZE) {
+ BTIF_TRACE_ERROR("%s: ext_val_index is 0x%02x, overflow!",
+ __func__, p_app_settings->ext_val_index);
+ return;
+ }
+
for (xx = 0; xx < p_rsp->num_attr; xx++) {
uint8_t x;
btrc_player_app_ext_attr_t* p_ext_attr;
p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
- for (x = 0; x < p_rsp->num_attr; x++) {
+ for (x = 0; x < p_rsp->num_attr && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) {
p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
@@ -5204,11 +5210,11 @@ static void handle_app_attr_val_txt_response(
/* Free the application settings information after sending to
* application.
*/
- for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
+ for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
int x;
btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
- for (x = 0; x < p_ext_attr->num_val; x++)
+ for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++)
osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
p_ext_attr->num_val = 0;
osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);

View File

@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Fri, 20 Jan 2023 19:39:30 +0000
Subject: [PATCH] Fix an OOB bug in register_notification_rsp
This is a backport of I901d973a736678d7f3cc816ddf0cbbcbbd1fe93f
to rvc-dev.
Bug: 245916076
Test: manual
Ignore-AOSP-First: security
Change-Id: I37a9f45e707702b2ec52b5a2d572f177f2911765
(cherry picked from commit 901e34203c6280d414cbfa3978de04fd6515ffdf)
Merged-In: I37a9f45e707702b2ec52b5a2d572f177f2911765
---
btif/src/btif_rc.cc | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/btif/src/btif_rc.cc b/btif/src/btif_rc.cc
index a0e38998f..41fd73485 100644
--- a/btif/src/btif_rc.cc
+++ b/btif/src/btif_rc.cc
@@ -3137,6 +3137,11 @@ static bt_status_t register_notification_rsp(
dump_rc_notification_event_id(event_id));
std::unique_lock<std::mutex> lock(btif_rc_cb.lock);
+ if (event_id > MAX_RC_NOTIFICATIONS) {
+ BTIF_TRACE_ERROR("Invalid event id");
+ return BT_STATUS_PARM_INVALID;
+ }
+
memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
avrc_rsp.reg_notif.event_id = event_id;

View File

@ -1,49 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mayank Madhukar <quic_mmadhuka@quicinc.com>
Date: Thu, 14 Jul 2022 15:33:53 +0530
Subject: [PATCH] AVDTP: Fix a potential overflow about the media payload
offset
This variable is uint16, and is possible to overflow when the length of
header extension is larger. Here we compare with the data length to
prevent any exceptions.
Change-Id: If55d77132e893d6856c9f4ccc42d24a6e7cafe29
CRs-Fixed: 3237187
---
stack/avdt/avdt_scb_act.cc | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/stack/avdt/avdt_scb_act.cc b/stack/avdt/avdt_scb_act.cc
index 130f44ab1..568575458 100644
--- a/stack/avdt/avdt_scb_act.cc
+++ b/stack/avdt/avdt_scb_act.cc
@@ -277,19 +277,24 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB* p_scb, tAVDT_SCB_EVT* p_data) {
if (offset > len) goto length_error;
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
- offset += ex_len * 4;
p += ex_len * 4;
}
+ if ((p - p_start) > len) {
+ android_errorWriteLog(0x534e4554, "142546355");
+ osi_free_and_reset((void**)&p_data->p_pkt);
+ return;
+ }
+ offset = p - p_start;
+
/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
- pad_len = *(p_start + p_data->p_pkt->len);
+ pad_len = *(p_start + len);
}
/* do sanity check */
- if ((offset > p_data->p_pkt->len) ||
- ((pad_len + offset) > p_data->p_pkt->len)) {
+ if (pad_len > (len - offset)) {
AVDT_TRACE_WARNING("Got bad media packet");
osi_free_and_reset((void**)&p_data->p_pkt);
}

View File

@ -1,109 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Tue, 11 Oct 2022 21:23:22 +0000
Subject: [PATCH] Prevent use-after-free of HID reports
BTA sends the the HID report pointer to BTIF and deallocates it immediately.
This is now prevented by providing a deep copy callback function for HID
reports when tranferring context from BTA to BTIF.
This is a backport of change Icef7a7ed1185b4283ee4fe4f812ca154d8f1b825,
already merged on T for b/227620181.
Bug: 228837201
Test: Validated against researcher POC, ran BT unit tests, played audio
manually.
Tag: #security
Ignore-AOSP-First: Security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:874c495c886cd8722625756dc5fd0634b16b4f42)
Merged-In: Ib837f395883de2369207f1b3b974d6bff02dcb19
Change-Id: Ib837f395883de2369207f1b3b974d6bff02dcb19
Change-Id: I7e94dbdf4990ce8ebb03d8ffdacd4049f16873bb
---
btif/src/btif_hh.cc | 50 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 45 insertions(+), 5 deletions(-)
diff --git a/btif/src/btif_hh.cc b/btif/src/btif_hh.cc
index 1b770ddb1..b5135ff2f 100644
--- a/btif/src/btif_hh.cc
+++ b/btif/src/btif_hh.cc
@@ -1127,6 +1127,38 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
}
}
+/*******************************************************************************
+ *
+ * Function btif_hh_hsdata_rpt_copy_cb
+ *
+ * Description Deep copies the tBTA_HH_HSDATA structure
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+
+static void btif_hh_hsdata_rpt_copy_cb(uint16_t event, char* p_dest,
+ char* p_src) {
+ tBTA_HH_HSDATA* p_dst_data = (tBTA_HH_HSDATA*)p_dest;
+ tBTA_HH_HSDATA* p_src_data = (tBTA_HH_HSDATA*)p_src;
+ BT_HDR* hdr;
+
+ if (!p_src) {
+ BTIF_TRACE_ERROR("%s: Nothing to copy", __func__);
+ return;
+ }
+
+ memcpy(p_dst_data, p_src_data, sizeof(tBTA_HH_HSDATA));
+
+ hdr = p_src_data->rsp_data.p_rpt_data;
+ if (hdr != NULL) {
+ uint8_t* p_data = ((uint8_t*)p_dst_data) + sizeof(tBTA_HH_HSDATA);
+ memcpy(p_data, hdr, BT_HDR_SIZE + hdr->offset + hdr->len);
+
+ p_dst_data->rsp_data.p_rpt_data = (BT_HDR*)p_data;
+ }
+}
+
/*******************************************************************************
*
* Function bte_hh_evt
@@ -1140,6 +1172,7 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
bt_status_t status;
int param_len = 0;
+ tBTIF_COPY_CBACK* p_copy_cback = NULL;
if (BTA_HH_ENABLE_EVT == event)
param_len = sizeof(tBTA_HH_STATUS);
@@ -1151,11 +1184,18 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
param_len = sizeof(tBTA_HH_CBDATA);
else if (BTA_HH_GET_DSCP_EVT == event)
param_len = sizeof(tBTA_HH_DEV_HANDLE_DSCP_INFO);
- else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_RPT_EVT == event) ||
- (BTA_HH_GET_IDLE_EVT == event))
+ else if ((BTA_HH_GET_PROTO_EVT == event) || (BTA_HH_GET_IDLE_EVT == event))
+ param_len = sizeof(tBTA_HH_HSDATA);
+ else if (BTA_HH_GET_RPT_EVT == event) {
+ BT_HDR* hdr = p_data->hs_data.rsp_data.p_rpt_data;
param_len = sizeof(tBTA_HH_HSDATA);
- else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
- (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
+
+ if (hdr != NULL) {
+ p_copy_cback = btif_hh_hsdata_rpt_copy_cb;
+ param_len += BT_HDR_SIZE + hdr->offset + hdr->len;
+ }
+ } else if ((BTA_HH_SET_PROTO_EVT == event) || (BTA_HH_SET_RPT_EVT == event) ||
+ (BTA_HH_VC_UNPLUG_EVT == event) || (BTA_HH_SET_IDLE_EVT == event))
param_len = sizeof(tBTA_HH_CBDATA);
else if ((BTA_HH_ADD_DEV_EVT == event) || (BTA_HH_RMV_DEV_EVT == event))
param_len = sizeof(tBTA_HH_DEV_INFO);
@@ -1164,7 +1204,7 @@ void bte_hh_evt(tBTA_HH_EVT event, tBTA_HH* p_data) {
/* switch context to btif task context (copy full union size for convenience)
*/
status = btif_transfer_context(btif_hh_upstreams_evt, (uint16_t)event,
- (char*)p_data, param_len, NULL);
+ (char*)p_data, param_len, p_copy_cback);
/* catch any failed context transfers */
ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);

View File

@ -1,139 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Tue, 21 Mar 2023 22:35:08 +0000
Subject: [PATCH] Revert^2 "Validate buffer length in sdpu_build_uuid_seq"
fd2ded7341c7f867a153e86f003758808f11bfb9
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4d33899d2c0573cf351691cdf27628416621f545)
Merged-In: I40ea9f3858215f460e6dab3768e0c6d2155e4755
Change-Id: I40ea9f3858215f460e6dab3768e0c6d2155e4755
Change-Id: I41b3e52c09638f8a46a26d9527b0e114f6c8682e
---
stack/sdp/sdp_discovery.cc | 64 +++++++++++++++++++++++++++++++++-----
1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/stack/sdp/sdp_discovery.cc b/stack/sdp/sdp_discovery.cc
index ebfa510f1..14713c4b1 100644
--- a/stack/sdp/sdp_discovery.cc
+++ b/stack/sdp/sdp_discovery.cc
@@ -74,10 +74,15 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db,
*
******************************************************************************/
static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
- Uuid* p_uuid_list) {
+ Uuid* p_uuid_list, uint16_t& bytes_left) {
uint16_t xx;
uint8_t* p_len;
+ if (bytes_left < 2) {
+ DCHECK(0) << "SDP: No space for data element header";
+ return (p_out);
+ }
+
/* First thing is the data element header */
UINT8_TO_BE_STREAM(p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
@@ -85,9 +90,20 @@ static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
p_len = p_out;
p_out += 1;
+ /* Account for data element header and length */
+ bytes_left -= 2;
+
/* Now, loop through and put in all the UUID(s) */
for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
int len = p_uuid_list->GetShortestRepresentationSize();
+
+ if (len + 1 > bytes_left) {
+ DCHECK(0) << "SDP: Too many UUIDs for internal buffer";
+ break;
+ } else {
+ bytes_left -= (len + 1);
+ }
+
if (len == Uuid::kNumBytes16) {
UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
UINT16_TO_BE_STREAM(p_out, p_uuid_list->As16Bit());
@@ -124,6 +140,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
uint8_t *p, *p_start, *p_param_len;
BT_HDR* p_cmd = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
uint16_t param_len;
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
/* Prepare the buffer for sending the packet to L2CAP */
p_cmd->offset = L2CAP_MIN_OFFSET;
@@ -138,13 +155,29 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
p_param_len = p;
p += 2;
-/* Build the UID sequence. */
+ /* Account for header size, max service record count and
+ * continuation state */
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
+ 3u + /* service search request header */
+ 2u + /* param len */
+ 3u + ((p_cont) ? cont_len : 0));
+
+ if (base_bytes > bytes_left) {
+ DCHECK(0) << "SDP: Overran SDP data buffer";
+ osi_free(p_cmd);
+ return;
+ }
+
+ bytes_left -= base_bytes;
+
+ /* Build the UID sequence. */
#if (SDP_BROWSE_PLUS == TRUE)
p = sdpu_build_uuid_seq(p, 1,
- &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx]);
+ &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx],
+ bytes_left);
#else
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
- p_ccb->p_db->uuid_filters);
+ p_ccb->p_db->uuid_filters, bytes_left);
#endif
/* Set max service record count */
@@ -635,6 +668,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
if ((cont_request_needed) || (!p_reply)) {
BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
uint8_t* p;
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
p_msg->offset = L2CAP_MIN_OFFSET;
p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
@@ -648,13 +682,29 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
p_param_len = p;
p += 2;
-/* Build the UID sequence. */
+ /* Account for header size, max service record count and
+ * continuation state */
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
+ 3u + /* service search request header */
+ 2u + /* param len */
+ 3u + /* max service record count */
+ ((p_reply) ? (*p_reply) : 0));
+
+ if (base_bytes > bytes_left) {
+ sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
+ return;
+ }
+
+ bytes_left -= base_bytes;
+
+ /* Build the UID sequence. */
#if (SDP_BROWSE_PLUS == TRUE)
p = sdpu_build_uuid_seq(p, 1,
- &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx]);
+ &p_ccb->p_db->uuid_filters[p_ccb->cur_uuid_idx],
+ bytes_left);
#else
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
- p_ccb->p_db->uuid_filters);
+ p_ccb->p_db->uuid_filters, bytes_left);
#endif
/* Max attribute byte count */

View File

@ -1,93 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Tue, 21 Mar 2023 22:39:16 +0000
Subject: [PATCH] Revert "Revert "Fix wrong BR/EDR link key downgrades
(P_256->P_192)""
This reverts commit d733c86cbc06ce0ec72216b9d41e172d1939c46f.
Function btm_sec_encrypt_change() is called at most places
with argument "encr_enable" treated as bool and not as per
(tHCI_ENCRYPT_MODE = 0/1/2) expected by the function. The
function has special handling for "encr_enable=1" to downgrade
the link key type for BR/EDR case. This gets executed even
when the caller/context did not mean/expect so. It appears
this handling in btm_sec_encrypt_change() is not necessary and
is removed by this commit to prevent accidental execution of it.
Test: Verified re-pairing with an iPhone works fine now
Issue Reproduction Steps:
1. Enable Bluetooth Hotspot on Android device (DUT).
2. Pair and connect an iPhone to DUT.
3. Forget this pairing on DUT.
4. On iPhone settings, click on old DUT's paired entry to connect.
5. iPhone notifies to click 'Forget Device' and try fresh pairing.
6. On iPhone, after doing 'Forget Device', discover DUT again.
7. Attempt pairing to DUT by clicking on discovered DUT entry.
Pairing will be unsuccessful.
Issue Cause:
During re-pairing, DUT is seen to downgrade
BR/EDR link key unexpectedly from link key type 0x8
(BTM_LKEY_TYPE_AUTH_COMB_P_256) to 0x5 (BTM_LKEY_TYPE_AUTH_COMB).
Log snippet (re-pairing time):
btm_sec_link_key_notification set new_encr_key_256 to 1
btif_dm_auth_cmpl_evt: Storing link key. key_type=0x8, bond_type=1
btm_sec_encrypt_change new_encr_key_256 is 1
--On DUT, HCI_Encryption_Key_Refresh_Complete event noticed---
btm_sec_encrypt_change new_encr_key_256 is 0
updated link key type to 5
btif_dm_auth_cmpl_evt: Storing link key. key_type=0x5, bond_type=1
This is a backport of the following patch: aosp/1890096
Bug: 258834033
Reason for revert: Reinstate original change for QPR
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:56891eedc68c86b40977191dad28d65ebf86a94f)
Merged-In: Iba0c220b82bcf6b15368762b7052a3987ccbc0c6
Change-Id: Iba0c220b82bcf6b15368762b7052a3987ccbc0c6
Change-Id: Ic5130971306864e5bd2a590f238175c9545a297a
---
stack/btm/btm_sec.cc | 25 -------------------------
1 file changed, 25 deletions(-)
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 2e4c0c196..40f051c0d 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -4303,31 +4303,6 @@ void btm_sec_encrypt_change(uint16_t handle, uint8_t status,
SMP_BR_PairWith(p_dev_rec->bd_addr);
}
}
- } else {
- // BR/EDR is successfully encrypted. Correct LK type if needed
- // (BR/EDR LK derived from LE LTK was used for encryption)
- if ((encr_enable == 1) && /* encryption is ON for SSP */
- /* LK type is for BR/EDR SC */
- (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256 ||
- p_dev_rec->link_key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256)) {
- if (p_dev_rec->sec_smp_pair_pending != BTM_SEC_SMP_PAIR_PENDING) {
- if (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256)
- p_dev_rec->link_key_type = BTM_LKEY_TYPE_UNAUTH_COMB;
- else /* BTM_LKEY_TYPE_AUTH_COMB_P_256 */
- p_dev_rec->link_key_type = BTM_LKEY_TYPE_AUTH_COMB;
-
- BTM_TRACE_DEBUG("updated link key type to %d",
- p_dev_rec->link_key_type);
- btm_send_link_key_notif(p_dev_rec);
- } else {
- BTM_TRACE_DEBUG("link key type to %d will update after SMP",
- p_dev_rec->link_key_type);
- if (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB_P_256)
- p_dev_rec->sec_smp_pair_pending |= BTM_SEC_LINK_KEY_TYPE_UNAUTH;
- else
- p_dev_rec->sec_smp_pair_pending |= BTM_SEC_LINK_KEY_TYPE_AUTH;
- }
- }
}
}

View File

@ -108,7 +108,7 @@ patchWorkspaceReal() {
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
source build/envsetup.sh;
repopick -it tzdb_N;
repopick -fit tzdb_N;
sh "$DOS_SCRIPTS/Patch.sh";
sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh";

View File

@ -77,20 +77,20 @@ patchWorkspaceReal() {
source build/envsetup.sh;
#repopick -it pie-firewall;
#repopick cannot handle empty commits
repopick -it P_asb_2022-05 -e 341484;
repopick -it P_asb_2022-06 -e 342112;
repopick -it P_asb_2022-07 -e 342113;
repopick -it P_asb_2022-08 -e 342114;
repopick -it P_asb_2022-09 -e 342116;
repopick -it P_asb_2022-10 -e 342119;
repopick -it P_tzdata_2022;
repopick -it P_asb_2022-11 -e 344200;
repopick -it P_asb_2022-12 -e 345931;
repopick -it P_asb_2023-01 -e 347129;
repopick -it P_asb_2023-02 -e 349337;
repopick -it P_asb_2023-03;
repopick -it P_asb_2023-04;
repopick -it P_asb_2023-05;
repopick -fit P_asb_2022-05 -e 341484;
repopick -fit P_asb_2022-06 -e 342112;
repopick -fit P_asb_2022-07 -e 342113;
repopick -fit P_asb_2022-08 -e 342114;
repopick -fit P_asb_2022-09 -e 342116;
repopick -fit P_asb_2022-10 -e 342119;
repopick -fit P_tzdata_2022;
repopick -fit P_asb_2022-11 -e 344200;
repopick -fit P_asb_2022-12 -e 345931;
repopick -fit P_asb_2023-01 -e 347129;
repopick -fit P_asb_2023-02 -e 349337;
repopick -fit P_asb_2023-03;
repopick -fit P_asb_2023-04;
repopick -fit P_asb_2023-05;
sh "$DOS_SCRIPTS/Patch.sh";
sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh";

View File

@ -77,8 +77,12 @@ patchWorkspaceReal() {
verifyAllPlatformTags;
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
#source build/envsetup.sh;
source build/envsetup.sh;
#repopick -it ten-firewall;
repopick -fit Q_asb_2023-03;
repopick -fit Q_asb_2023-04;
repopick -fit Q_asb_2023-05;
repopick -fit Q_asb_2023-06;
sh "$DOS_SCRIPTS/Patch.sh";
sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh";

View File

@ -97,7 +97,6 @@ sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aap
awk -i inplace '!/updatable_apex.mk/' target/product/mainline_system.mk; #Disable APEX
sed -i 's/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 23/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 28/' core/version_defaults.mk; #Set the minimum supported target SDK to Pie (GrapheneOS)
#sed -i 's/PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := true/PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := false/' core/product_config.mk; #broken by hardenDefconfig
sed -i 's/2023-02-05/2023-06-05/' core/version_defaults.mk; #Bump Security String #Q_asb_2023-06 #XXX
fi;
if enterAndClear "build/soong"; then
@ -133,42 +132,10 @@ awk -i inplace '!/deletePackage/' pico/src/com/svox/pico/LangPackUninstaller.jav
fi;
if enterAndClear "external/zlib"; then
applyPatch "$DOS_PATCHES/android_external_zlib/351107.patch"; #n-asb-2023-03 Fix a bug when getting a gzip header extra field with inflate().
fi;
if enterAndClear "frameworks/av"; then
applyPatch "$DOS_PATCHES/android_frameworks_av/358555.patch"; #R_asb_2023-06 Fix NuMediaExtractor::readSampleData buffer Handling
git fetch https://github.com/LineageOS/android_external_zlib refs/changes/70/352570/1 && git cherry-pick FETCH_HEAD; #Q_asb_2023-03
fi;
if enterAndClear "frameworks/base"; then
applyPatch "$DOS_PATCHES/android_frameworks_base/351411-backport.patch"; #R_asb_2023-03 Move service initialization
applyPatch "$DOS_PATCHES/android_frameworks_base/351412.patch"; #R_asb_2023-03 Stop managed profile owner granting READ_SMS
applyPatch "$DOS_PATCHES/android_frameworks_base/351413-backport.patch"; #R_asb_2023-03 Enable user graularity for lockdown mode #XXX
applyPatch "$DOS_PATCHES/android_frameworks_base/351414-backport.patch"; #R_asb_2023-03 Revoke dev perm if app is upgrading to post 23 and perm has pre23 flag #XXX
applyPatch "$DOS_PATCHES/android_frameworks_base/351415.patch"; #R_asb_2023-03 Reconcile WorkSource parcel and unparcel code.
applyPatch "$DOS_PATCHES/android_frameworks_base/351436.patch"; #R_asb_2023-03 Revert "Ensure that only SysUI can override pending intent launch flags"
applyPatch "$DOS_PATCHES/android_frameworks_base/352555.patch"; #Q_asb_2023-03 Revert "[RESTRICT AUTOMERGE] Trim the activity info of another uid if no privilege"
applyPatch "$DOS_PATCHES/android_frameworks_base/353117.patch"; #Q_asb_2023-03 Fix sharing to another profile where an app has multiple targets
applyPatch "$DOS_PATCHES/android_frameworks_base/353944.patch"; #R_asb_2023-04 Context#startInstrumentation could be started from SHELL only now.
applyPatch "$DOS_PATCHES/android_frameworks_base/353945.patch"; #R_asb_2023-04 Checking if package belongs to UID before registering broadcast receiver
applyPatch "$DOS_PATCHES/android_frameworks_base/353946.patch"; #R_asb_2023-04 Fix checkKeyIntentParceledCorrectly's bypass
applyPatch "$DOS_PATCHES/android_frameworks_base/353947.patch"; #R_asb_2023-04 Encode Intent scheme when serializing to URI string
applyPatch "$DOS_PATCHES/android_frameworks_base/353948-backport.patch"; #R_asb_2023-04 Backport BAL restrictions from S to R, this blocks apps from using AlarmManager to bypass BAL restrictions.
applyPatch "$DOS_PATCHES/android_frameworks_base/353949-backport.patch"; #R_asb_2023-04 Strip part of the activity info of another uid if no privilege
applyPatch "$DOS_PATCHES/android_frameworks_base/353950-backport.patch"; #R_asb_2023-04 Add a limit on channel group creation
applyPatch "$DOS_PATCHES/android_frameworks_base/353951-backport.patch"; #R_asb_2023-04 Fix bypass BG-FGS and BAL via package manager APIs #XXX
applyPatch "$DOS_PATCHES/android_frameworks_base/355763-backport.patch"; #R_asb_2023-05 [pm] Prevent system app downgrades of versions lower than preload #XXX: really should have next patch
applyPatch "$DOS_PATCHES/android_frameworks_base/355764.patch"; #R_asb_2023-05 [pm] Still allow debuggable for system app downgrades
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/355766-backport.patch"; #R_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/358556.patch"; #R_asb_2023-06 Remove Activity if it enters PiP without window #TODO: needs backport of findMainWindow
applyPatch "$DOS_PATCHES/android_frameworks_base/358557.patch"; #R_asb_2023-06 Prevent sharesheet from previewing unowned URIs
applyPatch "$DOS_PATCHES/android_frameworks_base/358560.patch"; #R_asb_2023-06 Check key intent for selectors and prohibited flags
applyPatch "$DOS_PATCHES/android_frameworks_base/358561-backport.patch"; #R_asb_2023-06 Handle invalid data during job loading.
applyPatch "$DOS_PATCHES/android_frameworks_base/358562-backport.patch"; #R_asb_2023-06 Allow filtering of services
#applyPatch "$DOS_PATCHES/android_frameworks_base/358564-backport.patch"; #R_asb_2023-06 Add BubbleMetadata detection to block FSI #TODO: needs backport of getSbn
applyPatch "$DOS_PATCHES/android_frameworks_base/358732-backport.patch"; #n-asb-2023-06 Prevent RemoteViews crashing SystemUi
#applyPatch "$DOS_PATCHES/android_frameworks_base/272645.patch"; #ten-bt-sbc-hd-dualchannel: Add CHANNEL_MODE_DUAL_CHANNEL constant (ValdikSS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/272646-forwardport.patch"; #ten-bt-sbc-hd-dualchannel: Add Dual Channel into Bluetooth Audio Channel Mode developer options menu (ValdikSS)
#applyPatch "$DOS_PATCHES/android_frameworks_base/272647.patch"; #ten-bt-sbc-hd-dualchannel: Allow SBC as HD audio codec in Bluetooth device configuration (ValdikSS)
@ -228,10 +195,6 @@ rm -rf packages/PrintRecommendationService; #Creates popups to install proprieta
fi;
if enterAndClear "frameworks/native"; then
applyPatch "$DOS_PATCHES/android_frameworks_native/353953-backport.patch"; #R_asb_2023-04 Mitigate the security vulnerability by sanitizing the transaction flags.
applyPatch "$DOS_PATCHES/android_frameworks_native/355772.patch"; #R_asb_2023-05 Check for malformed Sensor Flattenable
applyPatch "$DOS_PATCHES/android_frameworks_native/355773.patch"; #R_asb_2023-05 Remove some new memory leaks from SensorManager
applyPatch "$DOS_PATCHES/android_frameworks_native/355774.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;
@ -242,7 +205,6 @@ fi;
fi;
if enterAndClear "frameworks/opt/net/wifi"; then
#applyPatch "$DOS_PATCHES/android_frameworks_opt_net_wifi/351437-backport.patch"; #R_asb_2023-03 Revert "[DO NOT MERGE] wifi: remove certificates for network factory reset" #XXX: reverted in R_asb_2023-04
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_opt_net_wifi/0001-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
applyPatch "$DOS_PATCHES/android_frameworks_opt_net_wifi/0002-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS)
fi;
@ -308,10 +270,6 @@ if enterAndClear "packages/apps/Bluetooth"; then
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_packages_apps_Bluetooth/0001-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
fi;
if enterAndClear "packages/apps/Car/Settings"; then
applyPatch "$DOS_PATCHES/android_packages_apps_Car_Settings/358565-backport.patch"; #R_asb_2023-06 Convert argument to Intent in car settings AddAccountActivity.
fi;
#if enterAndClear "packages/apps/CarrierConfig"; then
#rm -rf assets/*.xml;
#cp $DOS_PATCHES_COMMON/android_packages_apps_CarrierConfig/*.xml assets/;
@ -340,7 +298,6 @@ if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_pa
fi;
if enterAndClear "packages/apps/PermissionController"; then
applyPatch "$DOS_PATCHES/android_packages_apps_PermissionController/351439-backport.patch"; #R_asb_2023-03 Stop managed profile owner granting READ_SMS
applyPatch "$DOS_PATCHES/android_packages_apps_PermissionController/0001-Network_Permission-1.patch"; #Always treat INTERNET as a runtime permission (GrapheneOS)
applyPatch "$DOS_PATCHES/android_packages_apps_PermissionController/0001-Network_Permission-2.patch"; #Add INTERNET permission toggle (GrapheneOS)
applyPatch "$DOS_PATCHES/android_packages_apps_PermissionController/0001-Sensors_Permission-1.patch"; #Always treat OTHER_SENSORS as a runtime permission (GrapheneOS)
@ -349,12 +306,6 @@ fi;
if enterAndClear "packages/apps/Settings"; then
git revert --no-edit 486980cfecce2ca64267f41462f9371486308e9d; #Don't hide OEM unlock
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/351440-backport.patch"; #R_asb_2023-03 FRP bypass defense in the settings app
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/351441.patch"; #R_asb_2023-03 Add DISALLOW_APPS_CONTROL check into uninstall app for all users
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/353956.patch"; #R_asb_2023-04 Only primary user is allowed to control secure nfc
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/358566.patch"; #R_asb_2023-06 Move display of VPN version into summary text
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/358567-backport.patch"; #R_asb_2023-06 Import translations.
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/358568-backport.patch"; #R_asb_2023-06 Convert argument to intent in AddAccountSettings.
#applyPatch "$DOS_PATCHES/android_packages_apps_Settings/272651.patch"; #ten-bt-sbc-hd-dualchannel: Add Dual Channel into Bluetooth Audio Channel Mode developer options menu (ValdikSS)
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0001-Captive_Portal_Toggle.patch"; #Add option to disable captive portal checks (MSe1969)
#applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0001-Captive_Portal_Toggle-gos.patch"; #Add option to disable captive portal checks (GrapheneOS) #FIXME: needs work
@ -382,10 +333,6 @@ if enterAndClear "packages/apps/Trebuchet"; then
cp $DOS_BUILD_BASE/vendor/divested/overlay/common/packages/apps/Trebuchet/res/xml/default_workspace_*.xml res/xml/; #XXX: Likely no longer needed
fi;
if enterAndClear "packages/apps/TvSettings"; then
applyPatch "$DOS_PATCHES/android_packages_apps_TvSettings/358578.patch"; #R_asb_2023-06 Convert argument to intent in addAccount TvSettings.
fi;
if enterAndClear "packages/apps/Updater"; then
applyPatch "$DOS_PATCHES/android_packages_apps_Updater/0001-Server.patch"; #Switch to our server (DivestOS)
applyPatch "$DOS_PATCHES/android_packages_apps_Updater/0002-Tor_Support.patch"; #Add Tor support (DivestOS)
@ -406,34 +353,15 @@ if enterAndClear "packages/providers/DownloadProvider"; then
applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Network_Permission.patch"; #Expose the NETWORK permission (GrapheneOS)
fi;
if enterAndClear "packages/providers/MediaProvider"; then
applyPatch "$DOS_PATCHES/android_packages_providers_MediaProvider/353957-backport.patch"; #R_asb_2023-04 Canonicalise path before extracting relative path
fi;
#if enterAndClear "packages/providers/TelephonyProvider"; then
#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/353958-backport.patch"; #R_asb_2023-04 Ensure service unbind when receiving a null call screening service in onBind.
applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/353959.patch"; #R_asb_2023-04 Do not process content uri in call Intents
applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/355777-backport.patch"; #R_asb_2023-05 enforce stricter rules when registering phoneAccounts
applyPatch "$DOS_PATCHES/android_packages_services_Telecomm/358579-backport.patch"; #R_asb_2023-06 Call Redirection: unbind service when onBind returns null
fi;
if enterAndClear "prebuilts/abi-dumps/vndk"; then
applyPatch "$DOS_PATCHES/android_prebuilts_abi-dumps_vndk/0001-protobuf-avi.patch"; #Work around ABI changes from compiler hardening (GrapheneOS)
fi;
if enterAndClear "system/bt"; then
applyPatch "$DOS_PATCHES/android_system_bt/351443.patch"; #R_asb_2023-03 Fix an OOB Write bug in gatt_check_write_long_terminate
applyPatch "$DOS_PATCHES/android_system_bt/351444.patch"; #R_asb_2023-03 Fix an OOB access bug in A2DP_BuildMediaPayloadHeaderSbc
applyPatch "$DOS_PATCHES/android_system_bt/351445.patch"; #R_asb_2023-03 Fix an OOB write in SDP_AddAttribute
applyPatch "$DOS_PATCHES/android_system_bt/353960.patch"; #R_asb_2023-04 Fix OOB access in avdt_scb_hdl_pkt_no_frag
applyPatch "$DOS_PATCHES/android_system_bt/353961.patch"; #R_asb_2023-04 Fix an OOB bug in register_notification_rsp
applyPatch "$DOS_PATCHES/android_system_bt/358580.patch"; #R_asb_2023-06 Prevent use-after-free of HID reports
applyPatch "$DOS_PATCHES/android_system_bt/358581.patch"; #R_asb_2023-06 Revert "Revert "[RESTRICT AUTOMERGE] Validate buffer length in sdpu_build_uuid_seq""
applyPatch "$DOS_PATCHES/android_system_bt/358582.patch"; #R_asb_2023-06 Revert "Revert "Fix wrong BR/EDR link key downgrades (P_256->P_192)""
applyPatch "$DOS_PATCHES_COMMON/android_system_bt/0001-alloc_size.patch"; #Add alloc_size attributes to the allocator (GrapheneOS)
#applyPatch "$DOS_PATCHES/android_system_bt/272648.patch"; #ten-bt-sbc-hd-dualchannel: Increase maximum Bluetooth SBC codec bitrate for SBC HD (ValdikSS)
#applyPatch "$DOS_PATCHES/android_system_bt/272649.patch"; #ten-bt-sbc-hd-dualchannel: Explicit SBC Dual Channel (SBC HD) support (ValdikSS)
@ -459,18 +387,6 @@ applyPatch "$DOS_PATCHES/android_system_netd/0001-Network_Permission.patch"; #Ex
applyPatch "$DOS_PATCHES/android_system_netd/0002-hosts_toggle.patch"; #Add a toggle to disable /etc/hosts lookup (DivestOS)
fi;
if enterAndClear "system/nfc"; then
applyPatch "$DOS_PATCHES/android_system_nfc/353962.patch"; #R_asb_2023-04 OOBW in nci_snd_set_routing_cmd()
fi;
if enterAndClear "vendor/nxp/opensource/commonsys/external/libnfc-nci"; then
applyPatch "$DOS_PATCHES/android_vendor_nxp_opensource_commonsys_external_libnfc-nci/353963.patch"; #R_asb_2023-04 OOBW in nci_snd_set_routing_cmd()
fi;
if enterAndClear "vendor/nxp/opensource/pn5xx/halimpl"; then
applyPatch "$DOS_PATCHES/android_vendor_nxp_opensource_pn5xx_halimpl/353964.patch"; #R_asb_2023-04 OOBW in nci_snd_set_routing_cmd()
fi;
if enterAndClear "system/sepolicy"; then
applyPatch "$DOS_PATCHES/android_system_sepolicy/0002-protected_files.patch"; #label protected_{fifos,regular} as proc_security (GrapheneOS)
applyPatch "$DOS_PATCHES/android_system_sepolicy/0003-ptrace_scope-1.patch"; #Allow init to control kernel.yama.ptrace_scope (GrapheneOS)
@ -510,18 +426,6 @@ if enter "vendor/divested"; then
echo "PRODUCT_PACKAGES += vendor.lineage.trust@1.0-service" >> packages.mk; #Add deny usb service, all of our kernels have the necessary patch
awk -i inplace '!/speed-profile/' build/target/product/lowram.mk; #breaks compile on some dexpreopt devices
fi;
if enterAndClear "vendor/qcom/opensource/commonsys/system/bt"; then
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/351448.patch"; #R_asb_2023-03 Fix an OOB Write bug in gatt_check_write_long_terminate
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/351449.patch"; #R_asb_2023-03 Fix an OOB access bug in A2DP_BuildMediaPayloadHeaderSbc
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/351450.patch"; #R_asb_2023-03 Fix an OOB write in SDP_AddAttribute
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/351451.patch"; #R_asb_2023-03 AVRCP: Fix potential buffer overflow
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/353967.patch"; #R_asb_2023-04 Fix an OOB bug in register_notification_rsp
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/353968.patch"; #R_asb_2023-04 AVDTP: Fix a potential overflow about the media payload offset
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/358583.patch"; #R_asb_2023-06 Prevent use-after-free of HID reports
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/358584.patch"; #R_asb_2023-06 Revert^2 "Validate buffer length in sdpu_build_uuid_seq"
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/358585.patch"; #R_asb_2023-06 Revert "Revert "Fix wrong BR/EDR link key downgrades (P_256->P_192)""
fi;
#
#END OF ROM CHANGES
#

View File

@ -114,11 +114,10 @@ patchWorkspaceReal() {
verifyAllPlatformTags;
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
source build/envsetup.sh;
#source build/envsetup.sh;
#repopick -it eleven-firewall;
#repopick -i 314453; #TaskViewTouchController: Null check current animation on drag
#repopick -i 325011; #lineage: Opt-in to shipping full recovery image by default
repopick -it R_asb_2023-06;
sh "$DOS_SCRIPTS/Patch.sh";
sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh";

View File

@ -88,10 +88,9 @@ patchWorkspaceReal() {
verifyAllPlatformTags;
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
source build/envsetup.sh;
#source build/envsetup.sh;
#repopick -ift twelve-bt-sbc-hd-dualchannel;
#repopick -it twelve-colors;
repopick -it S_asb_2023-06;
sh "$DOS_SCRIPTS/Patch.sh";
sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh";