Reconcile picks

Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
Tavi 2024-07-14 16:09:25 -04:00
parent 7182e4d63a
commit 30b658da98
No known key found for this signature in database
GPG Key ID: E599F62ECBAEAF2E
21 changed files with 5 additions and 2018 deletions

View File

@ -132,7 +132,7 @@ index ed9b539c05df..83cc7a251ebf 100644
|| newPkg.isForceQueryable() || newPkg.isForceQueryable()
|| ArrayUtils.contains(mForceQueryableByDevicePackageNames, || ArrayUtils.contains(mForceQueryableByDevicePackageNames,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e637dcf531f0..80eaaba933d2 100644 index 251d5a04f8ee..e0cd8fbbe31a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java --- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -552,6 +552,14 @@ public class PackageManagerService extends IPackageManager.Stub @@ -552,6 +552,14 @@ public class PackageManagerService extends IPackageManager.Stub

View File

@ -1,13 +0,0 @@
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index bb8fa9e..6b836ad 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -148,7 +148,7 @@
/** @hide */
public void setSkipPrompt(boolean value) {
- mSkipPrompt = true;
+ mSkipPrompt = value;
}
/** @hide */

View File

@ -1,82 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bishoy Gendy <bishoygendy@google.com>
Date: Thu, 11 Apr 2024 16:37:10 +0000
Subject: [PATCH] Fix security vulnerability allowing apps to start from
background
Bug: 317048338
Test: Using the steps in b/317048338#comment12
(cherry picked from commit c5fc8ea92c0aabbb2fdccc23b743c18a8bf62e64)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df3584bb93ab89d7e174f7d39e42d4b22cb92fe0)
Merged-In: Ia91199fdb23beed27bde687fdca8fe5d3a5a4759
Change-Id: Ia91199fdb23beed27bde687fdca8fe5d3a5a4759
---
.../media/session/ParcelableListBinder.java | 13 +++++++++++--
.../android/server/media/MediaSessionRecord.java | 14 ++++++++------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/media/java/android/media/session/ParcelableListBinder.java b/media/java/android/media/session/ParcelableListBinder.java
index bbf1e0889b68..d78828462b1e 100644
--- a/media/java/android/media/session/ParcelableListBinder.java
+++ b/media/java/android/media/session/ParcelableListBinder.java
@@ -45,6 +45,7 @@ public class ParcelableListBinder<T extends Parcelable> extends Binder {
private static final int END_OF_PARCEL = 0;
private static final int ITEM_CONTINUED = 1;
+ private final Class<T> mListElementsClass;
private final Consumer<List<T>> mConsumer;
private final Object mLock = new Object();
@@ -61,9 +62,11 @@ public class ParcelableListBinder<T extends Parcelable> extends Binder {
/**
* Creates an instance.
*
+ * @param listElementsClass the class of the list elements.
* @param consumer a consumer that consumes the list received
*/
- public ParcelableListBinder(@NonNull Consumer<List<T>> consumer) {
+ public ParcelableListBinder(Class<T> listElementsClass, @NonNull Consumer<List<T>> consumer) {
+ mListElementsClass = listElementsClass;
mConsumer = consumer;
}
@@ -83,7 +86,13 @@ public class ParcelableListBinder<T extends Parcelable> extends Binder {
mCount = data.readInt();
}
while (i < mCount && data.readInt() != END_OF_PARCEL) {
- mList.add(data.readParcelable(null));
+ Object object = data.readParcelable(null);
+ if (mListElementsClass.isAssignableFrom(object.getClass())) {
+ // Checking list items are of compaitible types to validate against malicious
+ // apps calling it directly via reflection with non compilable items.
+ // See b/317048338 for more details
+ mList.add((T) object);
+ }
i++;
}
if (i >= mCount) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 66adbad5372e..a0679d7457a0 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -1095,12 +1095,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
@Override
public IBinder getBinderForSetQueue() throws RemoteException {
- return new ParcelableListBinder<QueueItem>((list) -> {
- synchronized (mLock) {
- mQueue = list;
- }
- mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
- });
+ return new ParcelableListBinder<QueueItem>(
+ QueueItem.class,
+ (list) -> {
+ synchronized (mLock) {
+ mQueue = list;
+ }
+ mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
+ });
}
@Override

View File

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yi-an Chen <theianchen@google.com>
Date: Tue, 23 Apr 2024 21:17:44 +0000
Subject: [PATCH] Fix security vulnerability of non-dynamic permission removal
The original removePermission() code in PermissionManagerServiceImpl
missed a logical negation operator when handling non-dynamic
permissions, causing both
testPermissionPermission_nonDynamicPermission_permissionUnchanged and
testRemovePermission_dynamicPermission_permissionRemoved tests in
DynamicPermissionsTest to fail.
The corresponding test DynamicPermissionsTest is also updated in the
other CL: ag/27073864
Bug: 321711213
Test: DynamicPermissionsTest on sc-dev and tm-dev locally
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0ead58f69f5de82b00406316b333366d556239f1)
Merged-In: Ia146d4098643d9c473f8c83d33a8a125a53101fc
Change-Id: Ia146d4098643d9c473f8c83d33a8a125a53101fc
---
.../android/server/pm/permission/PermissionManagerService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 31babe0418b8..93f9e1c2295c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -687,7 +687,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (bp == null) {
return;
}
- if (bp.isDynamic()) {
+ if (!bp.isDynamic()) {
// TODO: switch this back to SecurityException
Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
+ permName);

View File

@ -1,175 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Martijn Coenen <maco@google.com>
Date: Thu, 29 Feb 2024 12:03:05 +0000
Subject: [PATCH] Verify UID of incoming Zygote connections.
Only the system UID should be allowed to connect to the Zygote. While
for generic Zygotes this is also covered by SELinux policy, this is not
true for App Zygotes: the preload code running in an app zygote could
connect to another app zygote socket, if it had access to its (random)
socket address.
On the Java layer, simply check the UID when the connection is made. In
the native layer, this check was already present, but it actually didn't
work in the case where we receive a new incoming connection on the
socket, and receive a 'non-fork' command: in that case, we will simply
exit the native loop, and let the Java layer handle the command, without
any further UID checking.
Modified the native logic to drop new connections with a mismatching
UID, and to keep serving the existing connection (if it was still
there).
Bug: 319081336
Test: manual
(cherry picked from commit 2ffc7cb220e4220b7e108c4043a3f0f2a85b6508)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f1d4b34ad51b6ccb84ab042486923da8b2451e0f)
Merged-In: I3f85a17107849e2cd3e82d6ef15c90b9e2f26532
Change-Id: I3f85a17107849e2cd3e82d6ef15c90b9e2f26532
---
.../android/internal/os/ZygoteConnection.java | 3 +
...ndroid_internal_os_ZygoteCommandBuffer.cpp | 81 ++++++++++++-------
2 files changed, 56 insertions(+), 28 deletions(-)
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 993e4e7b4b3d..765901a043a0 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -93,6 +93,9 @@ class ZygoteConnection {
throw ex;
}
+ if (peer.getUid() != Process.SYSTEM_UID) {
+ throw new ZygoteSecurityException("Only system UID is allowed to connect to Zygote.");
+ }
isEof = false;
}
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 248db76da71d..1ad64d58b7c9 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -341,6 +341,18 @@ jstring com_android_internal_os_ZygoteCommandBuffer_nativeNextArg(JNIEnv* env, j
return result;
}
+static uid_t getSocketPeerUid(int socket, const std::function<void(const std::string&)>& fail_fn) {
+ struct ucred credentials;
+ socklen_t cred_size = sizeof credentials;
+ if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
+ || cred_size != sizeof credentials) {
+ fail_fn(CREATE_ERROR("Failed to get socket credentials, %s",
+ strerror(errno)));
+ }
+
+ return credentials.uid;
+}
+
// Read all lines from the current command into the buffer, and then reset the buffer, so
// we will start reading again at the beginning of the command, starting with the argument
// count. And we don't need access to the fd to do so.
@@ -398,18 +410,12 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
fail_fn_z("Failed to retrieve session socket timeout");
}
- struct ucred credentials;
- socklen_t cred_size = sizeof credentials;
- if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
- || cred_size != sizeof credentials) {
- fail_fn_1(CREATE_ERROR("ForkMany failed to get initial credentials, %s", strerror(errno)));
+ uid_t peerUid = getSocketPeerUid(session_socket, fail_fn_1);
+ if (peerUid != static_cast<uid_t>(expected_uid)) {
+ return JNI_FALSE;
}
-
bool first_time = true;
do {
- if (credentials.uid != expected_uid) {
- return JNI_FALSE;
- }
n_buffer->readAllLines(first_time ? fail_fn_1 : fail_fn_n);
n_buffer->reset();
int pid = zygote::forkApp(env, /* no pipe FDs */ -1, -1, session_socket_fds,
@@ -439,30 +445,56 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
// Clear buffer and get count from next command.
n_buffer->clear();
for (;;) {
+ bool valid_session_socket = true;
// Poll isn't strictly necessary for now. But without it, disconnect is hard to detect.
int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */));
if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) {
if (n_buffer->getCount(fail_fn_z) != 0) {
break;
- } // else disconnected;
+ } else {
+ // Session socket was disconnected
+ valid_session_socket = false;
+ close(session_socket);
+ }
} else if (poll_res == 0 || (fd_structs[ZYGOTE_IDX].revents & POLLIN) == 0) {
fail_fn_z(
CREATE_ERROR("Poll returned with no descriptors ready! Poll returned %d", poll_res));
}
- // We've now seen either a disconnect or connect request.
- close(session_socket);
- int new_fd = TEMP_FAILURE_RETRY(accept(zygote_socket_fd, nullptr, nullptr));
+ int new_fd = -1;
+ do {
+ // We've now seen either a disconnect or connect request.
+ new_fd = TEMP_FAILURE_RETRY(accept(zygote_socket_fd, nullptr, nullptr));
+ if (new_fd == -1) {
+ fail_fn_z(CREATE_ERROR("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno)));
+ }
+ uid_t newPeerUid = getSocketPeerUid(new_fd, fail_fn_1);
+ if (newPeerUid != static_cast<uid_t>(expected_uid)) {
+ ALOGW("Dropping new connection with a mismatched uid %d\n", newPeerUid);
+ close(new_fd);
+ new_fd = -1;
+ } else {
+ // If we still have a valid session socket, close it now
+ if (valid_session_socket) {
+ close(session_socket);
+ }
+ valid_session_socket = true;
+ }
+ } while (!valid_session_socket);
+
+ // At this point we either have a valid new connection (new_fd > 0), or
+ // an existing session socket we can poll on
if (new_fd == -1) {
- fail_fn_z(CREATE_ERROR("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno)));
+ // The new connection wasn't valid, and we still have an old one; retry polling
+ continue;
}
if (new_fd != session_socket) {
- // Move new_fd back to the old value, so that we don't have to change Java-level data
- // structures to reflect a change. This implicitly closes the old one.
- if (TEMP_FAILURE_RETRY(dup2(new_fd, session_socket)) != session_socket) {
- fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s",
- new_fd, session_socket, strerror(errno)));
- }
- close(new_fd); // On Linux, fd is closed even if EINTR is returned.
+ // Move new_fd back to the old value, so that we don't have to change Java-level data
+ // structures to reflect a change. This implicitly closes the old one.
+ if (TEMP_FAILURE_RETRY(dup2(new_fd, session_socket)) != session_socket) {
+ fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s",
+ new_fd, session_socket, strerror(errno)));
+ }
+ close(new_fd); // On Linux, fd is closed even if EINTR is returned.
}
// If we ever return, we effectively reuse the old Java ZygoteConnection.
// None of its state needs to change.
@@ -474,13 +506,6 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
fail_fn_z(CREATE_ERROR("Failed to set send timeout for socket %d: %s",
session_socket, strerror(errno)));
}
- if (getsockopt(session_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1) {
- fail_fn_z(CREATE_ERROR("ForkMany failed to get credentials: %s", strerror(errno)));
- }
- if (cred_size != sizeof credentials) {
- fail_fn_z(CREATE_ERROR("ForkMany credential size = %d, should be %d",
- cred_size, static_cast<int>(sizeof credentials)));
- }
}
first_time = false;
} while (n_buffer->isSimpleForkCommand(minUid, fail_fn_n));

