diff --git a/Patches/LineageOS-20.0/ASB-2024-07/bluetooth-01.patch b/Patches/LineageOS-20.0/ASB-2024-07/bluetooth-01.patch new file mode 100644 index 00000000..bba71256 --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/bluetooth-01.patch @@ -0,0 +1,63 @@ +From d39bbaa57ea3e636aa581478ae27ef9829b75718 Mon Sep 17 00:00:00 2001 +From: Brian Delwiche +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) diff --git a/Patches/LineageOS-20.0/ASB-2024-07/fwb-01.patch b/Patches/LineageOS-20.0/ASB-2024-07/fwb-01.patch new file mode 100644 index 00000000..23a44f2a --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/fwb-01.patch @@ -0,0 +1,51 @@ +From a0afe17e817eb39f3de3251f7b040a5f6eebc577 Mon Sep 17 00:00:00 2001 +From: Ivan Chiang +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 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 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(); diff --git a/Patches/LineageOS-20.0/ASB-2024-07/fwb-02.patch b/Patches/LineageOS-20.0/ASB-2024-07/fwb-02.patch new file mode 100644 index 00000000..576bf159 --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/fwb-02.patch @@ -0,0 +1,82 @@ +From cb2db1244c4668fe8b3d6cf36d0078190fa8f0af Mon Sep 17 00:00:00 2001 +From: Bishoy Gendy +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 extends Binder { + private static final int END_OF_PARCEL = 0; + private static final int ITEM_CONTINUED = 1; + ++ private final Class mListElementsClass; + private final Consumer> mConsumer; + + private final Object mLock = new Object(); +@@ -61,9 +62,11 @@ public class ParcelableListBinder 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> consumer) { ++ public ParcelableListBinder(Class listElementsClass, @NonNull Consumer> 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((list) -> { +- synchronized (mLock) { +- mQueue = list; +- } +- mHandler.post(MessageHandler.MSG_UPDATE_QUEUE); +- }); ++ return new ParcelableListBinder( ++ QueueItem.class, ++ (list) -> { ++ synchronized (mLock) { ++ mQueue = list; ++ } ++ mHandler.post(MessageHandler.MSG_UPDATE_QUEUE); ++ }); + } + + @Override diff --git a/Patches/LineageOS-20.0/ASB-2024-07/fwb-03.patch b/Patches/LineageOS-20.0/ASB-2024-07/fwb-03.patch new file mode 100644 index 00000000..1b766d35 --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/fwb-03.patch @@ -0,0 +1,37 @@ +From 93a2c9a876b978db4109a5360479e793eba5bf95 Mon Sep 17 00:00:00 2001 +From: Yi-an Chen +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); diff --git a/Patches/LineageOS-20.0/ASB-2024-07/fwb-04.patch b/Patches/LineageOS-20.0/ASB-2024-07/fwb-04.patch new file mode 100644 index 00000000..a41572e2 --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/fwb-04.patch @@ -0,0 +1,176 @@ +From ed52683e9c4960b21ff9d7a7c38bef5bfa02d4fb Mon Sep 17 00:00:00 2001 +From: Martijn Coenen +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& 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(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(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(sizeof credentials))); +- } + } + first_time = false; + } while (n_buffer->isSimpleForkCommand(minUid, fail_fn_n)); diff --git a/Patches/LineageOS-20.0/ASB-2024-07/mediaprovider-01.patch b/Patches/LineageOS-20.0/ASB-2024-07/mediaprovider-01.patch new file mode 100644 index 00000000..7edc0f96 --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/mediaprovider-01.patch @@ -0,0 +1,51 @@ +From ce7b9fd0f521cb6b038cb355b64f81f0c7524114 Mon Sep 17 00:00:00 2001 +From: Omar Eissa +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( diff --git a/Patches/LineageOS-20.0/ASB-2024-07/settings-01.patch b/Patches/LineageOS-20.0/ASB-2024-07/settings-01.patch new file mode 100644 index 00000000..aac4cb0f --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/settings-01.patch @@ -0,0 +1,292 @@ +From df49ae67f1baf3b8d3f5f0558a4512bea1e28b04 Mon Sep 17 00:00:00 2001 +From: Weng Su +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(); ++ } ++} diff --git a/Patches/LineageOS-20.0/ASB-2024-07/statsd-01.patch b/Patches/LineageOS-20.0/ASB-2024-07/statsd-01.patch new file mode 100644 index 00000000..b9231b53 --- /dev/null +++ b/Patches/LineageOS-20.0/ASB-2024-07/statsd-01.patch @@ -0,0 +1,261 @@ +From 09e63307961e3fa93d4bcb2ce73821e73b3bc8c4 Mon Sep 17 00:00:00 2001 +From: Vova Sharaienko +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 +- + using namespace std; + + namespace android { +@@ -31,8 +30,7 @@ MultiConditionTrigger::MultiConditionTrigger(const set& 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([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 + #include ++#include + + 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 mRemainingConditionNames; + std::function mTrigger; + bool mCompleted; ++ std::unique_ptr 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 + #include + ++#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 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 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 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 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 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 unique_lk(lock); ++ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; }); ++ EXPECT_TRUE(triggerCalled); ++ EXPECT_EQ(triggerCount, 0); ++ } ++} ++ + } // namespace statsd + } // namespace os + } // namespace android diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-1.patch b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-1.patch index a8529d0f..de256ee7 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-1.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-1.patch @@ -9,7 +9,7 @@ Ported from 12: b294a2ce1d0d185dbc438ac3c06c90386d5f5949 1 file changed, 30 insertions(+), 9 deletions(-) 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 96c34db79898..9fd704ac7d44 100644 +index 9c406c35c5bb..5168676689c0 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -1410,7 +1410,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-10.patch b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-10.patch index 6a87dc1d..8528b264 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-10.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-10.patch @@ -9,7 +9,7 @@ Subject: [PATCH] srt permissions: don't auto-grant denied ones when 1 file changed, 3 insertions(+), 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 f4064d1ab984..556443b40c3d 100644 +index 4b448f2ddc06..7b4d310c0923 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -1811,7 +1811,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-2.patch b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-2.patch index fbdccb61..42e498bb 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-2.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-2.patch @@ -67,7 +67,7 @@ index 2091c0502b6f..4c45fdc4de44 100644 Retrieve window content 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 9fd704ac7d44..fde265d12bf9 100644 +index 5168676689c0..734499751a2f 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -2525,7 +2525,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-3.patch b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-3.patch index ba1c877d..3c528b36 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-3.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-3.patch @@ -86,7 +86,7 @@ index 4c45fdc4de44..e0ca922bf686 100644 Read calendar events and details 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 fde265d12bf9..f4064d1ab984 100644 +index 734499751a2f..4b448f2ddc06 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -2525,7 +2525,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-5.patch b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-5.patch index ebfc727c..3d3115d9 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-5.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0013-Special_Permissions-5.patch @@ -99,7 +99,7 @@ index 000000000000..efd48cb49aa3 + private SpecialRuntimePermAppUtils() {} +} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java -index 35be1bf7e005..59c534ae07b7 100644 +index 8c51df9d320e..373f11a4f333 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -214,6 +214,7 @@ import com.android.server.pm.permission.LegacyPermissionManagerInternal; @@ -110,7 +110,7 @@ index 35be1bf7e005..59c534ae07b7 100644 import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.pkg.PackageUserState; import com.android.server.pm.pkg.PackageUserStateInternal; -@@ -6090,6 +6091,24 @@ public class PackageManagerService implements PackageSender, TestUtilityService +@@ -6107,6 +6108,24 @@ public class PackageManagerService implements PackageSender, TestUtilityService getPerUidReadTimeouts(snapshot) ).doDump(snapshot, fd, pw, args); } diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch b/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch index 7cb57453..226d10b2 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch @@ -145,7 +145,7 @@ index 6860759eea8a..a2eef62f80be 100644 OsConstants._LINUX_CAPABILITY_VERSION_3, 0); StructCapUserData[] data; diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java -index 993e4e7b4b3d..c3e6e0453b50 100644 +index 765901a043a0..199ab0093f55 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -29,6 +29,7 @@ import android.net.Credentials; @@ -156,7 +156,7 @@ index 993e4e7b4b3d..c3e6e0453b50 100644 import android.os.Trace; import android.system.ErrnoException; import android.system.Os; -@@ -247,7 +248,7 @@ class ZygoteConnection { +@@ -250,7 +251,7 @@ class ZygoteConnection { fdsToClose[1] = zygoteFd.getInt$(); } @@ -165,7 +165,7 @@ index 993e4e7b4b3d..c3e6e0453b50 100644 || !multipleOK || peer.getUid() != Process.SYSTEM_UID) { // Continue using old code for now. TODO: Handle these cases in the other path. pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, -@@ -535,6 +536,13 @@ class ZygoteConnection { +@@ -538,6 +539,13 @@ class ZygoteConnection { throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { if (!isZygote) { diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch b/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch index e7c83434..f1dd0976 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch @@ -78,10 +78,10 @@ index b1e7d15cbf4a..96b56f7bd1d6 100644 + public static native void nativeHandleRuntimeFlags(int runtimeFlags); } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java -index 4573cb2c0b59..9cc90f3ac142 100644 +index d4844be2b381..f58d6102257a 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java -@@ -539,7 +539,7 @@ class ZygoteConnection { +@@ -542,7 +542,7 @@ class ZygoteConnection { if (SystemProperties.getBoolean("sys.spawn.exec", false) && (parsedArgs.mRuntimeFlags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { ExecInit.execApplication(parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch b/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch index ee43c679..0c62f7d9 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch @@ -10,10 +10,10 @@ spawning when doing debugging. 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java -index c3e6e0453b50..4573cb2c0b59 100644 +index 199ab0093f55..d4844be2b381 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java -@@ -536,7 +536,8 @@ class ZygoteConnection { +@@ -539,7 +539,8 @@ class ZygoteConnection { throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { if (!isZygote) { diff --git a/Patches/LineageOS-20.0/android_frameworks_base/0039-package_hooks.patch b/Patches/LineageOS-20.0/android_frameworks_base/0039-package_hooks.patch index 9a7494d1..7d55d62a 100644 --- a/Patches/LineageOS-20.0/android_frameworks_base/0039-package_hooks.patch +++ b/Patches/LineageOS-20.0/android_frameworks_base/0039-package_hooks.patch @@ -159,7 +159,7 @@ index a9b624653b92..9cac3e75a698 100644 ATTR_ENABLED_CALLER); final String harmfulAppWarning = 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 556443b40c3d..ac5aadd45467 100644 +index 7b4d310c0923..dd2bce0c14a2 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -127,6 +127,7 @@ import com.android.server.LocalServices; diff --git a/Scripts/LineageOS-20.0/Patch.sh b/Scripts/LineageOS-20.0/Patch.sh index d334603b..0439c221 100644 --- a/Scripts/LineageOS-20.0/Patch.sh +++ b/Scripts/LineageOS-20.0/Patch.sh @@ -94,6 +94,7 @@ 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) 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/2024-06-05/2024-07-05/' core/version_defaults.mk; #Bump Security String #X_asb_2024-07 fi; if enterAndClear "build/soong"; then @@ -118,6 +119,7 @@ sed -i -e '76,78d;' Android.bp; #fix compile under A13 fi; 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 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 @@ -305,6 +307,7 @@ applyPatch "$DOS_PATCHES/android_packages_apps_Nfc/0001-constify_JNINativeMethod fi; 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() 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) @@ -354,6 +357,10 @@ 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) fi; +if enterAndClear "packages/modules/Bluetooth"; then +git am $DOS_PATCHES/ASB-2024-07/bluetooth-*.patch; +fi; + 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-2.patch"; #Enforce INTERNET permission per-uid instead of per-appId (GrapheneOS) @@ -379,6 +386,10 @@ 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) fi; +if enterAndClear "packages/modules/StatsD"; then +git am $DOS_PATCHES/ASB-2024-07/statsd-*.patch; +fi; + 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/0001-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS) @@ -388,6 +399,10 @@ 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 +git am $DOS_PATCHES/ASB-2024-07/mediaprovider-*.patch; +fi; + 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) fi;