mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
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:
parent
a07133a064
commit
41e2669884
@ -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;
|
||||
}
|
||||
|
@ -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.
|
@ -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.
|
@ -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, it’s 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 user’s 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);
|
||||
}
|
||||
}
|
@ -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);
|
@ -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 {
|
@ -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
|
@ -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.
|
||||
*/
|
@ -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 {
|
@ -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;
|
@ -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);
|
@ -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)) {
|
@ -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(';');
|
@ -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;
|
||||
}
|
@ -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.
|
||||
*/
|
@ -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));
|
||||
+ }
|
||||
}
|
@ -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) {
|
||||
}
|
||||
}
|
@ -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;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
@ -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");
|
@ -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.
|
||||
*/
|
@ -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();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
@ -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/");
|
@ -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 {
|
@ -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");
|
@ -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
|
@ -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) {
|
@ -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);
|
||||
+ }
|
||||
+ }
|
||||
}
|
@ -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,
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
@ -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.
|
@ -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();
|
@ -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);
|
@ -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);
|
||||
+ }
|
||||
+}
|
@ -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();
|
||||
+ }
|
||||
+}
|
@ -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(
|
@ -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;
|
@ -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();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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) {
|
@ -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);
|
@ -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('/');
|
@ -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();
|
||||
}
|
@ -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() {
|
@ -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,
|
@ -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));
|
||||
+ }
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
@ -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);
|
@ -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);
|
||||
}
|
@ -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;
|
@ -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);
|
@ -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 */
|
@ -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);
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
@ -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) */
|
@ -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) */
|
@ -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) */
|
@ -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);
|
||||
|
@ -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;
|
@ -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);
|
@ -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);
|
@ -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;
|
@ -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);
|
||||
}
|
@ -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);
|
@ -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 */
|
@ -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;
|
||||
- }
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user