View File

@ -1,291 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Weng Su <wengsu@google.com>
Date: Wed, 3 Apr 2024 10:45:43 +0800
Subject: [PATCH] Restrict WifiDppConfiguratorActivity
- Don't show WifiDppConfiguratorActivity if user has DISALLOW_ADD_WIFI_CONFIG
- Don't show AddNetworkFragment if user has DISALLOW_ADD_WIFI_CONFIG
Fix: 299931076
Flag: None
Test: manual test with TestDPC
atest -c SettingsUnitTests:AddNetworkFragmentTest \
SettingsUnitTests:WifiDppConfiguratorActivityTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:254ba087c29503e8bcf01cc10082c3f393e7701f)
Merged-In: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a
Change-Id: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a
---
.../settings/wifi/AddNetworkFragment.java | 20 +++++
.../wifi/dpp/WifiDppConfiguratorActivity.java | 20 +++++
.../settings/wifi/AddNetworkFragmentTest.java | 74 +++++++++++++++++++
.../dpp/WifiDppConfiguratorActivityTest.java | 74 +++++++++++++++++++
4 files changed, 188 insertions(+)
create mode 100644 tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
create mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 01d5ef1ca4..c50ab9ae24 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -16,11 +16,16 @@
package com.android.settings.wifi;
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
import android.app.Activity;
import android.app.settings.SettingsEnums;
+import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +45,7 @@ import com.android.settings.wifi.dpp.WifiDppUtils;
*/
public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2,
View.OnClickListener {
+ private static final String TAG = "AddNetworkFragment";
public static final String WIFI_CONFIG_KEY = "wifi_config_key";
@VisibleForTesting
@@ -57,6 +63,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!isAddWifiConfigAllowed(getContext())) {
+ getActivity().finish();
+ return;
+ }
}
@Override
@@ -204,4 +214,14 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf
activity.setResult(Activity.RESULT_CANCELED);
activity.finish();
}
+
+ @VisibleForTesting
+ static boolean isAddWifiConfigAllowed(Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index ecaf9ee8fc..a658c16a8c 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -16,6 +16,8 @@
package com.android.settings.wifi.dpp;
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.net.Uri;
@@ -96,6 +98,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!isAddWifiConfigAllowed(getApplicationContext())) {
+ finish();
+ return;
+ }
if (savedInstanceState != null) {
String qrCode = savedInstanceState.getString(KEY_QR_CODE);
@@ -116,6 +122,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements
@Override
protected void handleIntent(Intent intent) {
+ if (!isAddWifiConfigAllowed(getApplicationContext())) {
+ finish();
+ return;
+ }
String action = intent != null ? intent.getAction() : null;
if (action == null) {
finish();
@@ -384,4 +394,14 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements
return null;
}
+
+ @VisibleForTesting
+ static boolean isAddWifiConfigAllowed(Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
new file mode 100644
index 0000000000..22d43c9bb4
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 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.wifi;
+
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+@UiThreadTest
+public class AddNetworkFragmentTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
+
+ private AddNetworkFragment mFragment;
+
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+
+ mFragment = new AddNetworkFragment();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false);
+
+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true);
+
+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
new file mode 100644
index 0000000000..4d723dc184
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 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.wifi.dpp;
+
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+@UiThreadTest
+public class WifiDppConfiguratorActivityTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
+
+ private WifiDppConfiguratorActivity mActivity;
+
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+
+ mActivity = new WifiDppConfiguratorActivity();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false);
+
+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true);
+
+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse();
+ }
+}

View File

