18.1: Import and verify picks

https://review.lineageos.org/q/topic:R_asb_2024-03
https://review.lineageos.org/q/topic:R_asb_2024-04

Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
Tavi 2024-05-08 09:02:55 -04:00
parent 0f6b9e9baa
commit bea8f92380
No known key found for this signature in database
GPG Key ID: E599F62ECBAEAF2E
18 changed files with 1356 additions and 2 deletions

View File

@ -0,0 +1,105 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Haripriya Deshmukh <haripriya.deshmukh@ittiam.com>
Date: Tue, 19 Sep 2023 20:42:45 +0000
Subject: [PATCH] Validate OMX Params for VPx encoders
Bug: 273936274
Bug: 273937171
Bug: 273937136
Bug: 273936553
Bug: 273936601
Test: POC in bug descriptions
(cherry picked from https://partner-android-review.googlesource.com/q/commit:022086b76536cd2e19a44053271190bdf6e181f7)
(cherry picked from commit 0e4ca1cb5c16af8f1dfb0ae41941c16c104d38e8)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:90641b2799fd3940cdf0bf8a73b2f76839e651a6)
Merged-In: I9bb17112d9f0217b6af0343afecc9c943453b757
Change-Id: I9bb17112d9f0217b6af0343afecc9c943453b757
---
media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp | 10 ++++++++++
media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp | 10 ++++++++++
media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp | 9 +++++++++
3 files changed, 29 insertions(+)
diff --git a/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp
index 04737a9ccf..9198b7c327 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVP8Encoder.cpp
@@ -120,6 +120,11 @@ OMX_ERRORTYPE SoftVP8Encoder::internalSetParameter(OMX_INDEXTYPE index,
OMX_ERRORTYPE SoftVP8Encoder::internalGetVp8Params(
OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
+ if (!isValidOMXParam(vp8Params)) {
+ android_errorWriteLog(0x534e4554, "273936274");
+ return OMX_ErrorBadParameter;
+ }
+
if (vp8Params->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
@@ -133,6 +138,11 @@ OMX_ERRORTYPE SoftVP8Encoder::internalGetVp8Params(
OMX_ERRORTYPE SoftVP8Encoder::internalSetVp8Params(
const OMX_VIDEO_PARAM_VP8TYPE* vp8Params) {
+ if (!isValidOMXParam(vp8Params)) {
+ android_errorWriteLog(0x534e4554, "273937171");
+ return OMX_ErrorBadParameter;
+ }
+
if (vp8Params->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
diff --git a/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp
index 1ea1c85f76..f8495c2da4 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVP9Encoder.cpp
@@ -119,6 +119,11 @@ OMX_ERRORTYPE SoftVP9Encoder::internalSetParameter(
OMX_ERRORTYPE SoftVP9Encoder::internalGetVp9Params(
OMX_VIDEO_PARAM_VP9TYPE *vp9Params) {
+ if (!isValidOMXParam(vp9Params)) {
+ android_errorWriteLog(0x534e4554, "273936553");
+ return OMX_ErrorBadParameter;
+ }
+
if (vp9Params->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
@@ -133,6 +138,11 @@ OMX_ERRORTYPE SoftVP9Encoder::internalGetVp9Params(
OMX_ERRORTYPE SoftVP9Encoder::internalSetVp9Params(
const OMX_VIDEO_PARAM_VP9TYPE *vp9Params) {
+ if (!isValidOMXParam(vp9Params)) {
+ android_errorWriteLog(0x534e4554, "273937136");
+ return OMX_ErrorBadParameter;
+ }
+
if (vp9Params->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index d0cb0718c2..054413e7c0 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -485,6 +485,11 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetBitrateParams(
OMX_ERRORTYPE SoftVPXEncoder::internalGetAndroidVpxParams(
OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vpxAndroidParams) {
+ if (!isValidOMXParam(vpxAndroidParams)) {
+ android_errorWriteLog(0x534e4554, "273936601");
+ return OMX_ErrorBadParameter;
+ }
+
if (vpxAndroidParams->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}
@@ -501,6 +506,10 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetAndroidVpxParams(
OMX_ERRORTYPE SoftVPXEncoder::internalSetAndroidVpxParams(
const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vpxAndroidParams) {
+ if (!isValidOMXParam(vpxAndroidParams)) {
+ android_errorWriteLog(0x534e4554, "273937551");
+ return OMX_ErrorBadParameter;
+ }
if (vpxAndroidParams->nPortIndex != kOutputPortIndex) {
return OMX_ErrorUnsupportedIndex;
}

View File

@ -0,0 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Harish Mahendrakar <harish.mahendrakar@ittiam.com>
Date: Mon, 30 Oct 2023 20:38:56 +0000
Subject: [PATCH] SoftVideoDecodeOMXComponent: validate OMX params for dynamic
HDR
Bug: 273935108
Bug: 281065553
(cherry picked from https://partner-android-review.googlesource.com/q/commit:b2c67bdcf57149a5e19a04466205266dc543fd86)
(cherry picked from commit a542f2c50700ca6df93e966fe8d4c468e1a15d9a)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:80e0acc096d201e80a1b65af944b1e47c9dd6f7b)
Merged-In: I707745594a9196d8d85d4c4bb498eba3c6198b42
Change-Id: I707745594a9196d8d85d4c4bb498eba3c6198b42
---
media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index e853da9763..418302389d 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -616,6 +616,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getConfig(
DescribeHDR10PlusInfoParams* outParams =
(DescribeHDR10PlusInfoParams *)params;
+ if (!isValidOMXParam(outParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
outParams->nParamSizeUsed = info->size();
// If the buffer provided by the client does not have enough
@@ -694,6 +698,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetConfig(
const DescribeHDR10PlusInfoParams* inParams =
(DescribeHDR10PlusInfoParams *)params;
+ if (!isValidOMXParam(inParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (*frameConfig) {
// This is a request to append to the current frame config set.
// For now, we only support kDescribeHdr10PlusInfoIndex, which

View File

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Haripriya Deshmukh <haripriya.deshmukh@ittiam.com>
Date: Tue, 5 Dec 2023 18:32:38 +0000
Subject: [PATCH] Fix out of bounds read and write in onQueueFilled in outQueue
Bug: 276442130
Test: POC in bug descriptions
(cherry picked from https://partner-android-review.googlesource.com/q/commit:7aef41e59412e2f95bab5de7e33f5f04bb808643)
(cherry picked from commit 8f4cfda9fc75f1e9ba3b6dee3fbffda4b6111d64)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:208e430bc6380fafafca8041b239f835263a9d47)
Merged-In: Ic230d10048193a785f185dc6a7de6f455f9318c1
Change-Id: Ic230d10048193a785f185dc6a7de6f455f9318c1
---
media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 60750d9a61..db08030ad1 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -312,8 +312,11 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
outHeader->nFilledLen = frameSize;
List<BufferInfo *>::iterator it = outQueue.begin();
- while ((*it)->mHeader != outHeader) {
- ++it;
+ while (it != outQueue.end() && (*it)->mHeader != outHeader) {
+ ++it;
+ }
+ if (it == outQueue.end()) {
+ return;
}
BufferInfo *outInfo = *it;

View File

@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: kumarashishg <kumarashishg@google.com>
Date: Mon, 17 Jul 2023 12:01:18 +0000
Subject: [PATCH] Resolve custom printer icon boundary exploit.
Because Settings grants the INTERACT_ACROSS_USERS_FULL permission, an exploit is possible where the third party print plugin service can pass other's User Icon URI. This CL provides a lightweight solution for parsing the image URI to detect profile exploitation.
Bug: 281525042
Test: Build and flash the code. Try to reproduce the issue with
mentioned steps in the bug
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0e0693ca9cb408d0dc82f6c6b3feb453fc8ddd83)
Merged-In: Iaaa6fe2a627a265c4d1d7b843a033a132e1fe2ce
Change-Id: Iaaa6fe2a627a265c4d1d7b843a033a132e1fe2ce
---
.../server/print/PrintManagerService.java | 35 ++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index d064f7ee62c3..e570c4452be7 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -253,12 +253,45 @@ public final class PrintManagerService extends SystemService {
}
final long identity = Binder.clearCallingIdentity();
try {
- return userState.getCustomPrinterIcon(printerId);
+ Icon icon = userState.getCustomPrinterIcon(printerId);
+ return validateIconUserBoundary(icon);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
+ /**
+ * Validates the custom printer icon to see if it's not in the calling user space.
+ * If the condition is not met, return null. Otherwise, return the original icon.
+ *
+ * @param icon
+ * @return icon (validated)
+ */
+ private Icon validateIconUserBoundary(Icon icon) {
+ // Refer to Icon#getUriString for context. The URI string is invalid for icons of
+ // incompatible types.
+ if (icon != null && (icon.getType() == Icon.TYPE_URI
+ || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
+ String encodedUser = icon.getUri().getEncodedUserInfo();
+
+ // If there is no encoded user, the URI is calling into the calling user space
+ if (encodedUser != null) {
+ int userId = Integer.parseInt(encodedUser);
+ // resolve encoded user
+ final int resolvedUserId = resolveCallingUserEnforcingPermissions(userId);
+
+ synchronized (mLock) {
+ // Only the current group members can get the printer icons.
+ if (resolveCallingProfileParentLocked(resolvedUserId)
+ != getCurrentUserId()) {
+ return null;
+ }
+ }
+ }
+ }
+ return icon;
+ }
+
@Override
public void cancelPrintJob(PrintJobId printJobId, int appId, int userId) {
if (printJobId == null) {

View File

@ -0,0 +1,84 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Buynytskyy <alexbuy@google.com>
Date: Thu, 2 Nov 2023 15:15:48 -0700
Subject: [PATCH] Validate package names passed to the installer.
Bug: 308989388
Bug: 307532206
Test: atest android.content.pm.cts.PackageManagerTest
(cherry picked from commit 1f445474cd1b902b2e7292a0d24e58f020fd51e7)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a7e48c8d7e00962d335b0076266a5df98d41a21c)
Merged-In: I840c9c9af5752b3901d4719a13e7908faa43ab04
Change-Id: I840c9c9af5752b3901d4719a13e7908faa43ab04
---
.../server/pm/PackageInstallerService.java | 30 +++++++++++++++----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index e770f0cafa32..7e67021e3b84 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -20,6 +20,7 @@ import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.Manifest;
+import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
@@ -43,6 +44,7 @@ import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
import android.content.pm.ParceledListSlice;
import android.content.pm.VersionedPackage;
import android.graphics.Bitmap;
@@ -571,17 +573,22 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
// App package name and label length is restricted so that really long strings aren't
// written to disk.
- if (params.appPackageName != null
- && params.appPackageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) {
+ if (params.appPackageName != null && !isValidPackageName(params.appPackageName)) {
params.appPackageName = null;
}
params.appLabel = TextUtils.trimToSize(params.appLabel,
PackageItemInfo.MAX_SAFE_LABEL_LENGTH);
- String requestedInstallerPackageName = (params.installerPackageName != null
- && params.installerPackageName.length() < SessionParams.MAX_PACKAGE_NAME_LENGTH)
- ? params.installerPackageName : installerPackageName;
+ // Validate installer package name.
+ if (params.installerPackageName != null && !isValidPackageName(
+ params.installerPackageName)) {
+ params.installerPackageName = null;
+ }
+
+ String requestedInstallerPackageName =
+ params.installerPackageName != null ? params.installerPackageName
+ : installerPackageName;
if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
params.installFlags |= PackageManager.INSTALL_FROM_ADB;
@@ -876,6 +883,19 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
throw new IllegalStateException("Failed to allocate session ID");
}
+ private static boolean isValidPackageName(@NonNull String packageName) {
+ if (packageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) {
+ return false;
+ }
+ // "android" is a valid package name
+ String errorMessage = PackageParser.validateName(
+ packageName, /* requireSeparator= */ false, /* requireFilename */ true);
+ if (errorMessage != null) {
+ return false;
+ }
+ return true;
+ }
+
private File getTmpSessionDir(String volumeUuid) {
return Environment.getDataAppDirectory(volumeUuid);
}

View File

@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alex Buynytskyy <alexbuy@google.com>
Date: Wed, 20 Dec 2023 01:50:36 +0000
Subject: [PATCH] Disallow system apps to be installed/updated as instant.
Bug: 299441833
Test: atest android.content.pm.cts.PackageManagerTest
(cherry picked from commit 496e78a1951f2ed69290f03c5625c0f8382f4d31)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0d0f185c0d526c1dac0a8894b2c2f2e378328d73)
Merged-In: Idd89a6dd72f0e68259095f677185f0494391025c
Change-Id: Idd89a6dd72f0e68259095f677185f0494391025c
---
.../core/java/com/android/server/pm/PackageManagerService.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9c71a29af107..1f6c113969c0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13397,6 +13397,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkgSetting == null) {
return PackageManager.INSTALL_FAILED_INVALID_URI;
}
+ if (instantApp && (pkgSetting.isSystem() || isUpdatedSystemApp(pkgSetting))) {
+ return PackageManager.INSTALL_FAILED_INVALID_URI;
+ }
if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
// only allow the existing package to be used if it's installed as a full
// application for at least one user

View File

@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Dementyev <dementyev@google.com>
Date: Wed, 3 Jan 2024 09:26:56 -0800
Subject: [PATCH] Close AccountManagerService.session after timeout.
Bug: 303905130
Bug: 316893159
Test: manual
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:bb53f192e0ceaa026a083da156ef0cb0140f0c09)
Merged-In: Ib4cebf1750fc6324dc1c8853e0d716ea5e8ec073
Change-Id: Ib4cebf1750fc6324dc1c8853e0d716ea5e8ec073
---
.../android/server/accounts/AccountManagerService.java | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ae72a65692e7..8a9ddda50d63 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -182,6 +182,7 @@ public class AccountManagerService
final MessageHandler mHandler;
+ private static final int TIMEOUT_DELAY_MS = 1000 * 60 * 15;
// Messages that can be sent on mHandler
private static final int MESSAGE_TIMED_OUT = 3;
private static final int MESSAGE_COPY_SHARED_ACCOUNT = 4;
@@ -4756,6 +4757,7 @@ public class AccountManagerService
synchronized (mSessions) {
mSessions.put(toString(), this);
}
+ scheduleTimeout();
if (response != null) {
try {
response.asBinder().linkToDeath(this, 0 /* flags */);
@@ -4922,6 +4924,11 @@ public class AccountManagerService
}
}
+ private void scheduleTimeout() {
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS);
+ }
+
public void cancelTimeout() {
mHandler.removeMessages(MESSAGE_TIMED_OUT, this);
}
@@ -4958,6 +4965,9 @@ public class AccountManagerService
public void onTimedOut() {
IAccountManagerResponse response = getResponseAndClose();
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Session.onTimedOut");
+ }
if (response != null) {
try {
response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION,

View File

@ -0,0 +1,87 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kiran Ramachandra <kiranmr@google.com>
Date: Tue, 19 Dec 2023 21:33:56 +0000
Subject: [PATCH] BACKPORT: Added limitations for attributions to handle
invalid cases
Bug: 304983146
Test: Modified and introduced new tests to verify change -> atest CtsAppOpsTestCases:AttributionTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:63d122cf0e18ff6d8e77b7bcc8f0f3f8d4e4a018)
Merged-In: Iee26fdb9cf1ca0fa8905e22732c32ec7d9b80fea
Change-Id: Iee26fdb9cf1ca0fa8905e22732c32ec7d9b80fea
---
.../android/server/appop/AppOpsService.java | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 63b5af59c3c1..ae417e53024e 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3092,6 +3092,11 @@ public class AppOpsService extends IAppOpsService.Stub {
return AppOpsManager.MODE_ERRORED;
}
+ if (proxyAttributionTag != null
+ && !isAttributionTagDefined(packageName, proxyPackageName, proxyAttributionTag)) {
+ proxyAttributionTag = null;
+ }
+
synchronized (this) {
final Ops ops = getOpsLocked(uid, packageName, attributionTag, bypass,
true /* edit */);
@@ -3958,6 +3963,55 @@ public class AppOpsService extends IAppOpsService.Stub {
return bypass;
}
+ private boolean isAttributionInPackage(@Nullable AndroidPackage pkg,
+ @Nullable String attributionTag) {
+ if (pkg == null) {
+ return false;
+ } else if (attributionTag == null) {
+ return true;
+ }
+ if (pkg.getAttributions() != null) {
+ int numAttributions = pkg.getAttributions().size();
+ for (int i = 0; i < numAttributions; i++) {
+ if (pkg.getAttributions().get(i).tag.equals(attributionTag)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks to see if the attribution tag is defined in either package or proxyPackage.
+ * This method is intended for ProxyAttributionTag validation and returns false
+ * if it does not exist in either one of them.
+ *
+ * @param packageName Name of the package
+ * @param proxyPackageName Name of the proxy package
+ * @param attributionTag attribution tag to be checked
+ *
+ * @return boolean specifying if attribution tag is valid or not
+ */
+ private boolean isAttributionTagDefined(@Nullable String packageName,
+ @Nullable String proxyPackageName,
+ @Nullable String attributionTag) {
+ if (packageName == null) {
+ return false;
+ } else if (attributionTag == null) {
+ return true;
+ }
+ PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
+ if (proxyPackageName != null) {
+ AndroidPackage proxyPkg = pmInt.getPackage(proxyPackageName);
+ if (proxyPkg != null && isAttributionInPackage(proxyPkg, attributionTag)) {
+ return true;
+ }
+ }
+ AndroidPackage pkg = pmInt.getPackage(packageName);
+ return isAttributionInPackage(pkg, attributionTag);
+ }
+
/**
* Get (and potentially create) ops.
*

View File

@ -0,0 +1,116 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Beverly <beverlyt@google.com>
Date: Thu, 18 Jan 2024 20:13:52 +0000
Subject: [PATCH] isUserInLockDown can be true when there are other strong auth
requirements
Bug: 315206668
Bug: 218495634
Flag: None
Test: manual, atest LockPatternUtilsTest
(cherry picked from commit d341f1ecdb011d24b17358f115391b3f997cb179)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ba8dfc68aada76127abafdb17d0f0896cc14447a)
Merged-In: I5e979a7822dd7254b4579ab28ecf96df1db44179
Change-Id: I5e979a7822dd7254b4579ab28ecf96df1db44179
---
.../internal/widget/LockPatternUtils.java | 4 +-
.../internal/util/LockPatternUtilsTest.java | 40 ++++++++++++++++---
2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e0a2803ea60b..d0e82ec29c80 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1484,8 +1484,8 @@ public class LockPatternUtils {
}
public boolean isUserInLockdown(int userId) {
- return getStrongAuthForUser(userId)
- == StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+ return (getStrongAuthForUser(userId)
+ & StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0;
}
private static class WrappedCallback extends ICheckCredentialProgressCallback.Stub {
diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
index 50e8474e8d52..01e840abb953 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java
@@ -19,6 +19,9 @@ package com.android.internal.util;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
@@ -48,12 +51,15 @@ import org.mockito.Mockito;
@SmallTest
public class LockPatternUtilsTest {
+ private ILockSettings mLockSettings;
+ private static final int USER_ID = 1;
private static final int DEMO_USER_ID = 5;
private LockPatternUtils mLockPatternUtils;
private void configureTest(boolean isSecure, boolean isDemoUser, int deviceDemoMode)
throws Exception {
+ mLockSettings = Mockito.mock(ILockSettings.class);
final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
final MockContentResolver cr = new MockContentResolver(context);
@@ -61,15 +67,14 @@ public class LockPatternUtilsTest {
when(context.getContentResolver()).thenReturn(cr);
Settings.Global.putInt(cr, Settings.Global.DEVICE_DEMO_MODE, deviceDemoMode);
- final ILockSettings ils = Mockito.mock(ILockSettings.class);
- when(ils.getCredentialType(DEMO_USER_ID)).thenReturn(
+ when(mLockSettings.getCredentialType(DEMO_USER_ID)).thenReturn(
isSecure ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
: LockPatternUtils.CREDENTIAL_TYPE_NONE);
- when(ils.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, DEMO_USER_ID))
- .thenReturn((long) PASSWORD_QUALITY_MANAGED);
+ when(mLockSettings.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED,
+ DEMO_USER_ID)).thenReturn((long) PASSWORD_QUALITY_MANAGED);
// TODO(b/63758238): stop spying the class under test
mLockPatternUtils = spy(new LockPatternUtils(context));
- when(mLockPatternUtils.getLockSettings()).thenReturn(ils);
+ when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
doReturn(true).when(mLockPatternUtils).hasSecureLockScreen();
final UserInfo userInfo = Mockito.mock(UserInfo.class);
@@ -79,6 +84,31 @@ public class LockPatternUtilsTest {
when(context.getSystemService(Context.USER_SERVICE)).thenReturn(um);
}
+ @Test
+ public void isUserInLockDown() throws Exception {
+ configureTest(true, false, 2);
+
+ // GIVEN strong auth not required
+ when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn(STRONG_AUTH_NOT_REQUIRED);
+
+ // THEN user isn't in lockdown
+ assertFalse(mLockPatternUtils.isUserInLockdown(USER_ID));
+
+ // GIVEN lockdown
+ when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn(
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+
+ // THEN user is in lockdown
+ assertTrue(mLockPatternUtils.isUserInLockdown(USER_ID));
+
+ // GIVEN lockdown and lockout
+ when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn(
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN | STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
+
+ // THEN user is in lockdown
+ assertTrue(mLockPatternUtils.isUserInLockdown(USER_ID));
+ }
+
@Test
public void isLockScreenDisabled_isDemoUser_true() throws Exception {
configureTest(false, true, 2);

View File

@ -0,0 +1,345 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tetiana Meronyk <tetianameronyk@google.com>
Date: Wed, 10 Jan 2024 16:25:13 +0000
Subject: [PATCH] Fix security vulnerability that creates user with no
restrictions when accountOptions are too long.
Bug: 293602970
Test: atest UserManagerTest#testAddUserAccountData_validStringValuesAreSaved_validBundleIsSaved && atest UserManagerTest#testAddUserAccountData_invalidStringValuesAreTruncated_invalidBundleIsDropped
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8dc6feaee7c0a5cea093b5280acaad862921cf3e)
Merged-In: I23c971f671546ac085060add89485cfac6691ca3
Change-Id: I23c971f671546ac085060add89485cfac6691ca3
---
core/java/android/os/PersistableBundle.java | 37 +++++++
core/java/android/os/UserManager.java | 23 +++-
.../app/ConfirmUserCreationActivity.java | 12 +++
.../android/server/pm/UserManagerService.java | 29 ++---
.../android/server/pm/UserManagerTest.java | 102 ++++++++++++++++++
5 files changed, 187 insertions(+), 16 deletions(-)
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index 7c7e2137aa17..b2adb5eb434c 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -275,6 +275,43 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa
XmlUtils.writeMapXml(mMap, out, this);
}
+ /**
+ * Checks whether all keys and values are within the given character limit.
+ * Note: Maximum character limit of String that can be saved to XML as part of bundle is 65535.
+ * Otherwise IOException is thrown.
+ * @param limit length of String keys and values in the PersistableBundle, including nested
+ * PersistableBundles to check against.
+ *
+ * @hide
+ */
+ public boolean isBundleContentsWithinLengthLimit(int limit) {
+ unparcel();
+ if (mMap == null) {
+ return true;
+ }
+ for (int i = 0; i < mMap.size(); i++) {
+ if (mMap.keyAt(i) != null && mMap.keyAt(i).length() > limit) {
+ return false;
+ }
+ final Object value = mMap.valueAt(i);
+ if (value instanceof String && ((String) value).length() > limit) {
+ return false;
+ } else if (value instanceof String[]) {
+ String[] stringArray = (String[]) value;
+ for (int j = 0; j < stringArray.length; j++) {
+ if (stringArray[j] != null
+ && stringArray[j].length() > limit) {
+ return false;
+ }
+ }
+ } else if (value instanceof PersistableBundle
+ && !((PersistableBundle) value).isBundleContentsWithinLengthLimit(limit)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/** @hide */
static class MyReadMapCallback implements XmlUtils.ReadMapCallback {
@Override
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2465b0e41876..9606ce97a3b0 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -91,6 +91,21 @@ public class UserManager {
private Boolean mIsManagedProfileCached;
private Boolean mIsProfileCached;
+ /** Maximum length of username.
+ * @hide
+ */
+ public static final int MAX_USER_NAME_LENGTH = 100;
+
+ /** Maximum length of user property String value.
+ * @hide
+ */
+ public static final int MAX_ACCOUNT_STRING_LENGTH = 500;
+
+ /** Maximum length of account options String values.
+ * @hide
+ */
+ public static final int MAX_ACCOUNT_OPTIONS_LENGTH = 1000;
+
/**
* User type representing a {@link UserHandle#USER_SYSTEM system} user that is a human user.
* This type of user cannot be created; it can only pre-exist on first boot.
@@ -2974,15 +2989,15 @@ public class UserManager {
* time, the preferred user name and account information are used by the setup process for that
* user.
*
- * @param userName Optional name to assign to the user.
+ * @param userName Optional name to assign to the user. Character limit is 100.
* @param accountName Optional account name that will be used by the setup wizard to initialize
- * the user.
+ * the user. Character limit is 500.
* @param accountType Optional account type for the account to be created. This is required
- * if the account name is specified.
+ * if the account name is specified. Character limit is 500.
* @param accountOptions Optional bundle of data to be passed in during account creation in the
* new user via {@link AccountManager#addAccount(String, String, String[],
* Bundle, android.app.Activity, android.accounts.AccountManagerCallback,
- * Handler)}.
+ * Handler)}. Character limit is 1000.
* @return An Intent that can be launched from an Activity.
* @see #USER_CREATION_FAILED_NOT_PERMITTED
* @see #USER_CREATION_FAILED_NO_MORE_USERS
diff --git a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
index 03da9bc939ec..74dedc38a922 100644
--- a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
+++ b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java
@@ -110,6 +110,14 @@ public class ConfirmUserCreationActivity extends AlertActivity
if (cantCreateUser) {
setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED);
return null;
+ } else if (!(isUserPropertyWithinLimit(mUserName, UserManager.MAX_USER_NAME_LENGTH)
+ && isUserPropertyWithinLimit(mAccountName, UserManager.MAX_ACCOUNT_STRING_LENGTH)
+ && isUserPropertyWithinLimit(mAccountType, UserManager.MAX_ACCOUNT_STRING_LENGTH))
+ || (mAccountOptions != null && !mAccountOptions.isBundleContentsWithinLengthLimit(
+ UserManager.MAX_ACCOUNT_OPTIONS_LENGTH))) {
+ setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED);
+ Log.i(TAG, "User properties must not exceed their character limits");
+ return null;
} else if (cantCreateAnyMoreUsers) {
setResult(UserManager.USER_CREATION_FAILED_NO_MORE_USERS);
return null;
@@ -137,4 +145,8 @@ public class ConfirmUserCreationActivity extends AlertActivity
}
finish();
}
+
+ private boolean isUserPropertyWithinLimit(String property, int limit) {
+ return property == null || property.length() <= limit;
+ }
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4a9d6f6ef5ff..88c4223d0925 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -240,8 +240,6 @@ public class UserManagerService extends IUserManager.Stub {
private static final int USER_VERSION = 9;
- private static final int MAX_USER_STRING_LENGTH = 500;
-
private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
static final int WRITE_USER_MSG = 1;
@@ -2938,16 +2936,18 @@ public class UserManagerService extends IUserManager.Stub {
if (userData.persistSeedData) {
if (userData.seedAccountName != null) {
serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME,
- truncateString(userData.seedAccountName));
+ truncateString(userData.seedAccountName,
+ UserManager.MAX_ACCOUNT_STRING_LENGTH));
}
if (userData.seedAccountType != null) {
serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE,
- truncateString(userData.seedAccountType));
+ truncateString(userData.seedAccountType,
+ UserManager.MAX_ACCOUNT_STRING_LENGTH));
}
}
if (userInfo.name != null) {
serializer.startTag(null, TAG_NAME);
- serializer.text(truncateString(userInfo.name));
+ serializer.text(truncateString(userInfo.name, UserManager.MAX_USER_NAME_LENGTH));
serializer.endTag(null, TAG_NAME);
}
synchronized (mRestrictionsLock) {
@@ -2987,11 +2987,11 @@ public class UserManagerService extends IUserManager.Stub {
serializer.endDocument();
}
- private String truncateString(String original) {
- if (original == null || original.length() <= MAX_USER_STRING_LENGTH) {
+ private String truncateString(String original, int limit) {
+ if (original == null || original.length() <= limit) {
return original;
}
- return original.substring(0, MAX_USER_STRING_LENGTH);
+ return original.substring(0, limit);
}
/*
@@ -3409,7 +3409,7 @@ public class UserManagerService extends IUserManager.Stub {
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
boolean preCreate, @Nullable String[] disallowedPackages,
@NonNull TimingsTraceAndSlog t) throws UserManager.CheckedUserOperationException {
- String truncatedName = truncateString(name);
+ String truncatedName = truncateString(name, UserManager.MAX_USER_NAME_LENGTH);
final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
if (userTypeDetails == null) {
Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType);
@@ -4619,9 +4619,14 @@ public class UserManagerService extends IUserManager.Stub {
Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId);
return;
}
- userData.seedAccountName = truncateString(accountName);
- userData.seedAccountType = truncateString(accountType);
- userData.seedAccountOptions = accountOptions;
+ userData.seedAccountName = truncateString(accountName,
+ UserManager.MAX_ACCOUNT_STRING_LENGTH);
+ userData.seedAccountType = truncateString(accountType,
+ UserManager.MAX_ACCOUNT_STRING_LENGTH);
+ if (accountOptions != null && accountOptions.isBundleContentsWithinLengthLimit(
+ UserManager.MAX_ACCOUNT_OPTIONS_LENGTH)) {
+ userData.seedAccountOptions = accountOptions;
+ }
userData.persistSeedData = persist;
}
if (persist) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 44bb58f62253..e7bb3ef42136 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -19,6 +19,7 @@ package com.android.server.pm;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import static org.testng.Assert.assertThrows;
@@ -33,6 +34,7 @@ import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -879,6 +881,106 @@ public final class UserManagerTest {
assertThat(userInfo.name).isEqualTo(newName);
}
+ @Test
+ public void testAddUserAccountData_validStringValuesAreSaved_validBundleIsSaved() {
+ assumeManagedUsersSupported();
+
+ String userName = "User";
+ String accountName = "accountName";
+ String accountType = "accountType";
+ String arrayKey = "StringArrayKey";
+ String stringKey = "StringKey";
+ String intKey = "IntKey";
+ String nestedBundleKey = "PersistableBundleKey";
+ String value1 = "Value 1";
+ String value2 = "Value 2";
+ String value3 = "Value 3";
+
+ UserInfo userInfo = mUserManager.createUser(userName,
+ UserManager.USER_TYPE_FULL_SECONDARY, 0);
+
+ PersistableBundle accountOptions = new PersistableBundle();
+ String[] stringArray = {value1, value2};
+ accountOptions.putInt(intKey, 1234);
+ PersistableBundle nested = new PersistableBundle();
+ nested.putString(stringKey, value3);
+ accountOptions.putPersistableBundle(nestedBundleKey, nested);
+ accountOptions.putStringArray(arrayKey, stringArray);
+
+ mUserManager.clearSeedAccountData();
+ mUserManager.setSeedAccountData(mContext.getUserId(), accountName,
+ accountType, accountOptions);
+
+ //assert userName accountName and accountType were saved correctly
+ assertTrue(mUserManager.getUserInfo(userInfo.id).name.equals(userName));
+ assertTrue(mUserManager.getSeedAccountName().equals(accountName));
+ assertTrue(mUserManager.getSeedAccountType().equals(accountType));
+
+ //assert bundle with correct values was added
+ assertThat(mUserManager.getSeedAccountOptions().containsKey(arrayKey)).isTrue();
+ assertThat(mUserManager.getSeedAccountOptions().getPersistableBundle(nestedBundleKey)
+ .getString(stringKey)).isEqualTo(value3);
+ assertThat(mUserManager.getSeedAccountOptions().getStringArray(arrayKey)[0])
+ .isEqualTo(value1);
+
+ mUserManager.removeUser(userInfo.id);
+ }
+
+ @Test
+ public void testAddUserAccountData_invalidStringValuesAreTruncated_invalidBundleIsDropped() {
+ assumeManagedUsersSupported();
+
+ String tooLongString = generateLongString();
+ String userName = "User " + tooLongString;
+ String accountType = "Account Type " + tooLongString;
+ String accountName = "accountName " + tooLongString;
+ String arrayKey = "StringArrayKey";
+ String stringKey = "StringKey";
+ String intKey = "IntKey";
+ String nestedBundleKey = "PersistableBundleKey";
+ String value1 = "Value 1";
+ String value2 = "Value 2";
+
+ UserInfo userInfo = mUserManager.createUser(userName,
+ UserManager.USER_TYPE_FULL_SECONDARY, 0);
+
+ PersistableBundle accountOptions = new PersistableBundle();
+ String[] stringArray = {value1, value2};
+ accountOptions.putInt(intKey, 1234);
+ PersistableBundle nested = new PersistableBundle();
+ nested.putString(stringKey, tooLongString);
+ accountOptions.putPersistableBundle(nestedBundleKey, nested);
+ accountOptions.putStringArray(arrayKey, stringArray);
+ mUserManager.clearSeedAccountData();
+ mUserManager.setSeedAccountData(mContext.getUserId(), accountName,
+ accountType, accountOptions);
+
+ //assert userName was truncated
+ assertTrue(mUserManager.getUserInfo(userInfo.id).name.length()
+ == UserManager.MAX_USER_NAME_LENGTH);
+
+ //assert accountName and accountType got truncated
+ assertTrue(mUserManager.getSeedAccountName().length()
+ == UserManager.MAX_ACCOUNT_STRING_LENGTH);
+ assertTrue(mUserManager.getSeedAccountType().length()
+ == UserManager.MAX_ACCOUNT_STRING_LENGTH);
+
+ //assert bundle with invalid values was dropped
+ assertThat(mUserManager.getSeedAccountOptions() == null).isTrue();
+
+ mUserManager.removeUser(userInfo.id);
+ }
+
+ private String generateLongString() {
+ String partialString = "Test Name Test Name Test Name Test Name Test Name Test Name Test "
+ + "Name Test Name Test Name Test Name "; //String of length 100
+ StringBuilder resultString = new StringBuilder();
+ for (int i = 0; i < 600; i++) {
+ resultString.append(partialString);
+ }
+ return resultString.toString();
+ }
+
private boolean isPackageInstalledForUser(String packageName, int userId) {
try {
return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null;

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Tue, 28 Nov 2023 19:57:20 +0000
Subject: [PATCH] Fix an OOB bug in smp_proc_sec_req
This is a backport of I400cfa3523c6d8b25c233205748c2db5dc803d1d
Bug: 300903400
Test: m com.android.btservices
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:970c95d7c06c909c34a849587f701098129fc2ef)
Merged-In: Id4c65801ff8519aff18b24007e344934493cab55
Change-Id: Id4c65801ff8519aff18b24007e344934493cab55
---
stack/smp/smp_act.cc | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index 03d73f781..c1f143e92 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -423,6 +423,13 @@ void smp_send_ltk_reply(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
* Description process security request.
******************************************************************************/
void smp_proc_sec_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
+ if (smp_command_has_invalid_length(p_cb)) {
+ 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;
+ }
+
tBTM_LE_AUTH_REQ auth_req = *(tBTM_LE_AUTH_REQ*)p_data->p_data;
tBTM_BLE_SEC_REQ_ACT sec_req_act;

View File

@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Fri, 15 Dec 2023 22:55:33 +0000
Subject: [PATCH] Reland: Fix an OOB write bug in attp_build_value_cmd
This is a backport of I291fd665a68d90813b8c21c80d23cc438f84f285
Bug: 295887535
Bug: 315127634
Test: m com.android.btservices
Test: atest net_test_stack_gatt
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:70f7ff2b34e6683301c9c6cd021e1ddef76c5b1c)
Merged-In: Ieffac6db5c6359b071efc599f7a70de609b80b72
Change-Id: Ieffac6db5c6359b071efc599f7a70de609b80b72
---
stack/gatt/att_protocol.cc | 56 ++++++++++++++++++++++++++++++--------
1 file changed, 45 insertions(+), 11 deletions(-)
diff --git a/stack/gatt/att_protocol.cc b/stack/gatt/att_protocol.cc
index cdf472e40..aaf1a53a3 100644
--- a/stack/gatt/att_protocol.cc
+++ b/stack/gatt/att_protocol.cc
@@ -278,46 +278,80 @@ BT_HDR* attp_build_opcode_cmd(uint8_t op_code) {
BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code,
uint16_t handle, uint16_t offset, uint16_t len,
uint8_t* p_data) {
- uint8_t *p, *pp, pair_len, *p_pair_len;
+ uint8_t *p, *pp, *p_pair_len;
+ size_t pair_len;
+ size_t size_now = 1;
+
+#define CHECK_SIZE() \
+ do { \
+ if (size_now > payload_size) { \
+ LOG(ERROR) << "payload size too small"; \
+ osi_free(p_buf); \
+ return nullptr; \
+ } \
+ } while (false)
+
BT_HDR* p_buf =
(BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
+
+ CHECK_SIZE();
UINT8_TO_STREAM(p, op_code);
p_buf->offset = L2CAP_MIN_OFFSET;
- p_buf->len = 1;
if (op_code == GATT_RSP_READ_BY_TYPE) {
- p_pair_len = p;
+ p_pair_len = p++;
pair_len = len + 2;
- UINT8_TO_STREAM(p, pair_len);
- p_buf->len += 1;
+ size_now += 1;
+ CHECK_SIZE();
+ // this field will be backfilled in the end of this function
}
+
if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) {
+ size_now += 2;
+ CHECK_SIZE();
UINT16_TO_STREAM(p, handle);
- p_buf->len += 2;
}
if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
+ size_now += 2;
+ CHECK_SIZE();
UINT16_TO_STREAM(p, offset);
- p_buf->len += 2;
}
if (len > 0 && p_data != NULL) {
/* ensure data not exceed MTU size */
- if (payload_size - p_buf->len < len) {
- len = payload_size - p_buf->len;
+ if (payload_size - size_now < len) {
+ len = payload_size - size_now;
/* update handle value pair length */
- if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);
+ if (op_code == GATT_RSP_READ_BY_TYPE) {
+ pair_len = (len + 2);
+ }
LOG(WARNING) << StringPrintf(
"attribute value too long, to be truncated to %d", len);
}
+ size_now += len;
+ CHECK_SIZE();
ARRAY_TO_STREAM(p, p_data, len);
- p_buf->len += len;
}
+ // backfill pair len field
+ if (op_code == GATT_RSP_READ_BY_TYPE) {
+ if (pair_len > UINT8_MAX) {
+ LOG(ERROR) << StringPrintf("pair_len greater than %d", UINT8_MAX);
+ osi_free(p_buf);
+ return nullptr;
+ }
+
+ *p_pair_len = (uint8_t)pair_len;
+ }
+
+#undef CHECK_SIZE
+
+ p_buf->len = (uint16_t)size_now;
return p_buf;
}

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Tue, 9 Jan 2024 22:38:20 +0000
Subject: [PATCH] Fix a security bypass issue in
access_secure_service_from_temp_bond
Backport I48df2c2d77810077e97d4131540277273d441998
to rvc-dev
Bug: 318374503
Test: m com.android.btservices | manual test against PoC | QA
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e908c16d9157b9e4a936117f06b8f964cf8386b8)
Merged-In: Ib7cf66019b3d45a2a23d235ad5f9dc406394456f
Change-Id: Ib7cf66019b3d45a2a23d235ad5f9dc406394456f
---
stack/btm/btm_sec.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 2f973ee0b..1eba879e3 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -237,8 +237,7 @@ static bool access_secure_service_from_temp_bond(const tBTM_SEC_DEV_REC* p_dev_r
bool locally_initiated,
uint16_t security_req) {
return !locally_initiated && (security_req & BTM_SEC_IN_AUTHENTICATE) &&
- btm_dev_authenticated(p_dev_rec) &&
- p_dev_rec->bond_type == BOND_TYPE_TEMPORARY;
+ p_dev_rec->bond_type == BOND_TYPE_TEMPORARY;
}
/*******************************************************************************

View File

@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Tue, 28 Nov 2023 19:57:20 +0000
Subject: [PATCH] Fix an OOB bug in smp_proc_sec_req
This is a backport of I400cfa3523c6d8b25c233205748c2db5dc803d1d
Bug: 300903400
Test: m com.android.btservices
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:970c95d7c06c909c34a849587f701098129fc2ef)
Merged-In: Id4c65801ff8519aff18b24007e344934493cab55
Change-Id: Id4c65801ff8519aff18b24007e344934493cab55
---
stack/smp/smp_act.cc | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index 5ba96a65d..c2023e421 100755
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -439,6 +439,13 @@ void smp_send_ltk_reply(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
* Description process security request.
******************************************************************************/
void smp_proc_sec_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
+ if (smp_command_has_invalid_length(p_cb)) {
+ 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;
+ }
+
tBTM_LE_AUTH_REQ auth_req = *(tBTM_LE_AUTH_REQ*)p_data->p_data;
tBTM_BLE_SEC_REQ_ACT sec_req_act;

View File

@ -0,0 +1,115 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Fri, 15 Dec 2023 22:55:33 +0000
Subject: [PATCH] Reland: Fix an OOB write bug in attp_build_value_cmd
This is a backport of I291fd665a68d90813b8c21c80d23cc438f84f285
Bug: 295887535
Bug: 315127634
Test: m com.android.btservices
Test: atest net_test_stack_gatt
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:70f7ff2b34e6683301c9c6cd021e1ddef76c5b1c)
Merged-In: Ieffac6db5c6359b071efc599f7a70de609b80b72
Change-Id: Ieffac6db5c6359b071efc599f7a70de609b80b72
---
stack/gatt/att_protocol.cc | 56 ++++++++++++++++++++++++++++++--------
1 file changed, 45 insertions(+), 11 deletions(-)
diff --git a/stack/gatt/att_protocol.cc b/stack/gatt/att_protocol.cc
index d1e0ece59..41839b072 100644
--- a/stack/gatt/att_protocol.cc
+++ b/stack/gatt/att_protocol.cc
@@ -278,46 +278,80 @@ BT_HDR* attp_build_opcode_cmd(uint8_t op_code) {
BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code,
uint16_t handle, uint16_t offset, uint16_t len,
uint8_t* p_data) {
- uint8_t *p, *pp, pair_len, *p_pair_len;
+ uint8_t *p, *pp, *p_pair_len;
+ size_t pair_len;
+ size_t size_now = 1;
+
+#define CHECK_SIZE() \
+ do { \
+ if (size_now > payload_size) { \
+ LOG(ERROR) << "payload size too small"; \
+ osi_free(p_buf); \
+ return nullptr; \
+ } \
+ } while (false)
+
BT_HDR* p_buf =
(BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET;
+
+ CHECK_SIZE();
UINT8_TO_STREAM(p, op_code);
p_buf->offset = L2CAP_MIN_OFFSET;
- p_buf->len = 1;
if (op_code == GATT_RSP_READ_BY_TYPE) {
- p_pair_len = p;
+ p_pair_len = p++;
pair_len = len + 2;
- UINT8_TO_STREAM(p, pair_len);
- p_buf->len += 1;
+ size_now += 1;
+ CHECK_SIZE();
+ // this field will be backfilled in the end of this function
}
+
if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) {
+ size_now += 2;
+ CHECK_SIZE();
UINT16_TO_STREAM(p, handle);
- p_buf->len += 2;
}
if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
+ size_now += 2;
+ CHECK_SIZE();
UINT16_TO_STREAM(p, offset);
- p_buf->len += 2;
}
if (len > 0 && p_data != NULL) {
/* ensure data not exceed MTU size */
- if (payload_size - p_buf->len < len) {
- len = payload_size - p_buf->len;
+ if (payload_size - size_now < len) {
+ len = payload_size - size_now;
/* update handle value pair length */
- if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2);
+ if (op_code == GATT_RSP_READ_BY_TYPE) {
+ pair_len = (len + 2);
+ }
LOG(WARNING) << StringPrintf(
"attribute value too long, to be truncated to %d", len);
}
+ size_now += len;
+ CHECK_SIZE();
ARRAY_TO_STREAM(p, p_data, len);
- p_buf->len += len;
}
+ // backfill pair len field
+ if (op_code == GATT_RSP_READ_BY_TYPE) {
+ if (pair_len > UINT8_MAX) {
+ LOG(ERROR) << StringPrintf("pair_len greater than %d", UINT8_MAX);
+ osi_free(p_buf);
+ return nullptr;
+ }
+
+ *p_pair_len = (uint8_t)pair_len;
+ }
+
+#undef CHECK_SIZE
+
+ p_buf->len = (uint16_t)size_now;
return p_buf;
}

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Hui Peng <phui@google.com>
Date: Tue, 9 Jan 2024 22:38:20 +0000
Subject: [PATCH] Fix a security bypass issue in
access_secure_service_from_temp_bond
Backport I48df2c2d77810077e97d4131540277273d441998
to rvc-dev
Bug: 318374503
Test: m com.android.btservices | manual test against PoC | QA
Ignore-AOSP-First: security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e908c16d9157b9e4a936117f06b8f964cf8386b8)
Merged-In: Ib7cf66019b3d45a2a23d235ad5f9dc406394456f
Change-Id: Ib7cf66019b3d45a2a23d235ad5f9dc406394456f
---
stack/btm/btm_sec.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index f1d920f8d..48fecc959 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -234,8 +234,7 @@ static bool access_secure_service_from_temp_bond(const tBTM_SEC_DEV_REC* p_dev_r
bool locally_initiated,
uint16_t security_req) {
return !locally_initiated && (security_req & BTM_SEC_IN_AUTHENTICATE) &&
- btm_dev_authenticated(p_dev_rec) &&
- p_dev_rec->bond_type == BOND_TYPE_TEMPORARY;
+ p_dev_rec->bond_type == BOND_TYPE_TEMPORARY;
}
/*******************************************************************************

View File

@ -123,8 +123,6 @@ patchWorkspaceReal() {
repopick -fit msm8974-gps-r; repopick -fit msm8974-gps-r;
repopick -fit hh-vsync; repopick -fit hh-vsync;
repopick -fi 311299; #ble: Workaround malformed HCI_BLE_VENDOR_CAP response repopick -fi 311299; #ble: Workaround malformed HCI_BLE_VENDOR_CAP response
repopick -it R_asb_2024-03;
repopick -it R_asb_2024-04;
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

@ -131,7 +131,20 @@ rm -rfv androidtest;
fi; fi;
fi; fi;
if enterAndClear "frameworks/av"; then
applyPatch "$DOS_PATCHES/android_frameworks_av/385529.patch"; #R_asb_2024-03 Validate OMX Params for VPx encoders
applyPatch "$DOS_PATCHES/android_frameworks_av/385530.patch"; #R_asb_2024-03 SoftVideoDecodeOMXComponent: validate OMX params for dynamic HDR
applyPatch "$DOS_PATCHES/android_frameworks_av/385531.patch"; #R_asb_2024-03 Fix out of bounds read and write in onQueueFilled in outQueue
fi;
if enterAndClear "frameworks/base"; then if enterAndClear "frameworks/base"; then
applyPatch "$DOS_PATCHES/android_frameworks_base/385536.patch"; #R_asb_2024-03 Resolve custom printer icon boundary exploit.
applyPatch "$DOS_PATCHES/android_frameworks_base/385537.patch"; #R_asb_2024-03 Validate package names passed to the installer.
applyPatch "$DOS_PATCHES/android_frameworks_base/385538.patch"; #R_asb_2024-03 Disallow system apps to be installed/updated as instant.
applyPatch "$DOS_PATCHES/android_frameworks_base/385539.patch"; #R_asb_2024-03 Close AccountManagerService.session after timeout.
applyPatch "$DOS_PATCHES/android_frameworks_base/389131.patch"; #R_asb_2024-04 Added limitations for attributions to handle invalid cases
applyPatch "$DOS_PATCHES/android_frameworks_base/389132.patch"; #R_asb_2024-04 isUserInLockDown can be true when there are other strong auth requirements
applyPatch "$DOS_PATCHES/android_frameworks_base/389133.patch"; #R_asb_2024-04 Fix security vulnerability that creates user with no restrictions when accountOptions are too long.
git revert --no-edit 438d9feacfcad73d3ee918541574132928a93644; #Reverts "Allow signature spoofing for microG Companion/Services" in favor of below patch git revert --no-edit 438d9feacfcad73d3ee918541574132928a93644; #Reverts "Allow signature spoofing for microG Companion/Services" in favor of below patch
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)
applyPatch "$DOS_PATCHES/android_frameworks_base/0008-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS) applyPatch "$DOS_PATCHES/android_frameworks_base/0008-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS)
@ -391,6 +404,9 @@ applyPatch "$DOS_PATCHES/android_packages_providers_TelephonyProvider/312102.pat
fi; fi;
if enterAndClear "system/bt"; then if enterAndClear "system/bt"; then
applyPatch "$DOS_PATCHES/android_system_bt/385557.patch"; #R_asb_2024-03 Fix an OOB bug in smp_proc_sec_req
applyPatch "$DOS_PATCHES/android_system_bt/385558.patch"; #R_asb_2024-03 Reland: Fix an OOB write bug in attp_build_value_cmd
applyPatch "$DOS_PATCHES/android_system_bt/385559.patch"; #R_asb_2024-03 Fix a security bypass issue in access_secure_service_from_temp_bond
git am "$DOS_PATCHES/android_system_bt/a2dp-master-fixes.patch"; #topic (AOSP) git am "$DOS_PATCHES/android_system_bt/a2dp-master-fixes.patch"; #topic (AOSP)
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;
@ -440,6 +456,12 @@ if enterAndClear "system/vold"; then
git revert --no-edit 3461ff5c9ad334c96780f3da14f1d23fcbee63ad; #breaks mako first boot git revert --no-edit 3461ff5c9ad334c96780f3da14f1d23fcbee63ad; #breaks mako first boot
fi; fi;
if enterAndClear "vendor/qcom/opensource/commonsys/system/bt"; then
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/385591.patch"; #R_asb_2024-03 Fix an OOB bug in smp_proc_sec_req
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/385592.patch"; #R_asb_2024-03 Reland: Fix an OOB write bug in attp_build_value_cmd
applyPatch "$DOS_PATCHES/android_vendor_qcom_opensource_system_bt/385593.patch"; #R_asb_2024-03 Fix a security bypass issue in access_secure_service_from_temp_bond
fi;
if enterAndClear "vendor/lineage"; then if enterAndClear "vendor/lineage"; then
rm build/target/product/security/lineage.x509.pem; #Remove Lineage keys rm build/target/product/security/lineage.x509.pem; #Remove Lineage keys
rm -rf overlay/common/lineage-sdk/packages/LineageSettingsProvider/res/values/defaults.xml; #Remove analytics rm -rf overlay/common/lineage-sdk/packages/LineageSettingsProvider/res/values/defaults.xml; #Remove analytics