@ -1,260 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Vova Sharaienko <sharaienko@google.com>
Date: Thu, 20 Jul 2023 23:25:31 +0000
Subject: [PATCH] Make executor thread a class member of MultiConditionTrigger
executorThread references class members after detaching. Making
executorThread as class member and joining in MultiConditionTrigger
destructor.
Ignore-AOSP-First: Security bugs merged into internal branch first
Test: atest statsd_test
Bug: 292160348
Flag: NONE mainline module bug fix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:262e2c8a5293483c98be498e60e1e5d15c6a0145)
Merged-In: I7036eb3d506e8ca88e4a5faa6275dc4cba8020ee
Change-Id: I7036eb3d506e8ca88e4a5faa6275dc4cba8020ee
---
statsd/src/utils/MultiConditionTrigger.cpp | 21 ++-
statsd/src/utils/MultiConditionTrigger.h | 10 +-
.../utils/MultiConditionTrigger_test.cpp | 121 ++++++++++++++++++
3 files changed, 144 insertions(+), 8 deletions(-)
diff --git a/statsd/src/utils/MultiConditionTrigger.cpp b/statsd/src/utils/MultiConditionTrigger.cpp
index 43a69337..3088453e 100644
--- a/statsd/src/utils/MultiConditionTrigger.cpp
+++ b/statsd/src/utils/MultiConditionTrigger.cpp
@@ -14,11 +14,10 @@
* limitations under the License.
*/
#define DEBUG false // STOPSHIP if true
+#include "Log.h"
#include "MultiConditionTrigger.h"
-#include <thread>
-
using namespace std;
namespace android {
@@ -31,8 +30,7 @@ MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames,
mTrigger(trigger),
mCompleted(mRemainingConditionNames.empty()) {
if (mCompleted) {
- thread executorThread([this] { mTrigger(); });
- executorThread.detach();
+ startExecutorThread();
}
}
@@ -48,10 +46,21 @@ void MultiConditionTrigger::markComplete(const string& conditionName) {
doTrigger = mCompleted;
}
if (doTrigger) {
- std::thread executorThread([this] { mTrigger(); });
- executorThread.detach();
+ startExecutorThread();
}
}
+
+void MultiConditionTrigger::startExecutorThread() {
+ mExecutorThread = make_unique<thread>([this] { mTrigger(); });
+}
+
+MultiConditionTrigger::~MultiConditionTrigger() {
+ if (mExecutorThread != nullptr && mExecutorThread->joinable()) {
+ VLOG("MultiConditionTrigger waiting on execution thread termination");
+ mExecutorThread->join();
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/statsd/src/utils/MultiConditionTrigger.h b/statsd/src/utils/MultiConditionTrigger.h
index 51f60299..dee00713 100644
--- a/statsd/src/utils/MultiConditionTrigger.h
+++ b/statsd/src/utils/MultiConditionTrigger.h
@@ -19,6 +19,7 @@
#include <mutex>
#include <set>
+#include <thread>
namespace android {
namespace os {
@@ -27,8 +28,8 @@ namespace statsd {
/**
* This class provides a utility to wait for a set of named conditions to occur.
*
- * It will execute the trigger runnable in a detached thread once all conditions have been marked
- * true.
+ * It will execute the trigger runnable in a separate thread (which will be joined at instance
+ * destructor time) once all conditions have been marked true.
*/
class MultiConditionTrigger {
public:
@@ -37,19 +38,24 @@ public:
MultiConditionTrigger(const MultiConditionTrigger&) = delete;
MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
+ ~MultiConditionTrigger();
// Mark a specific condition as true. If this condition has called markComplete already or if
// the event was not specified in the constructor, the function is a no-op.
void markComplete(const std::string& eventName);
private:
+ void startExecutorThread();
+
mutable std::mutex mMutex;
std::set<std::string> mRemainingConditionNames;
std::function<void()> mTrigger;
bool mCompleted;
+ std::unique_ptr<std::thread> mExecutorThread;
FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
};
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/statsd/tests/utils/MultiConditionTrigger_test.cpp b/statsd/tests/utils/MultiConditionTrigger_test.cpp
index 32cecd3b..b525f75e 100644
--- a/statsd/tests/utils/MultiConditionTrigger_test.cpp
+++ b/statsd/tests/utils/MultiConditionTrigger_test.cpp
@@ -22,6 +22,8 @@
#include <thread>
#include <vector>
+#include "tests/statsd_test_util.h"
+
#ifdef __ANDROID__
using namespace std;
@@ -166,6 +168,125 @@ TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) {
}
}
+namespace {
+
+class TriggerDependency {
+public:
+ TriggerDependency(mutex& lock, condition_variable& cv, bool& triggerCalled, int& triggerCount)
+ : mLock(lock), mCv(cv), mTriggerCalled(triggerCalled), mTriggerCount(triggerCount) {
+ }
+
+ void someMethod() {
+ lock_guard lg(mLock);
+ mTriggerCount++;
+ mTriggerCalled = true;
+ mCv.notify_all();
+ }
+
+private:
+ mutex& mLock;
+ condition_variable& mCv;
+ bool& mTriggerCalled;
+ int& mTriggerCount;
+};
+
+} // namespace
+
+TEST(MultiConditionTrigger, TestTriggerHasSleep) {
+ const string t1 = "t1";
+ set<string> conditionNames = {t1};
+
+ mutex lock;
+ condition_variable cv;
+ bool triggerCalled = false;
+ int triggerCount = 0;
+
+ {
+ TriggerDependency dependency(lock, cv, triggerCalled, triggerCount);
+ MultiConditionTrigger trigger(conditionNames, [&dependency] {
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ dependency.someMethod();
+ });
+ trigger.markComplete(t1);
+
+ // Here dependency instance will go out of scope and the thread within MultiConditionTrigger
+ // after delay will try to call method of already destroyed class instance
+ // with leading crash if trigger execution thread is detached in MultiConditionTrigger
+ // Instead since the MultiConditionTrigger destructor happens before TriggerDependency
+ // destructor, MultiConditionTrigger destructor is waiting on execution thread termination
+ // with thread::join
+ }
+ // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor
+
+ // Ensure that the trigger fired.
+ {
+ unique_lock<mutex> unique_lk(lock);
+ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
+ EXPECT_TRUE(triggerCalled);
+ EXPECT_EQ(triggerCount, 1);
+ }
+}
+
+TEST(MultiConditionTrigger, TestTriggerHasSleepEarlyTermination) {
+ const string t1 = "t1";
+ set<string> conditionNames = {t1};
+
+ mutex lock;
+ condition_variable cv;
+ bool triggerCalled = false;
+ int triggerCount = 0;
+
+ std::condition_variable triggerTerminationFlag;
+ std::mutex triggerTerminationFlagMutex;
+ bool terminationRequested = false;
+
+ // used for error threshold tolerance due to wait_for() is involved
+ const int64_t errorThresholdMs = 25;
+ const int64_t triggerEarlyTerminationDelayMs = 100;
+ const int64_t triggerStartNs = getElapsedRealtimeNs();
+ {
+ TriggerDependency dependency(lock, cv, triggerCalled, triggerCount);
+ MultiConditionTrigger trigger(
+ conditionNames, [&dependency, &triggerTerminationFlag, &triggerTerminationFlagMutex,
+ &lock, &triggerCalled, &cv, &terminationRequested] {
+ std::unique_lock<std::mutex> lk(triggerTerminationFlagMutex);
+ if (triggerTerminationFlag.wait_for(
+ lk, std::chrono::seconds(1),
+ [&terminationRequested] { return terminationRequested; })) {
+ // triggerTerminationFlag was notified - early termination is requested
+ lock_guard lg(lock);
+ triggerCalled = true;
+ cv.notify_all();
+ return;
+ }
+ dependency.someMethod();
+ });
+ trigger.markComplete(t1);
+
+ // notify to terminate trigger executor thread after triggerEarlyTerminationDelayMs
+ std::this_thread::sleep_for(std::chrono::milliseconds(triggerEarlyTerminationDelayMs));
+ {
+ std::unique_lock<std::mutex> lk(triggerTerminationFlagMutex);
+ terminationRequested = true;
+ }
+ triggerTerminationFlag.notify_all();
+ }
+ // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor
+
+ // check that test duration is closer to 100ms rather to 1s
+ const int64_t triggerEndNs = getElapsedRealtimeNs();
+ EXPECT_LE(NanoToMillis(triggerEndNs - triggerStartNs),
+ triggerEarlyTerminationDelayMs + errorThresholdMs);
+
+ // Ensure that the trigger fired but not the dependency.someMethod().
+ {
+ unique_lock<mutex> unique_lk(lock);
+ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
+ EXPECT_TRUE(triggerCalled);
+ EXPECT_EQ(triggerCount, 0);
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android

View File

@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Omar Eissa <oeissa@google.com>
Date: Mon, 15 Apr 2024 12:04:56 +0000
Subject: [PATCH] Prevent insertion in other users storage volumes
Don't allow file insertion in other users storage volumes.
This was already handled if DATA was explicitly set in content values,
but was allowed if DATA was generated based on other values like RELATIVE_PATH and DISPLAY_NAME.
Insertion of files in other users storage volumes can be used by malicious apps
to get access to other users files, since the same file would exist in both users MP databases
which would lead to MP falsely assuming that the user has access to this file.
Bug: 294406604
Test: atest MediaProviderTests
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df39f8486b25473d0bdbeed896ad917e3c793bf9)
Merged-In: Ie219bbdbe28819421040e4c083b65ab47d8ebde6
Change-Id: Ie219bbdbe28819421040e4c083b65ab47d8ebde6
---
src/com/android/providers/media/MediaProvider.java | 1 +
tests/src/com/android/providers/media/MediaProviderTest.java | 5 ++---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 0d220aa5..71b652f1 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -3275,6 +3275,7 @@ public class MediaProvider extends ContentProvider {
FileUtils.sanitizeValues(values, /*rewriteHiddenFileName*/ !isFuseThread());
FileUtils.computeDataFromValues(values, volumePath, isFuseThread());
+ assertFileColumnsConsistent(match, uri, values);
// Create result file
File res = new File(values.getAsString(MediaColumns.DATA));
diff --git a/tests/src/com/android/providers/media/MediaProviderTest.java b/tests/src/com/android/providers/media/MediaProviderTest.java
index 11fc327b..28463477 100644
--- a/tests/src/com/android/providers/media/MediaProviderTest.java
+++ b/tests/src/com/android/providers/media/MediaProviderTest.java
@@ -377,9 +377,8 @@ public class MediaProviderTest {
@Test
public void testInsertionWithInvalidFilePath_throwsIllegalArgumentException() {
final ContentValues values = new ContentValues();
- values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/com.example");
- values.put(MediaStore.Images.Media.DISPLAY_NAME,
- "./../../../../../../../../../../../data/media/test.txt");
+ values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/com.example/");
+ values.put(MediaStore.Images.Media.DISPLAY_NAME, "data/media/test.txt");
IllegalArgumentException illegalArgumentException = Assert.assertThrows(
IllegalArgumentException.class, () -> sIsolatedResolver.insert(

View File

@ -1,63 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Mon, 22 Apr 2024 21:10:09 +0000
Subject: [PATCH] Fix an authentication bypass bug in SMP
When pairing with BLE legacy pairing initiated
from remote, authentication can be bypassed.
This change fixes it.
Bug: 251514170
Test: m com.android.btservices
Test: manual run against PoC
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:25a3fcd487c799d5d9029b8646159a0b10143d97)
Merged-In: I369a8fdd675eca731a7a488ed6a2be645058b795
Change-Id: I369a8fdd675eca731a7a488ed6a2be645058b795
---
stack/smp/smp_act.cc | 12 ++++++++++++
stack/smp/smp_int.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index 1863fdf51..47be844aa 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -294,6 +294,7 @@ void smp_send_pair_rsp(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
void smp_send_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
SMP_TRACE_DEBUG("%s", __func__);
smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb);
+ p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM_SENT;
}
/*******************************************************************************
@@ -655,6 +656,17 @@ void smp_proc_init(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
return;
}
+ if (!((p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) &&
+ (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT)) &&
+ !(p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM_SENT)) {
+ // in legacy pairing, the peer should send its rand after
+ // we send our confirm
+ tSMP_INT_DATA smp_int_data{};
+ smp_int_data.status = SMP_INVALID_PARAMETERS;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+ return;
+ }
+
/* save the SRand for comparison */
STREAM_TO_ARRAY(p_cb->rrand.data(), p, OCTET16_LEN);
}
diff --git a/stack/smp/smp_int.h b/stack/smp/smp_int.h
index c13120182..b8c1a5b95 100644
--- a/stack/smp/smp_int.h
+++ b/stack/smp/smp_int.h
@@ -211,6 +211,7 @@ typedef union {
(1 << 7) /* used to resolve race condition */
#define SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY \
(1 << 8) /* used on peripheral to resolve race condition */
+#define SMP_PAIR_FLAGS_CMD_CONFIRM_SENT (1 << 9)
/* check if authentication requirement need MITM protection */
#define SMP_NO_MITM_REQUIRED(x) (((x)&SMP_AUTH_YN_BIT) == 0)

View File

@ -1,63 +0,0 @@
From d39bbaa57ea3e636aa581478ae27ef9829b75718 Mon Sep 17 00:00:00 2001
From: Brian Delwiche <delwiche@google.com>
Date: Mon, 22 Apr 2024 21:10:09 +0000
Subject: [PATCH] Fix an authentication bypass bug in SMP
When pairing with BLE legacy pairing initiated
from remote, authentication can be bypassed.
This change fixes it.
Bug: 251514170
Test: m com.android.btservices
Test: manual run against PoC
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:25a3fcd487c799d5d9029b8646159a0b10143d97)
Merged-In: I369a8fdd675eca731a7a488ed6a2be645058b795
Change-Id: I369a8fdd675eca731a7a488ed6a2be645058b795
---
system/stack/smp/smp_act.cc | 12 ++++++++++++
system/stack/smp/smp_int.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc
index 868c7b53118..d6021bbecd2 100644
--- a/system/stack/smp/smp_act.cc
+++ b/system/stack/smp/smp_act.cc
@@ -291,6 +291,7 @@ void smp_send_pair_rsp(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
void smp_send_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
SMP_TRACE_DEBUG("%s", __func__);
smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb);
+ p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM_SENT;
}
/*******************************************************************************
@@ -665,6 +666,17 @@ void smp_proc_init(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
return;
}
+ if (!((p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) &&
+ (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT)) &&
+ !(p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM_SENT)) {
+ // in legacy pairing, the peer should send its rand after
+ // we send our confirm
+ tSMP_INT_DATA smp_int_data{};
+ smp_int_data.status = SMP_INVALID_PARAMETERS;
+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+ return;
+ }
+
/* save the SRand for comparison */
STREAM_TO_ARRAY(p_cb->rrand.data(), p, OCTET16_LEN);
}
diff --git a/system/stack/smp/smp_int.h b/system/stack/smp/smp_int.h
index 5e731806de7..b2ab4776421 100644
--- a/system/stack/smp/smp_int.h
+++ b/system/stack/smp/smp_int.h
@@ -222,6 +222,7 @@ typedef union {
(1 << 7) /* used to resolve race condition */
#define SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY \
(1 << 8) /* used on peripheral to resolve race condition */
+#define SMP_PAIR_FLAGS_CMD_CONFIRM_SENT (1 << 9)
/* check if authentication requirement need MITM protection */
#define SMP_NO_MITM_REQUIRED(x) (((x)&SMP_AUTH_YN_BIT) == 0)

View File

@ -1,51 +0,0 @@
From a0afe17e817eb39f3de3251f7b040a5f6eebc577 Mon Sep 17 00:00:00 2001
From: Ivan Chiang <chiangi@google.com>
Date: Mon, 18 Mar 2024 02:46:56 +0000
Subject: [PATCH] [PM] Send ACTION_PACKAGE_CHANGED when mimeGroups are changed
Test: atest CtsPackageManagerTestCases:PackageManagerShellCommandMultiUserTest
Test: atest CtsPackageManagerTestCases:PackageManagerTest
Bug: 297517712
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:81eb9f8294645684ce1fad39d5d4a00ef11736e4)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c160424ef22bffd25a9cc9bc7b901ae1b9721a72)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6d9520bb9be2e31fd43bb08f0017838bbd389883)
Merged-In: I271a3526ea4555249e3a2797605269257330e0e9
Change-Id: I271a3526ea4555249e3a2797605269257330e0e9
---
.../server/pm/PackageManagerService.java | 23 ++++++++++++++++---
1 file changed, 20 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 f41b9fc540f6..a34693b7cb12 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5869,9 +5869,26 @@ public void setMimeGroup(String packageName, String mimeGroup, List<String> mime
packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet);
});
if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) {
- Binder.withCleanCallingIdentity(() ->
- mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
- UserHandle.USER_ALL));
+ Binder.withCleanCallingIdentity(() -> {
+ mPreferredActivityHelper.clearPackagePreferredActivities(packageName,
+ UserHandle.USER_ALL);
+ // Send the ACTION_PACKAGE_CHANGED when the mimeGroup has changes
+ final Computer snapShot = snapshotComputer();
+ final ArrayList<String> components = new ArrayList<>(
+ Collections.singletonList(packageName));
+ final int appId = packageState.getAppId();
+ final int[] userIds = resolveUserIds(UserHandle.USER_ALL);
+ final String reason = "The mimeGroup is changed";
+ for (int i = 0; i < userIds.length; i++) {
+ final PackageUserStateInternal pkgUserState =
+ packageState.getUserStates().get(userIds[i]);
+ if (pkgUserState != null && pkgUserState.isInstalled()) {
+ final int packageUid = UserHandle.getUid(userIds[i], appId);
+ sendPackageChangedBroadcast(snapShot, packageName,
+ true /* dontKillApp */, components, packageUid, reason);
+ }
+ }
+ });
}
scheduleWriteSettings();

View File

@ -1,82 +0,0 @@
From cb2db1244c4668fe8b3d6cf36d0078190fa8f0af Mon Sep 17 00:00:00 2001
From: Bishoy Gendy <bishoygendy@google.com>
Date: Thu, 11 Apr 2024 16:37:10 +0000
Subject: [PATCH] Fix security vulnerability allowing apps to start from
background
Bug: 317048338
Test: Using the steps in b/317048338#comment12
(cherry picked from commit c5fc8ea92c0aabbb2fdccc23b743c18a8bf62e64)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df3584bb93ab89d7e174f7d39e42d4b22cb92fe0)
Merged-In: Ia91199fdb23beed27bde687fdca8fe5d3a5a4759
Change-Id: Ia91199fdb23beed27bde687fdca8fe5d3a5a4759
---
.../media/session/ParcelableListBinder.java | 13 +++++++++++--
.../android/server/media/MediaSessionRecord.java | 14 ++++++++------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/media/java/android/media/session/ParcelableListBinder.java b/media/java/android/media/session/ParcelableListBinder.java
index bbf1e0889b68..d78828462b1e 100644
--- a/media/java/android/media/session/ParcelableListBinder.java
+++ b/media/java/android/media/session/ParcelableListBinder.java
@@ -45,6 +45,7 @@ public class ParcelableListBinder<T extends Parcelable> extends Binder {
private static final int END_OF_PARCEL = 0;
private static final int ITEM_CONTINUED = 1;
+ private final Class<T> mListElementsClass;
private final Consumer<List<T>> mConsumer;
private final Object mLock = new Object();
@@ -61,9 +62,11 @@ public class ParcelableListBinder<T extends Parcelable> extends Binder {
/**
* Creates an instance.
*
+ * @param listElementsClass the class of the list elements.
* @param consumer a consumer that consumes the list received
*/
- public ParcelableListBinder(@NonNull Consumer<List<T>> consumer) {
+ public ParcelableListBinder(Class<T> listElementsClass, @NonNull Consumer<List<T>> consumer) {
+ mListElementsClass = listElementsClass;
mConsumer = consumer;
}
@@ -83,7 +86,13 @@ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
mCount = data.readInt();
}
while (i < mCount && data.readInt() != END_OF_PARCEL) {
- mList.add(data.readParcelable(null));
+ Object object = data.readParcelable(null);
+ if (mListElementsClass.isAssignableFrom(object.getClass())) {
+ // Checking list items are of compaitible types to validate against malicious
+ // apps calling it directly via reflection with non compilable items.
+ // See b/317048338 for more details
+ mList.add((T) object);
+ }
i++;
}
if (i >= mCount) {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index b459cfe6b44e..8f07b3924da0 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -1100,12 +1100,14 @@ public void resetQueue() throws RemoteException {
@Override
public IBinder getBinderForSetQueue() throws RemoteException {
- return new ParcelableListBinder<QueueItem>((list) -> {
- synchronized (mLock) {
- mQueue = list;
- }
- mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
- });
+ return new ParcelableListBinder<QueueItem>(
+ QueueItem.class,
+ (list) -> {
+ synchronized (mLock) {
+ mQueue = list;
+ }
+ mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
+ });
}
@Override

View File

@ -1,37 +0,0 @@
From 93a2c9a876b978db4109a5360479e793eba5bf95 Mon Sep 17 00:00:00 2001
From: Yi-an Chen <theianchen@google.com>
Date: Tue, 23 Apr 2024 21:17:44 +0000
Subject: [PATCH] Fix security vulnerability of non-dynamic permission removal
The original removePermission() code in PermissionManagerServiceImpl
missed a logical negation operator when handling non-dynamic
permissions, causing both
testPermissionPermission_nonDynamicPermission_permissionUnchanged and
testRemovePermission_dynamicPermission_permissionRemoved tests in
DynamicPermissionsTest to fail.
The corresponding test DynamicPermissionsTest is also updated in the
other CL: ag/27073864
Bug: 321711213
Test: DynamicPermissionsTest on sc-dev and tm-dev locally
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0ead58f69f5de82b00406316b333366d556239f1)
Merged-In: Ia146d4098643d9c473f8c83d33a8a125a53101fc
Change-Id: Ia146d4098643d9c473f8c83d33a8a125a53101fc
---
.../server/pm/permission/PermissionManagerServiceImpl.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 1ec3403a9d46..3e06df908858 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -677,7 +677,7 @@ public void removePermission(String permName) {
if (bp == null) {
return;
}
- if (bp.isDynamic()) {
+ if (!bp.isDynamic()) {
// TODO: switch this back to SecurityException
Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
+ permName);

View File

@ -1,176 +0,0 @@
From ed52683e9c4960b21ff9d7a7c38bef5bfa02d4fb Mon Sep 17 00:00:00 2001
From: Martijn Coenen <maco@google.com>
Date: Thu, 29 Feb 2024 12:03:05 +0000
Subject: [PATCH] Verify UID of incoming Zygote connections.
Only the system UID should be allowed to connect to the Zygote. While
for generic Zygotes this is also covered by SELinux policy, this is not
true for App Zygotes: the preload code running in an app zygote could
connect to another app zygote socket, if it had access to its (random)
socket address.
On the Java layer, simply check the UID when the connection is made. In
the native layer, this check was already present, but it actually didn't
work in the case where we receive a new incoming connection on the
socket, and receive a 'non-fork' command: in that case, we will simply
exit the native loop, and let the Java layer handle the command, without
any further UID checking.
Modified the native logic to drop new connections with a mismatching
UID, and to keep serving the existing connection (if it was still
there).
Bug: 319081336
Test: manual
(cherry picked from commit 2ffc7cb220e4220b7e108c4043a3f0f2a85b6508)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f1d4b34ad51b6ccb84ab042486923da8b2451e0f)
Merged-In: I3f85a17107849e2cd3e82d6ef15c90b9e2f26532
Change-Id: I3f85a17107849e2cd3e82d6ef15c90b9e2f26532
---
.../android/internal/os/ZygoteConnection.java | 3 +
...ndroid_internal_os_ZygoteCommandBuffer.cpp | 82 ++++++++++++-------
2 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 252c0d08ac5a..3e0698d4564c 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -94,6 +94,9 @@ class ZygoteConnection {
throw ex;
}
+ if (peer.getUid() != Process.SYSTEM_UID) {
+ throw new ZygoteSecurityException("Only system UID is allowed to connect to Zygote.");
+ }
isEof = false;
}
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 0b422122f03b..77e9bee9df5e 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -367,6 +367,18 @@ jstring com_android_internal_os_ZygoteCommandBuffer_nativeNextArg(JNIEnv* env, j
return result;
}
+static uid_t getSocketPeerUid(int socket, const std::function<void(const std::string&)>& fail_fn) {
+ struct ucred credentials;
+ socklen_t cred_size = sizeof credentials;
+ if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
+ || cred_size != sizeof credentials) {
+ fail_fn(CREATE_ERROR("Failed to get socket credentials, %s",
+ strerror(errno)));
+ }
+
+ return credentials.uid;
+}
+
// Read all lines from the current command into the buffer, and then reset the buffer, so
// we will start reading again at the beginning of the command, starting with the argument
// count. And we don't need access to the fd to do so.
@@ -425,19 +437,12 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
fail_fn_z("Failed to retrieve session socket timeout");
}
- struct ucred credentials;
- socklen_t cred_size = sizeof credentials;
- if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
- || cred_size != sizeof credentials) {
- fail_fn_1(CREATE_ERROR("ForkRepeatedly failed to get initial credentials, %s",
- strerror(errno)));
+ uid_t peerUid = getSocketPeerUid(session_socket, fail_fn_1);
+ if (peerUid != static_cast<uid_t>(expected_uid)) {
+ return JNI_FALSE;
}
-
bool first_time = true;
do {
- if (credentials.uid != expected_uid) {
- return JNI_FALSE;
- }
n_buffer->readAllLines(first_time ? fail_fn_1 : fail_fn_n);
n_buffer->reset();
int pid = zygote::forkApp(env, /* no pipe FDs */ -1, -1, session_socket_fds,
@@ -467,30 +472,56 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
// Clear buffer and get count from next command.
n_buffer->clear();
for (;;) {
+ bool valid_session_socket = true;
// Poll isn't strictly necessary for now. But without it, disconnect is hard to detect.
int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */));
if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) {
if (n_buffer->getCount(fail_fn_z) != 0) {
break;
- } // else disconnected;
+ } else {
+ // Session socket was disconnected
+ valid_session_socket = false;
+ close(session_socket);
+ }
} else if (poll_res == 0 || (fd_structs[ZYGOTE_IDX].revents & POLLIN) == 0) {
fail_fn_z(
CREATE_ERROR("Poll returned with no descriptors ready! Poll returned %d", poll_res));
}
- // We've now seen either a disconnect or connect request.
- close(session_socket);
- int new_fd = TEMP_FAILURE_RETRY(accept(zygote_socket_fd, nullptr, nullptr));
+ int new_fd = -1;
+ do {
+ // We've now seen either a disconnect or connect request.
+ new_fd = TEMP_FAILURE_RETRY(accept(zygote_socket_fd, nullptr, nullptr));
+ if (new_fd == -1) {
+ fail_fn_z(CREATE_ERROR("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno)));
+ }
+ uid_t newPeerUid = getSocketPeerUid(new_fd, fail_fn_1);
+ if (newPeerUid != static_cast<uid_t>(expected_uid)) {
+ ALOGW("Dropping new connection with a mismatched uid %d\n", newPeerUid);
+ close(new_fd);
+ new_fd = -1;
+ } else {
+ // If we still have a valid session socket, close it now
+ if (valid_session_socket) {
+ close(session_socket);
+ }
+ valid_session_socket = true;
+ }
+ } while (!valid_session_socket);
+
+ // At this point we either have a valid new connection (new_fd > 0), or
+ // an existing session socket we can poll on
if (new_fd == -1) {
- fail_fn_z(CREATE_ERROR("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno)));
+ // The new connection wasn't valid, and we still have an old one; retry polling
+ continue;
}
if (new_fd != session_socket) {
- // Move new_fd back to the old value, so that we don't have to change Java-level data
- // structures to reflect a change. This implicitly closes the old one.
- if (TEMP_FAILURE_RETRY(dup2(new_fd, session_socket)) != session_socket) {
- fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s",
- new_fd, session_socket, strerror(errno)));
- }
- close(new_fd); // On Linux, fd is closed even if EINTR is returned.
+ // Move new_fd back to the old value, so that we don't have to change Java-level data
+ // structures to reflect a change. This implicitly closes the old one.
+ if (TEMP_FAILURE_RETRY(dup2(new_fd, session_socket)) != session_socket) {
+ fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s",
+ new_fd, session_socket, strerror(errno)));
+ }
+ close(new_fd); // On Linux, fd is closed even if EINTR is returned.
}
// If we ever return, we effectively reuse the old Java ZygoteConnection.
// None of its state needs to change.
@@ -502,13 +533,6 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
fail_fn_z(CREATE_ERROR("Failed to set send timeout for socket %d: %s",
session_socket, strerror(errno)));
}
- if (getsockopt(session_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1) {
- fail_fn_z(CREATE_ERROR("ForkMany failed to get credentials: %s", strerror(errno)));
- }
- if (cred_size != sizeof credentials) {
- fail_fn_z(CREATE_ERROR("ForkMany credential size = %d, should be %d",
- cred_size, static_cast<int>(sizeof credentials)));
- }
}
first_time = false;
} while (n_buffer->isSimpleForkCommand(minUid, fail_fn_n));

View File

@ -1,51 +0,0 @@
From ce7b9fd0f521cb6b038cb355b64f81f0c7524114 Mon Sep 17 00:00:00 2001
From: Omar Eissa <oeissa@google.com>
Date: Mon, 15 Apr 2024 12:04:56 +0000
Subject: [PATCH] Prevent insertion in other users storage volumes
Don't allow file insertion in other users storage volumes.
This was already handled if DATA was explicitly set in content values,
but was allowed if DATA was generated based on other values like RELATIVE_PATH and DISPLAY_NAME.
Insertion of files in other users storage volumes can be used by malicious apps
to get access to other users files, since the same file would exist in both users MP databases
which would lead to MP falsely assuming that the user has access to this file.
Bug: 294406604
Test: atest MediaProviderTests
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df39f8486b25473d0bdbeed896ad917e3c793bf9)
Merged-In: Ie219bbdbe28819421040e4c083b65ab47d8ebde6
Change-Id: Ie219bbdbe28819421040e4c083b65ab47d8ebde6
---
src/com/android/providers/media/MediaProvider.java | 1 +
tests/src/com/android/providers/media/MediaProviderTest.java | 5 ++---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 8c1df561b..04167d911 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -3891,6 +3891,7 @@ private void ensureFileColumns(int match, @NonNull Uri uri, @NonNull Bundle extr
FileUtils.sanitizeValues(values, /*rewriteHiddenFileName*/ !isFuseThread());
FileUtils.computeDataFromValues(values, volumePath, isFuseThread());
+ assertFileColumnsConsistent(match, uri, values);
// Create result file
File res = new File(values.getAsString(MediaColumns.DATA));
diff --git a/tests/src/com/android/providers/media/MediaProviderTest.java b/tests/src/com/android/providers/media/MediaProviderTest.java
index fc3029241..3bd86673c 100644
--- a/tests/src/com/android/providers/media/MediaProviderTest.java
+++ b/tests/src/com/android/providers/media/MediaProviderTest.java
@@ -379,9 +379,8 @@ private void testActionLongFileNameItemHasTrimmedFileName(String columnKey) thro
@Test
public void testInsertionWithInvalidFilePath_throwsIllegalArgumentException() {
final ContentValues values = new ContentValues();
- values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/com.example");
- values.put(MediaStore.Images.Media.DISPLAY_NAME,
- "./../../../../../../../../../../../data/media/test.txt");
+ values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/com.example/");
+ values.put(MediaStore.Images.Media.DISPLAY_NAME, "data/media/test.txt");
IllegalArgumentException illegalArgumentException = Assert.assertThrows(
IllegalArgumentException.class, () -> sIsolatedResolver.insert(

View File

@ -1,292 +0,0 @@
From df49ae67f1baf3b8d3f5f0558a4512bea1e28b04 Mon Sep 17 00:00:00 2001
From: Weng Su <wengsu@google.com>
Date: Wed, 3 Apr 2024 10:45:43 +0800
Subject: [PATCH] [RESTRICT AUTOMERGE] Restrict WifiDppConfiguratorActivity
- Don't show WifiDppConfiguratorActivity if user has DISALLOW_ADD_WIFI_CONFIG
- Don't show AddNetworkFragment if user has DISALLOW_ADD_WIFI_CONFIG
Fix: 299931076
Flag: None
Test: manual test with TestDPC
atest -c SettingsUnitTests:AddNetworkFragmentTest \
SettingsUnitTests:WifiDppConfiguratorActivityTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:254ba087c29503e8bcf01cc10082c3f393e7701f)
Merged-In: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a
Change-Id: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a
---
.../settings/wifi/AddNetworkFragment.java | 20 +++++
.../wifi/dpp/WifiDppConfiguratorActivity.java | 21 ++++++
.../settings/wifi/AddNetworkFragmentTest.java | 74 +++++++++++++++++++
.../dpp/WifiDppConfiguratorActivityTest.java | 74 +++++++++++++++++++
4 files changed, 189 insertions(+)
create mode 100644 tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
create mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index 47a027d8bed..eb48d7d9aa2 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -16,11 +16,16 @@
package com.android.settings.wifi;
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
import android.app.Activity;
import android.app.settings.SettingsEnums;
+import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,6 +46,7 @@
*/
public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2,
View.OnClickListener {
+ private static final String TAG = "AddNetworkFragment";
public static final String WIFI_CONFIG_KEY = "wifi_config_key";
@VisibleForTesting
@@ -58,6 +64,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!isAddWifiConfigAllowed(getContext())) {
+ getActivity().finish();
+ return;
+ }
}
@Override
@@ -209,4 +219,14 @@ void handleCancelAction() {
activity.setResult(Activity.RESULT_CANCELED);
activity.finish();
}
+
+ @VisibleForTesting
+ static boolean isAddWifiConfigAllowed(Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index e6f0b31f384..d7444c8a42b 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -16,6 +16,8 @@
package com.android.settings.wifi.dpp;
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
@@ -99,6 +101,10 @@ public int getMetricsCategory() {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!isAddWifiConfigAllowed(getApplicationContext())) {
+ finish();
+ return;
+ }
if (savedInstanceState != null) {
String qrCode = savedInstanceState.getString(KEY_QR_CODE);
@@ -119,6 +125,11 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
protected void handleIntent(Intent intent) {
+ if (!isAddWifiConfigAllowed(getApplicationContext())) {
+ finish();
+ return;
+ }
+
if (isGuestUser(getApplicationContext())) {
Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!");
EventLog.writeEvent(0x534e4554, "224772890", -1 /* UID */, "User is a guest");
@@ -402,4 +413,14 @@ private static boolean isGuestUser(Context context) {
if (userManager == null) return false;
return userManager.isGuestUser();
}
+
+ @VisibleForTesting
+ static boolean isAddWifiConfigAllowed(Context context) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
+ return false;
+ }
+ return true;
+ }
}
diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
new file mode 100644
index 00000000000..22d43c9bb4e
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 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.wifi;
+
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+@UiThreadTest
+public class AddNetworkFragmentTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
+
+ private AddNetworkFragment mFragment;
+
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+
+ mFragment = new AddNetworkFragment();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false);
+
+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true);
+
+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
new file mode 100644
index 00000000000..4d723dc1846
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 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.wifi.dpp;
+
+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(AndroidJUnit4.class)
+@UiThreadTest
+public class WifiDppConfiguratorActivityTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ @Spy
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ @Mock
+ private UserManager mUserManager;
+
+ private WifiDppConfiguratorActivity mActivity;
+
+ @Before
+ public void setUp() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+
+ mActivity = new WifiDppConfiguratorActivity();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false);
+
+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue();
+ }
+
+ @Test
+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() {
+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true);
+
+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse();
+ }
+}

View File

@ -1,261 +0,0 @@
From 09e63307961e3fa93d4bcb2ce73821e73b3bc8c4 Mon Sep 17 00:00:00 2001
From: Vova Sharaienko <sharaienko@google.com>
Date: Thu, 20 Jul 2023 23:25:31 +0000
Subject: [PATCH] [statsd] Make executor thread a class member of
MultiConditionTrigger
executorThread references class members after detaching. Making
executorThread as class member and joining in MultiConditionTrigger
destructor.
Ignore-AOSP-First: Security bugs merged into internal branch first
Test: atest statsd_test
Bug: 292160348
Flag: NONE mainline module bug fix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:262e2c8a5293483c98be498e60e1e5d15c6a0145)
Merged-In: I7036eb3d506e8ca88e4a5faa6275dc4cba8020ee
Change-Id: I7036eb3d506e8ca88e4a5faa6275dc4cba8020ee
---
statsd/src/utils/MultiConditionTrigger.cpp | 21 ++-
statsd/src/utils/MultiConditionTrigger.h | 10 +-
.../utils/MultiConditionTrigger_test.cpp | 121 ++++++++++++++++++
3 files changed, 144 insertions(+), 8 deletions(-)
diff --git a/statsd/src/utils/MultiConditionTrigger.cpp b/statsd/src/utils/MultiConditionTrigger.cpp
index 5ef50ee09..5078cae6d 100644
--- a/statsd/src/utils/MultiConditionTrigger.cpp
+++ b/statsd/src/utils/MultiConditionTrigger.cpp
@@ -14,11 +14,10 @@
* limitations under the License.
*/
#define STATSD_DEBUG false // STOPSHIP if true
+#include "Log.h"
#include "MultiConditionTrigger.h"
-#include <thread>
-
using namespace std;
namespace android {
@@ -31,8 +30,7 @@ MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames,
mTrigger(trigger),
mCompleted(mRemainingConditionNames.empty()) {
if (mCompleted) {
- thread executorThread([this] { mTrigger(); });
- executorThread.detach();
+ startExecutorThread();
}
}
@@ -48,10 +46,21 @@ void MultiConditionTrigger::markComplete(const string& conditionName) {
doTrigger = mCompleted;
}
if (doTrigger) {
- std::thread executorThread([this] { mTrigger(); });
- executorThread.detach();
+ startExecutorThread();
}
}
+
+void MultiConditionTrigger::startExecutorThread() {
+ mExecutorThread = make_unique<thread>([this] { mTrigger(); });
+}
+
+MultiConditionTrigger::~MultiConditionTrigger() {
+ if (mExecutorThread != nullptr && mExecutorThread->joinable()) {
+ VLOG("MultiConditionTrigger waiting on execution thread termination");
+ mExecutorThread->join();
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/statsd/src/utils/MultiConditionTrigger.h b/statsd/src/utils/MultiConditionTrigger.h
index 51f602991..dee007133 100644
--- a/statsd/src/utils/MultiConditionTrigger.h
+++ b/statsd/src/utils/MultiConditionTrigger.h
@@ -19,6 +19,7 @@
#include <mutex>
#include <set>
+#include <thread>
namespace android {
namespace os {
@@ -27,8 +28,8 @@ namespace statsd {
/**
* This class provides a utility to wait for a set of named conditions to occur.
*
- * It will execute the trigger runnable in a detached thread once all conditions have been marked
- * true.
+ * It will execute the trigger runnable in a separate thread (which will be joined at instance
+ * destructor time) once all conditions have been marked true.
*/
class MultiConditionTrigger {
public:
@@ -37,19 +38,24 @@ class MultiConditionTrigger {
MultiConditionTrigger(const MultiConditionTrigger&) = delete;
MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
+ ~MultiConditionTrigger();
// Mark a specific condition as true. If this condition has called markComplete already or if
// the event was not specified in the constructor, the function is a no-op.
void markComplete(const std::string& eventName);
private:
+ void startExecutorThread();
+
mutable std::mutex mMutex;
std::set<std::string> mRemainingConditionNames;
std::function<void()> mTrigger;
bool mCompleted;
+ std::unique_ptr<std::thread> mExecutorThread;
FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
};
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/statsd/tests/utils/MultiConditionTrigger_test.cpp b/statsd/tests/utils/MultiConditionTrigger_test.cpp
index 32cecd3b9..b525f75e6 100644
--- a/statsd/tests/utils/MultiConditionTrigger_test.cpp
+++ b/statsd/tests/utils/MultiConditionTrigger_test.cpp
@@ -22,6 +22,8 @@
#include <thread>
#include <vector>
+#include "tests/statsd_test_util.h"
+
#ifdef __ANDROID__
using namespace std;
@@ -166,6 +168,125 @@ TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) {
}
}
+namespace {
+
+class TriggerDependency {
+public:
+ TriggerDependency(mutex& lock, condition_variable& cv, bool& triggerCalled, int& triggerCount)
+ : mLock(lock), mCv(cv), mTriggerCalled(triggerCalled), mTriggerCount(triggerCount) {
+ }
+
+ void someMethod() {
+ lock_guard lg(mLock);
+ mTriggerCount++;
+ mTriggerCalled = true;
+ mCv.notify_all();
+ }
+
+private:
+ mutex& mLock;
+ condition_variable& mCv;
+ bool& mTriggerCalled;
+ int& mTriggerCount;
+};
+
+} // namespace
+
+TEST(MultiConditionTrigger, TestTriggerHasSleep) {
+ const string t1 = "t1";
+ set<string> conditionNames = {t1};
+
+ mutex lock;
+ condition_variable cv;
+ bool triggerCalled = false;
+ int triggerCount = 0;
+
+ {
+ TriggerDependency dependency(lock, cv, triggerCalled, triggerCount);
+ MultiConditionTrigger trigger(conditionNames, [&dependency] {
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+ dependency.someMethod();
+ });
+ trigger.markComplete(t1);
+
+ // Here dependency instance will go out of scope and the thread within MultiConditionTrigger
+ // after delay will try to call method of already destroyed class instance
+ // with leading crash if trigger execution thread is detached in MultiConditionTrigger
+ // Instead since the MultiConditionTrigger destructor happens before TriggerDependency
+ // destructor, MultiConditionTrigger destructor is waiting on execution thread termination
+ // with thread::join
+ }
+ // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor
+
+ // Ensure that the trigger fired.
+ {
+ unique_lock<mutex> unique_lk(lock);
+ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
+ EXPECT_TRUE(triggerCalled);
+ EXPECT_EQ(triggerCount, 1);
+ }
+}
+
+TEST(MultiConditionTrigger, TestTriggerHasSleepEarlyTermination) {
+ const string t1 = "t1";
+ set<string> conditionNames = {t1};
+
+ mutex lock;
+ condition_variable cv;
+ bool triggerCalled = false;
+ int triggerCount = 0;
+
+ std::condition_variable triggerTerminationFlag;
+ std::mutex triggerTerminationFlagMutex;
+ bool terminationRequested = false;
+
+ // used for error threshold tolerance due to wait_for() is involved
+ const int64_t errorThresholdMs = 25;
+ const int64_t triggerEarlyTerminationDelayMs = 100;
+ const int64_t triggerStartNs = getElapsedRealtimeNs();
+ {
+ TriggerDependency dependency(lock, cv, triggerCalled, triggerCount);
+ MultiConditionTrigger trigger(
+ conditionNames, [&dependency, &triggerTerminationFlag, &triggerTerminationFlagMutex,
+ &lock, &triggerCalled, &cv, &terminationRequested] {
+ std::unique_lock<std::mutex> lk(triggerTerminationFlagMutex);
+ if (triggerTerminationFlag.wait_for(
+ lk, std::chrono::seconds(1),
+ [&terminationRequested] { return terminationRequested; })) {
+ // triggerTerminationFlag was notified - early termination is requested
+ lock_guard lg(lock);
+ triggerCalled = true;
+ cv.notify_all();
+ return;
+ }
+ dependency.someMethod();
+ });
+ trigger.markComplete(t1);
+
+ // notify to terminate trigger executor thread after triggerEarlyTerminationDelayMs
+ std::this_thread::sleep_for(std::chrono::milliseconds(triggerEarlyTerminationDelayMs));
+ {
+ std::unique_lock<std::mutex> lk(triggerTerminationFlagMutex);
+ terminationRequested = true;
+ }
+ triggerTerminationFlag.notify_all();
+ }
+ // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor
+
+ // check that test duration is closer to 100ms rather to 1s
+ const int64_t triggerEndNs = getElapsedRealtimeNs();
+ EXPECT_LE(NanoToMillis(triggerEndNs - triggerStartNs),
+ triggerEarlyTerminationDelayMs + errorThresholdMs);
+
+ // Ensure that the trigger fired but not the dependency.someMethod().
+ {
+ unique_lock<mutex> unique_lk(lock);
+ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; });
+ EXPECT_TRUE(triggerCalled);
+ EXPECT_EQ(triggerCount, 0);
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android

View File

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

View File

@ -95,7 +95,6 @@ applyPatch "$DOS_PATCHES_COMMON/android_build/0001-verity-openssl3.patch"; #Fix
sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches. sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches.
awk -i inplace '!/updatable_apex.mk/' target/product/generic_system.mk; #Disable APEX awk -i inplace '!/updatable_apex.mk/' target/product/generic_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/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/2024-06-05/2024-07-05/' core/version_defaults.mk; #Bump Security String #X_asb_2024-07
fi; fi;
if enterAndClear "build/soong"; then if enterAndClear "build/soong"; then
@ -126,10 +125,6 @@ sed -i '11iLOCAL_OVERRIDES_PACKAGES := Camera Camera2 LegacyCamera Snap OpenCame
fi; fi;
if enterAndClear "frameworks/base"; then if enterAndClear "frameworks/base"; then
applyPatch "$DOS_PATCHES/android_frameworks_base/329230490-1.patch"; #X_asb_2024-07 [CDM] Fix setSkipPrompt on Android S
applyPatch "$DOS_PATCHES/android_frameworks_base/397375.patch"; #T_asb_2024-07 Fix security vulnerability allowing apps to start from background
applyPatch "$DOS_PATCHES/android_frameworks_base/397376-backport.patch"; #T_asb_2024-07 Fix security vulnerability of non-dynamic permission removal
applyPatch "$DOS_PATCHES/android_frameworks_base/397377-backport.patch"; #T_asb_2024-07 Verify UID of incoming Zygote connections.
git revert --no-edit 83fe523914728a3674debba17a6019cb74803045; #Reverts "Allow signature spoofing for microG Companion/Services" in favor of below patch git revert --no-edit 83fe523914728a3674debba17a6019cb74803045; #Reverts "Allow signature spoofing for microG Companion/Services" in favor of below patch
applyPatch "$DOS_PATCHES/android_frameworks_base/344888-backport.patch"; #fixup! fw/b: Add support for allowing/disallowing apps on cellular, vpn and wifi networks (CalyxOS) applyPatch "$DOS_PATCHES/android_frameworks_base/344888-backport.patch"; #fixup! fw/b: Add support for allowing/disallowing apps on cellular, vpn and wifi networks (CalyxOS)
applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS) applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS)
@ -304,7 +299,6 @@ fi;
if enterAndClear "packages/apps/Settings"; then if enterAndClear "packages/apps/Settings"; then
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/316891059-19.patch"; #x-asb_2024-05 Replace getCallingActivity() with getLaunchedFromPackage() applyPatch "$DOS_PATCHES/android_packages_apps_Settings/316891059-19.patch"; #x-asb_2024-05 Replace getCallingActivity() with getLaunchedFromPackage()
#applyPatch "$DOS_PATCHES/android_packages_apps_Settings/397378-backport.patch"; #T_asb_2024-07 Restrict WifiDppConfiguratorActivity
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch) applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch)
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0005-Automatic_Reboot.patch"; #Timeout for reboot (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0005-Automatic_Reboot.patch"; #Timeout for reboot (GrapheneOS)
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0006-Bluetooth_Timeout.patch"; #Timeout for Bluetooth (CalyxOS) applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0006-Bluetooth_Timeout.patch"; #Timeout for Bluetooth (CalyxOS)
@ -378,10 +372,6 @@ applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0005-Browser_No_Loc
applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0006-Location_Indicators.patch"; #SystemUI: Use new privacy indicators for location (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0006-Location_Indicators.patch"; #SystemUI: Use new privacy indicators for location (GrapheneOS)
fi; fi;
if enterAndClear "packages/modules/StatsD"; then
applyPatch "$DOS_PATCHES/android_packages_modules_StatsD/397380-backport.patch"; #T_asb_2024-07 Make executor thread a class member of MultiConditionTrigger
fi;
if enterAndClear "packages/modules/Wifi"; then if enterAndClear "packages/modules/Wifi"; then
applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS)
applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC-a1.patch"; #Fix MAC address leak after SSR (AOSP) applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC-a1.patch"; #Fix MAC address leak after SSR (AOSP)
@ -392,16 +382,11 @@ if enterAndClear "packages/providers/DownloadProvider"; then
applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Network_Permission.patch"; #Expose the NETWORK permission (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Network_Permission.patch"; #Expose the NETWORK permission (GrapheneOS)
fi; fi;
if enterAndClear "packages/providers/MediaProvider"; then
applyPatch "$DOS_PATCHES/android_packages_providers_MediaProvider/397381.patch"; #T_asb_2024-07 Prevent insertion in other users storage volumes
fi
if enterAndClear "packages/services/Telephony"; then if enterAndClear "packages/services/Telephony"; then
if [ -d "$DOS_BUILD_BASE"/vendor/divested-carriersettings ]; then applyPatch "$DOS_PATCHES/android_packages_services_Telephony/0001-CC2.patch"; fi; #Runtime control of platform carrier config package (DivestOS) if [ -d "$DOS_BUILD_BASE"/vendor/divested-carriersettings ]; then applyPatch "$DOS_PATCHES/android_packages_services_Telephony/0001-CC2.patch"; fi; #Runtime control of platform carrier config package (DivestOS)
fi; fi;
if enterAndClear "system/bt"; then if enterAndClear "system/bt"; then
applyPatch "$DOS_PATCHES/android_system_bt/397379-backport.patch"; #T_asb_2024-07 Fix an authentication bypass bug in SMP
applyPatch "$DOS_PATCHES_COMMON/android_system_bt/0001-alloc_size.patch"; #Add alloc_size attributes to the allocator (GrapheneOS) applyPatch "$DOS_PATCHES_COMMON/android_system_bt/0001-alloc_size.patch"; #Add alloc_size attributes to the allocator (GrapheneOS)
fi; fi;

View File

@ -162,7 +162,8 @@ patchWorkspaceReal() {
verifyAllPlatformTags; verifyAllPlatformTags;
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview"; gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
#source build/envsetup.sh; source build/envsetup.sh;
repopick -it T_asb_2024-07;
sh "$DOS_SCRIPTS/Patch.sh"; sh "$DOS_SCRIPTS/Patch.sh";
sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh"; sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh";

View File

@ -94,7 +94,6 @@ applyPatch "$DOS_PATCHES/android_build/0003-Exec_Based_Spawning.patch"; #Add exe
applyPatch "$DOS_PATCHES/android_build/0004-Selective_APEX.patch"; #Only enable APEX on 6th/7th gen Pixel devices (GrapheneOS) applyPatch "$DOS_PATCHES/android_build/0004-Selective_APEX.patch"; #Only enable APEX on 6th/7th gen Pixel devices (GrapheneOS)
sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches. sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches.
sed -i 's/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 23/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 28/' core/version_util.mk; #Set the minimum supported target SDK to Pie (GrapheneOS) sed -i 's/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 23/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 28/' core/version_util.mk; #Set the minimum supported target SDK to Pie (GrapheneOS)
sed -i 's/2024-06-05/2024-07-05/' core/version_defaults.mk; #Bump Security String #X_asb_2024-07
fi; fi;
if enterAndClear "build/soong"; then if enterAndClear "build/soong"; then
@ -119,7 +118,6 @@ sed -i -e '76,78d;' Android.bp; #fix compile under A13
fi; fi;
if enterAndClear "frameworks/base"; then if enterAndClear "frameworks/base"; then
git am $DOS_PATCHES/ASB-2024-07/fwb-*.patch;
git revert --no-edit d36faad3267522c6d3ff91ba9dcca8f6274bccd1; #Reverts "JobScheduler: Respect allow-in-power-save perm" in favor of below patch git revert --no-edit d36faad3267522c6d3ff91ba9dcca8f6274bccd1; #Reverts "JobScheduler: Respect allow-in-power-save perm" in favor of below patch
git revert --no-edit 90d6826548189ca850d91692e71fcc1be426f453; #Reverts "Remove sensitive info from SUPL requests" in favor of below patch git revert --no-edit 90d6826548189ca850d91692e71fcc1be426f453; #Reverts "Remove sensitive info from SUPL requests" in favor of below patch
git revert --no-edit 6d2955f0bd55e9938d5d49415182c27b50900b95; #Reverts "Allow signature spoofing for microG Companion/Services" in favor of below patch git revert --no-edit 6d2955f0bd55e9938d5d49415182c27b50900b95; #Reverts "Allow signature spoofing for microG Companion/Services" in favor of below patch
@ -307,7 +305,6 @@ applyPatch "$DOS_PATCHES/android_packages_apps_Nfc/0001-constify_JNINativeMethod
fi; fi;
if enterAndClear "packages/apps/Settings"; then if enterAndClear "packages/apps/Settings"; then
git am $DOS_PATCHES/ASB-2024-07/settings-*.patch;
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/316891059-20.patch"; #x-asb_2024-05 Replace getCallingActivity() with getLaunchedFromPackage() applyPatch "$DOS_PATCHES/android_packages_apps_Settings/316891059-20.patch"; #x-asb_2024-05 Replace getCallingActivity() with getLaunchedFromPackage()
git revert --no-edit 41b4ed345a91da1dd46c00ee11a151c2b5ff4f43; git revert --no-edit 41b4ed345a91da1dd46c00ee11a151c2b5ff4f43;
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch) applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch)
@ -357,10 +354,6 @@ applyPatch "$DOS_PATCHES/android_packages_inputmethods_LatinIME/0001-Voice.patch
applyPatch "$DOS_PATCHES/android_packages_inputmethods_LatinIME/0002-Disable_Personalization.patch"; #Disable personalization dictionary by default (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_inputmethods_LatinIME/0002-Disable_Personalization.patch"; #Disable personalization dictionary by default (GrapheneOS)
fi; fi;
if enterAndClear "packages/modules/Bluetooth"; then
git am $DOS_PATCHES/ASB-2024-07/bluetooth-*.patch;
fi;
if enterAndClear "packages/modules/Connectivity"; then if enterAndClear "packages/modules/Connectivity"; then
applyPatch "$DOS_PATCHES/android_packages_modules_Connectivity/0001-Network_Permission-1.patch"; #Skip reportNetworkConnectivity() when permission is revoked (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_modules_Connectivity/0001-Network_Permission-1.patch"; #Skip reportNetworkConnectivity() when permission is revoked (GrapheneOS)
applyPatch "$DOS_PATCHES/android_packages_modules_Connectivity/0001-Network_Permission-2.patch"; #Enforce INTERNET permission per-uid instead of per-appId (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_modules_Connectivity/0001-Network_Permission-2.patch"; #Enforce INTERNET permission per-uid instead of per-appId (GrapheneOS)
@ -386,10 +379,6 @@ applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0005-Browser_No_Loc
applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0006-Location_Indicators.patch"; #SystemUI: Use new privacy indicators for location (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0006-Location_Indicators.patch"; #SystemUI: Use new privacy indicators for location (GrapheneOS)
fi; fi;
if enterAndClear "packages/modules/StatsD"; then
git am $DOS_PATCHES/ASB-2024-07/statsd-*.patch;
fi;
if enterAndClear "packages/modules/Wifi"; then if enterAndClear "packages/modules/Wifi"; then
applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/344228.patch"; #wifi: resurrect mWifiLinkLayerStatsSupported counter (sassmann) applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/344228.patch"; #wifi: resurrect mWifiLinkLayerStatsSupported counter (sassmann)
applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS)
@ -399,10 +388,6 @@ if enterAndClear "packages/providers/DownloadProvider"; then
applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Network_Permission.patch"; #Expose the NETWORK permission (GrapheneOS) applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Network_Permission.patch"; #Expose the NETWORK permission (GrapheneOS)
fi; fi;
if enterAndClear "packages/providers/MediaProvider"; then
git am $DOS_PATCHES/ASB-2024-07/mediaprovider-*.patch;
fi;
if enterAndClear "packages/services/Telephony"; then if enterAndClear "packages/services/Telephony"; then
if [ -d "$DOS_BUILD_BASE"/vendor/divested-carriersettings ]; then applyPatch "$DOS_PATCHES/android_packages_services_Telephony/0001-CC2.patch"; fi; #Runtime control of platform carrier config package (DivestOS) if [ -d "$DOS_BUILD_BASE"/vendor/divested-carriersettings ]; then applyPatch "$DOS_PATCHES/android_packages_services_Telephony/0001-CC2.patch"; fi; #Runtime control of platform carrier config package (DivestOS)
fi; fi;