mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-09-27 19:56:32 +00:00
Compare commits
5 Commits
835fbb7d2c
...
741e5a7ca3
Author | SHA1 | Date | |
---|---|---|---|
|
741e5a7ca3 | ||
|
3f430b038e | ||
|
4f8cfc8a41 | ||
|
f5d06ea9aa | ||
|
ea83b47d59 |
6
Misc/apex.py
Normal file
6
Misc/apex.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
apexes = open(sys.argv[1], "r");
|
||||||
|
for line in apexes:
|
||||||
|
print('--extra_apks ' + line.strip() + '.apex="$KEY_DIR/releasekey" \\');
|
||||||
|
print('--extra_apex_payload_key ' + line.strip() + '.apex="$KEY_DIR/avb.pem" \\');
|
58
Misc/apex.txt
Normal file
58
Misc/apex.txt
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
com.android.adbd
|
||||||
|
com.android.adservices
|
||||||
|
com.android.adservices.api
|
||||||
|
com.android.apex.cts.shim
|
||||||
|
com.android.appsearch
|
||||||
|
com.android.art
|
||||||
|
com.android.art.debug
|
||||||
|
com.android.bluetooth
|
||||||
|
com.android.btservices
|
||||||
|
com.android.cellbroadcast
|
||||||
|
com.android.compos
|
||||||
|
com.android.configinfrastructure
|
||||||
|
com.android.connectivity.resources
|
||||||
|
com.android.conscrypt
|
||||||
|
com.android.devicelock
|
||||||
|
com.android.extservices
|
||||||
|
com.android.graphics.pdf
|
||||||
|
com.android.hardware.biometrics.face.virtual
|
||||||
|
com.android.hardware.biometrics.fingerprint.virtual
|
||||||
|
com.android.hardware.cas
|
||||||
|
com.android.hardware.wifi
|
||||||
|
com.android.healthfitness
|
||||||
|
com.android.hotspot2.osulogin
|
||||||
|
com.android.i18n
|
||||||
|
com.android.ipsec
|
||||||
|
com.android.media
|
||||||
|
com.android.mediaprovider
|
||||||
|
com.android.media.swcodec
|
||||||
|
com.android.nearby.halfsheet
|
||||||
|
com.android.networkstack.tethering
|
||||||
|
com.android.neuralnetworks
|
||||||
|
com.android.ondevicepersonalization
|
||||||
|
com.android.os.statsd
|
||||||
|
com.android.permission
|
||||||
|
com.android.resolv
|
||||||
|
com.android.rkpd
|
||||||
|
com.android.runtime
|
||||||
|
com.android.safetycenter.resources
|
||||||
|
com.android.scheduling
|
||||||
|
com.android.sdkext
|
||||||
|
com.android.support.apexer
|
||||||
|
com.android.telephony
|
||||||
|
com.android.telephonymodules
|
||||||
|
com.android.tethering
|
||||||
|
com.android.tzdata
|
||||||
|
com.android.uwb
|
||||||
|
com.android.uwb.resources
|
||||||
|
com.android.vibrator.drv2624
|
||||||
|
com.android.vibrator.sunfish
|
||||||
|
com.android.virt
|
||||||
|
com.android.vndk.current
|
||||||
|
com.android.vndk.current.on_vendor
|
||||||
|
com.android.wifi
|
||||||
|
com.android.wifi.dialog
|
||||||
|
com.android.wifi.resources
|
||||||
|
com.google.pixel.camera.hal
|
||||||
|
com.google.pixel.vibrator.hal
|
||||||
|
com.qorvo.uwb
|
511
Patches/LineageOS-16.0/android_frameworks_base/snet-16.patch
Normal file
511
Patches/LineageOS-16.0/android_frameworks_base/snet-16.patch
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||||
|
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||||
|
enforcement
|
||||||
|
|
||||||
|
As of September 2, Google is enforcing SafetyNet's previously
|
||||||
|
opportunistic hardware-backed attestation based on device information.
|
||||||
|
Append a space to the device model name in order to avoid such
|
||||||
|
enforcement.
|
||||||
|
|
||||||
|
Also contains:
|
||||||
|
Spoof build fingerprint for Google Play Services
|
||||||
|
|
||||||
|
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||||
|
matches that of the device's stock OS, which has passed CTS testing.
|
||||||
|
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||||
|
|
||||||
|
We used to set the real system build fingerprint to the stock one, but
|
||||||
|
Android relies on each build having a unique fingerprint in order to
|
||||||
|
clear the correct caches and update persistent state for system changes.
|
||||||
|
On devices that no longer receive updates from the OEM, the build
|
||||||
|
fingerprint never changes and Android doesn't account for updates
|
||||||
|
correctly, which causes issues when updating without wiping data.
|
||||||
|
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||||
|
|
||||||
|
Corresponding vendor commit:
|
||||||
|
"Only use stock build fingerprint for Google Play Services"
|
||||||
|
|
||||||
|
NB: This code is under the gmscompat package, but it does not depend on
|
||||||
|
any code from gmscompat.
|
||||||
|
|
||||||
|
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||||
|
|
||||||
|
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||||
|
use the Build field spoofing code it added for model
|
||||||
|
|
||||||
|
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||||
|
---
|
||||||
|
core/java/android/app/Instrumentation.java | 4 ++
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||||
|
2 files changed, 63 insertions(+)
|
||||||
|
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
|
||||||
|
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||||
|
index d4385549da02..61e4176392f7 100644
|
||||||
|
--- a/core/java/android/app/Instrumentation.java
|
||||||
|
+++ b/core/java/android/app/Instrumentation.java
|
||||||
|
@@ -53,6 +53,8 @@ import android.view.Window;
|
||||||
|
|
||||||
|
import com.android.internal.content.ReferrerIntent;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
@@ -1119,6 +1121,7 @@ public class Instrumentation {
|
||||||
|
Application app = getFactory(context.getPackageName())
|
||||||
|
.instantiateApplication(cl, className);
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1136,6 +1139,7 @@ public class Instrumentation {
|
||||||
|
ClassNotFoundException {
|
||||||
|
Application app = (Application)clazz.newInstance();
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..621156eb84b9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2021 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.internal.gmscompat;
|
||||||
|
+
|
||||||
|
+import android.app.Application;
|
||||||
|
+import android.os.Build;
|
||||||
|
+import android.os.SystemProperties;
|
||||||
|
+import android.util.Log;
|
||||||
|
+
|
||||||
|
+import java.lang.reflect.Field;
|
||||||
|
+
|
||||||
|
+/** @hide */
|
||||||
|
+public final class AttestationHooks {
|
||||||
|
+ private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+
|
||||||
|
+ private AttestationHooks() { }
|
||||||
|
+
|
||||||
|
+ private static void setBuildField(String key, String value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void spoofBuildGms() {
|
||||||
|
+ // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||||
|
Subject: [PATCH 2/8] keystore: Block key attestation for SafetyNet
|
||||||
|
|
||||||
|
SafetyNet (part of Google Play Services) opportunistically uses
|
||||||
|
hardware-backed key attestation via KeyStore as a strong integrity
|
||||||
|
check. This causes SafetyNet to fail on custom ROMs because the verified
|
||||||
|
boot key and bootloader unlock state can be detected from attestation
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
As a workaround, we can take advantage of the fact that SafetyNet's
|
||||||
|
usage of key attestation is opportunistic (i.e. falls back to basic
|
||||||
|
integrity checks if it fails) and prevent it from getting the
|
||||||
|
attestation certificate chain from KeyStore. This is done by checking
|
||||||
|
the stack for DroidGuard, which is the codename for SafetyNet, and
|
||||||
|
pretending that the device doesn't support key attestation.
|
||||||
|
|
||||||
|
Key attestation has only been blocked for SafetyNet specifically, as
|
||||||
|
Google Play Services and other apps have many valid reasons to use it.
|
||||||
|
For example, it appears to be involved in Google's mobile security key
|
||||||
|
ferature.
|
||||||
|
|
||||||
|
Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||||
|
.../security/keystore/AndroidKeyStoreSpi.java | 4 ++++
|
||||||
|
2 files changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 621156eb84b9..fe12dfe02a9f 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
|
||||||
|
+ private static volatile boolean sIsGms = false;
|
||||||
|
+
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
private static void setBuildField(String key, String value) {
|
||||||
|
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ private static boolean isCallerSafetyNet() {
|
||||||
|
+ return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ .anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void onEngineGetCertificateChain() {
|
||||||
|
+ // Check stack for SafetyNet
|
||||||
|
+ if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
index 4c007cb70ba2..7dcd79197aa5 100644
|
||||||
|
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
@@ -30,6 +30,8 @@ import android.security.keystore.SecureKeyImportUnavailableException;
|
||||||
|
import android.security.keystore.WrappedKeyEntry;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
@@ -104,6 +106,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
|
+ AttestationHooks.onEngineGetCertificateChain();
|
||||||
|
+
|
||||||
|
if (alias == null) {
|
||||||
|
throw new NullPointerException("alias == null");
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||||
|
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||||
|
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||||
|
>=33
|
||||||
|
|
||||||
|
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||||
|
Setting it to 32 allows for software attestation and passing CTS.
|
||||||
|
|
||||||
|
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index fe12dfe02a9f..f512adc3985b 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static void setVersionField(String key, Integer value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name to avoid hardware attestation enforcement
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||||
|
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||||
|
|
||||||
|
The unstable process is where SafetyNet attestation actually runs, so
|
||||||
|
we only need to spoof the model in that process. Leaving other processes
|
||||||
|
fixes various issues caused by model detection and flag provisioning,
|
||||||
|
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||||
|
weather and settings on Android 12, and more.
|
||||||
|
|
||||||
|
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index f512adc3985b..c1021dd2eb22 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
|
||||||
|
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||||
|
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||||
|
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||||
|
aswell
|
||||||
|
|
||||||
|
Play Store is used for the new Play Integrity API, extend the hack
|
||||||
|
to it aswell
|
||||||
|
|
||||||
|
Test: Device Integrity and Basic Integrity passes.
|
||||||
|
|
||||||
|
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index c1021dd2eb22..6a4aab000fe0 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||||
|
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
+ private static volatile boolean sIsFinsky = false;
|
||||||
|
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
+ sIsFinsky = true;
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||||
|
if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Check stack for PlayIntegrity
|
||||||
|
+ if (sIsFinsky) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||||
|
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||||
|
|
||||||
|
Google seems to have patched the KM block to Play Store in record time,
|
||||||
|
but is still not enforced for anything under android N.
|
||||||
|
|
||||||
|
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||||
|
anymore, however the KM block is still needed.
|
||||||
|
|
||||||
|
Test: Run Play Intregrity Attestation
|
||||||
|
|
||||||
|
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
- // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
sIsFinsky = true;
|
||||||
|
- spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||||
|
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||||
|
|
||||||
|
The logic behind CTS and Play Integrity has been updated today it now
|
||||||
|
checks the product and model names against the fingerprint and if
|
||||||
|
they do not match the CTS profile will fail.
|
||||||
|
|
||||||
|
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||||
|
for key attestation blocking for debugging.
|
||||||
|
|
||||||
|
Test: Boot, check for CTS and Play Integrity
|
||||||
|
|
||||||
|
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||||
|
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
- setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
- }
|
||||||
|
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
+ setBuildField("PRODUCT", "marlin");
|
||||||
|
+ setBuildField("DEVICE", "marlin");
|
||||||
|
+ setBuildField("MODEL", "Pixel XL");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ return sIsGms && Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
.anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onEngineGetCertificateChain() {
|
||||||
|
- // Check stack for SafetyNet
|
||||||
|
- if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
- throw new UnsupportedOperationException();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // Check stack for PlayIntegrity
|
||||||
|
- if (sIsFinsky) {
|
||||||
|
+ // Check stack for SafetyNet or Play Integrity
|
||||||
|
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||||
|
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Davide Garberi <dade.garberi@gmail.com>
|
||||||
|
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||||
|
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||||
|
|
||||||
|
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index b10cb04cb4f3..04a536d8073d 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
- setBuildField("PRODUCT", "marlin");
|
||||||
|
- setBuildField("DEVICE", "marlin");
|
||||||
|
- setBuildField("MODEL", "Pixel XL");
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
+ setBuildField("DEVICE", "bullhead");
|
||||||
|
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||||
|
+ setBuildField("MODEL", "Nexus 5X");
|
||||||
|
+ setBuildField("PRODUCT", "bullhead");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
59
Patches/LineageOS-16.0/android_system_core/snet-16.patch
Normal file
59
Patches/LineageOS-16.0/android_system_core/snet-16.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||||
|
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||||
|
|
||||||
|
Google's SafetyNet integrity checks will check the values of these
|
||||||
|
properties when performing basic attestation. Setting fake values helps
|
||||||
|
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||||
|
|
||||||
|
Note that these properties need to be set very early, before parsing the
|
||||||
|
kernel command-line, as they are read-only properties that the bootloader
|
||||||
|
sets using androidboot kernel arguments. The bootloader's real values
|
||||||
|
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||||
|
software because the verified boot chain is broken in that case.
|
||||||
|
|
||||||
|
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||||
|
|
||||||
|
- Also don't set these in recovery
|
||||||
|
|
||||||
|
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||||
|
---
|
||||||
|
init/property_service.cpp | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||||
|
index f47c93596..6c404de62 100644
|
||||||
|
--- a/init/property_service.cpp
|
||||||
|
+++ b/init/property_service.cpp
|
||||||
|
@@ -101,6 +101,15 @@ struct PropertyAuditData {
|
||||||
|
const char* name;
|
||||||
|
};
|
||||||
|
|
||||||
|
+static void SetSafetyNetProps() {
|
||||||
|
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||||
|
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||||
|
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||||
|
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||||
|
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||||
|
+ InitPropertySet("ro.warranty_bit", "0");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void property_init() {
|
||||||
|
mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH);
|
||||||
|
CreateSerializedPropertyInfo();
|
||||||
|
@@ -110,6 +119,14 @@ void property_init() {
|
||||||
|
if (!property_info_area.LoadDefaultPath()) {
|
||||||
|
LOG(FATAL) << "Failed to load serialized property info file";
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||||
|
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||||
|
+ // these properties are read-only and will be set to invalid values with
|
||||||
|
+ // androidboot cmdline arguments.
|
||||||
|
+ if (!IsRecoveryMode()) {
|
||||||
|
+ SetSafetyNetProps();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
static bool CheckMacPerms(const std::string& name, const char* target_context,
|
||||||
|
const char* source_context, const ucred& cr) {
|
511
Patches/LineageOS-17.1/android_frameworks_base/snet-17.patch
Normal file
511
Patches/LineageOS-17.1/android_frameworks_base/snet-17.patch
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||||
|
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||||
|
enforcement
|
||||||
|
|
||||||
|
As of September 2, Google is enforcing SafetyNet's previously
|
||||||
|
opportunistic hardware-backed attestation based on device information.
|
||||||
|
Append a space to the device model name in order to avoid such
|
||||||
|
enforcement.
|
||||||
|
|
||||||
|
Also contains:
|
||||||
|
Spoof build fingerprint for Google Play Services
|
||||||
|
|
||||||
|
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||||
|
matches that of the device's stock OS, which has passed CTS testing.
|
||||||
|
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||||
|
|
||||||
|
We used to set the real system build fingerprint to the stock one, but
|
||||||
|
Android relies on each build having a unique fingerprint in order to
|
||||||
|
clear the correct caches and update persistent state for system changes.
|
||||||
|
On devices that no longer receive updates from the OEM, the build
|
||||||
|
fingerprint never changes and Android doesn't account for updates
|
||||||
|
correctly, which causes issues when updating without wiping data.
|
||||||
|
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||||
|
|
||||||
|
Corresponding vendor commit:
|
||||||
|
"Only use stock build fingerprint for Google Play Services"
|
||||||
|
|
||||||
|
NB: This code is under the gmscompat package, but it does not depend on
|
||||||
|
any code from gmscompat.
|
||||||
|
|
||||||
|
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||||
|
|
||||||
|
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||||
|
use the Build field spoofing code it added for model
|
||||||
|
|
||||||
|
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||||
|
---
|
||||||
|
core/java/android/app/Instrumentation.java | 4 ++
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||||
|
2 files changed, 63 insertions(+)
|
||||||
|
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
|
||||||
|
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||||
|
index 9720e9f47f83..e19f3fc4db85 100644
|
||||||
|
--- a/core/java/android/app/Instrumentation.java
|
||||||
|
+++ b/core/java/android/app/Instrumentation.java
|
||||||
|
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
|
import com.android.internal.content.ReferrerIntent;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
@@ -1154,6 +1156,7 @@ public class Instrumentation {
|
||||||
|
Application app = getFactory(context.getPackageName())
|
||||||
|
.instantiateApplication(cl, className);
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1171,6 +1174,7 @@ public class Instrumentation {
|
||||||
|
ClassNotFoundException {
|
||||||
|
Application app = (Application)clazz.newInstance();
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..621156eb84b9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2021 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.internal.gmscompat;
|
||||||
|
+
|
||||||
|
+import android.app.Application;
|
||||||
|
+import android.os.Build;
|
||||||
|
+import android.os.SystemProperties;
|
||||||
|
+import android.util.Log;
|
||||||
|
+
|
||||||
|
+import java.lang.reflect.Field;
|
||||||
|
+
|
||||||
|
+/** @hide */
|
||||||
|
+public final class AttestationHooks {
|
||||||
|
+ private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+
|
||||||
|
+ private AttestationHooks() { }
|
||||||
|
+
|
||||||
|
+ private static void setBuildField(String key, String value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void spoofBuildGms() {
|
||||||
|
+ // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||||
|
Subject: [PATCH 2/8] keystore: Block key attestation for SafetyNet
|
||||||
|
|
||||||
|
SafetyNet (part of Google Play Services) opportunistically uses
|
||||||
|
hardware-backed key attestation via KeyStore as a strong integrity
|
||||||
|
check. This causes SafetyNet to fail on custom ROMs because the verified
|
||||||
|
boot key and bootloader unlock state can be detected from attestation
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
As a workaround, we can take advantage of the fact that SafetyNet's
|
||||||
|
usage of key attestation is opportunistic (i.e. falls back to basic
|
||||||
|
integrity checks if it fails) and prevent it from getting the
|
||||||
|
attestation certificate chain from KeyStore. This is done by checking
|
||||||
|
the stack for DroidGuard, which is the codename for SafetyNet, and
|
||||||
|
pretending that the device doesn't support key attestation.
|
||||||
|
|
||||||
|
Key attestation has only been blocked for SafetyNet specifically, as
|
||||||
|
Google Play Services and other apps have many valid reasons to use it.
|
||||||
|
For example, it appears to be involved in Google's mobile security key
|
||||||
|
ferature.
|
||||||
|
|
||||||
|
Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||||
|
.../security/keystore/AndroidKeyStoreSpi.java | 4 ++++
|
||||||
|
2 files changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 621156eb84b9..fe12dfe02a9f 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
|
||||||
|
+ private static volatile boolean sIsGms = false;
|
||||||
|
+
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
private static void setBuildField(String key, String value) {
|
||||||
|
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ private static boolean isCallerSafetyNet() {
|
||||||
|
+ return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ .anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void onEngineGetCertificateChain() {
|
||||||
|
+ // Check stack for SafetyNet
|
||||||
|
+ if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
index 51c42520ccc9..b77ddc711492 100644
|
||||||
|
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
@@ -30,6 +30,8 @@ import android.security.keystore.SecureKeyImportUnavailableException;
|
||||||
|
import android.security.keystore.WrappedKeyEntry;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import libcore.util.EmptyArray;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
@@ -113,6 +115,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
|
+ AttestationHooks.onEngineGetCertificateChain();
|
||||||
|
+
|
||||||
|
if (alias == null) {
|
||||||
|
throw new NullPointerException("alias == null");
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||||
|
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||||
|
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||||
|
>=33
|
||||||
|
|
||||||
|
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||||
|
Setting it to 32 allows for software attestation and passing CTS.
|
||||||
|
|
||||||
|
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index fe12dfe02a9f..f512adc3985b 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static void setVersionField(String key, Integer value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name to avoid hardware attestation enforcement
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||||
|
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||||
|
|
||||||
|
The unstable process is where SafetyNet attestation actually runs, so
|
||||||
|
we only need to spoof the model in that process. Leaving other processes
|
||||||
|
fixes various issues caused by model detection and flag provisioning,
|
||||||
|
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||||
|
weather and settings on Android 12, and more.
|
||||||
|
|
||||||
|
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index f512adc3985b..c1021dd2eb22 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
|
||||||
|
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||||
|
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||||
|
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||||
|
aswell
|
||||||
|
|
||||||
|
Play Store is used for the new Play Integrity API, extend the hack
|
||||||
|
to it aswell
|
||||||
|
|
||||||
|
Test: Device Integrity and Basic Integrity passes.
|
||||||
|
|
||||||
|
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index c1021dd2eb22..6a4aab000fe0 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||||
|
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
+ private static volatile boolean sIsFinsky = false;
|
||||||
|
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
+ sIsFinsky = true;
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||||
|
if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Check stack for PlayIntegrity
|
||||||
|
+ if (sIsFinsky) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||||
|
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||||
|
|
||||||
|
Google seems to have patched the KM block to Play Store in record time,
|
||||||
|
but is still not enforced for anything under android N.
|
||||||
|
|
||||||
|
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||||
|
anymore, however the KM block is still needed.
|
||||||
|
|
||||||
|
Test: Run Play Intregrity Attestation
|
||||||
|
|
||||||
|
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
- // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
sIsFinsky = true;
|
||||||
|
- spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||||
|
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||||
|
|
||||||
|
The logic behind CTS and Play Integrity has been updated today it now
|
||||||
|
checks the product and model names against the fingerprint and if
|
||||||
|
they do not match the CTS profile will fail.
|
||||||
|
|
||||||
|
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||||
|
for key attestation blocking for debugging.
|
||||||
|
|
||||||
|
Test: Boot, check for CTS and Play Integrity
|
||||||
|
|
||||||
|
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||||
|
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
- setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
- }
|
||||||
|
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
+ setBuildField("PRODUCT", "marlin");
|
||||||
|
+ setBuildField("DEVICE", "marlin");
|
||||||
|
+ setBuildField("MODEL", "Pixel XL");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ return sIsGms && Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
.anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onEngineGetCertificateChain() {
|
||||||
|
- // Check stack for SafetyNet
|
||||||
|
- if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
- throw new UnsupportedOperationException();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // Check stack for PlayIntegrity
|
||||||
|
- if (sIsFinsky) {
|
||||||
|
+ // Check stack for SafetyNet or Play Integrity
|
||||||
|
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||||
|
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Davide Garberi <dade.garberi@gmail.com>
|
||||||
|
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||||
|
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||||
|
|
||||||
|
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index b10cb04cb4f3..04a536d8073d 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
- setBuildField("PRODUCT", "marlin");
|
||||||
|
- setBuildField("DEVICE", "marlin");
|
||||||
|
- setBuildField("MODEL", "Pixel XL");
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
+ setBuildField("DEVICE", "bullhead");
|
||||||
|
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||||
|
+ setBuildField("MODEL", "Nexus 5X");
|
||||||
|
+ setBuildField("PRODUCT", "bullhead");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
59
Patches/LineageOS-17.1/android_system_core/snet-17.patch
Normal file
59
Patches/LineageOS-17.1/android_system_core/snet-17.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||||
|
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||||
|
|
||||||
|
Google's SafetyNet integrity checks will check the values of these
|
||||||
|
properties when performing basic attestation. Setting fake values helps
|
||||||
|
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||||
|
|
||||||
|
Note that these properties need to be set very early, before parsing the
|
||||||
|
kernel command-line, as they are read-only properties that the bootloader
|
||||||
|
sets using androidboot kernel arguments. The bootloader's real values
|
||||||
|
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||||
|
software because the verified boot chain is broken in that case.
|
||||||
|
|
||||||
|
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||||
|
|
||||||
|
- Also don't set these in recovery
|
||||||
|
|
||||||
|
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||||
|
---
|
||||||
|
init/property_service.cpp | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||||
|
index 65e9cda1c..7be56d0db 100644
|
||||||
|
--- a/init/property_service.cpp
|
||||||
|
+++ b/init/property_service.cpp
|
||||||
|
@@ -117,6 +117,15 @@ static int PropertyAuditCallback(void* data, security_class_t /*cls*/, char* buf
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void SetSafetyNetProps() {
|
||||||
|
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||||
|
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||||
|
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||||
|
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||||
|
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||||
|
+ InitPropertySet("ro.warranty_bit", "0");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void property_init() {
|
||||||
|
selinux_callback cb;
|
||||||
|
cb.func_audit = PropertyAuditCallback;
|
||||||
|
@@ -130,6 +139,14 @@ void property_init() {
|
||||||
|
if (!property_info_area.LoadDefaultPath()) {
|
||||||
|
LOG(FATAL) << "Failed to load serialized property info file";
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||||
|
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||||
|
+ // these properties are read-only and will be set to invalid values with
|
||||||
|
+ // androidboot cmdline arguments.
|
||||||
|
+ if (!IsRecoveryMode()) {
|
||||||
|
+ SetSafetyNetProps();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanReadProperty(const std::string& source_context, const std::string& name) {
|
@ -1,117 +0,0 @@
|
|||||||
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:ce7ca2d9f405c94062504411c886eff93bd7ce15)
|
|
||||||
Merged-In: I5e979a7822dd7254b4579ab28ecf96df1db44179
|
|
||||||
Change-Id: I5e979a7822dd7254b4579ab28ecf96df1db44179
|
|
||||||
---
|
|
||||||
.../internal/widget/LockPatternUtils.java | 4 +-
|
|
||||||
.../internal/util/LockPatternUtilsTest.java | 41 ++++++++++++++++---
|
|
||||||
2 files changed, 38 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..01494a7659a5 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,10 @@ 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_LOCKOUT;
|
|
||||||
+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 +52,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 +68,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 +85,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);
|
|
@ -1,345 +0,0 @@
|
|||||||
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:944ea959ab8464c39a8f6a4fc391fb6953e1df89)
|
|
||||||
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;
|
|
511
Patches/LineageOS-18.1/android_frameworks_base/snet-18.patch
Normal file
511
Patches/LineageOS-18.1/android_frameworks_base/snet-18.patch
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||||
|
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||||
|
enforcement
|
||||||
|
|
||||||
|
As of September 2, Google is enforcing SafetyNet's previously
|
||||||
|
opportunistic hardware-backed attestation based on device information.
|
||||||
|
Append a space to the device model name in order to avoid such
|
||||||
|
enforcement.
|
||||||
|
|
||||||
|
Also contains:
|
||||||
|
Spoof build fingerprint for Google Play Services
|
||||||
|
|
||||||
|
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||||
|
matches that of the device's stock OS, which has passed CTS testing.
|
||||||
|
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||||
|
|
||||||
|
We used to set the real system build fingerprint to the stock one, but
|
||||||
|
Android relies on each build having a unique fingerprint in order to
|
||||||
|
clear the correct caches and update persistent state for system changes.
|
||||||
|
On devices that no longer receive updates from the OEM, the build
|
||||||
|
fingerprint never changes and Android doesn't account for updates
|
||||||
|
correctly, which causes issues when updating without wiping data.
|
||||||
|
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||||
|
|
||||||
|
Corresponding vendor commit:
|
||||||
|
"Only use stock build fingerprint for Google Play Services"
|
||||||
|
|
||||||
|
NB: This code is under the gmscompat package, but it does not depend on
|
||||||
|
any code from gmscompat.
|
||||||
|
|
||||||
|
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||||
|
|
||||||
|
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||||
|
use the Build field spoofing code it added for model
|
||||||
|
|
||||||
|
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||||
|
---
|
||||||
|
core/java/android/app/Instrumentation.java | 4 ++
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||||
|
2 files changed, 63 insertions(+)
|
||||||
|
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
|
||||||
|
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||||
|
index 721525d9af9d..09dcad811d4d 100644
|
||||||
|
--- a/core/java/android/app/Instrumentation.java
|
||||||
|
+++ b/core/java/android/app/Instrumentation.java
|
||||||
|
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
|
import com.android.internal.content.ReferrerIntent;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
@@ -1157,6 +1159,7 @@ public class Instrumentation {
|
||||||
|
Application app = getFactory(context.getPackageName())
|
||||||
|
.instantiateApplication(cl, className);
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1174,6 +1177,7 @@ public class Instrumentation {
|
||||||
|
ClassNotFoundException {
|
||||||
|
Application app = (Application)clazz.newInstance();
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..621156eb84b9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2021 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.internal.gmscompat;
|
||||||
|
+
|
||||||
|
+import android.app.Application;
|
||||||
|
+import android.os.Build;
|
||||||
|
+import android.os.SystemProperties;
|
||||||
|
+import android.util.Log;
|
||||||
|
+
|
||||||
|
+import java.lang.reflect.Field;
|
||||||
|
+
|
||||||
|
+/** @hide */
|
||||||
|
+public final class AttestationHooks {
|
||||||
|
+ private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+
|
||||||
|
+ private AttestationHooks() { }
|
||||||
|
+
|
||||||
|
+ private static void setBuildField(String key, String value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void spoofBuildGms() {
|
||||||
|
+ // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||||
|
Subject: [PATCH 2/8] keystore: Block key attestation for SafetyNet
|
||||||
|
|
||||||
|
SafetyNet (part of Google Play Services) opportunistically uses
|
||||||
|
hardware-backed key attestation via KeyStore as a strong integrity
|
||||||
|
check. This causes SafetyNet to fail on custom ROMs because the verified
|
||||||
|
boot key and bootloader unlock state can be detected from attestation
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
As a workaround, we can take advantage of the fact that SafetyNet's
|
||||||
|
usage of key attestation is opportunistic (i.e. falls back to basic
|
||||||
|
integrity checks if it fails) and prevent it from getting the
|
||||||
|
attestation certificate chain from KeyStore. This is done by checking
|
||||||
|
the stack for DroidGuard, which is the codename for SafetyNet, and
|
||||||
|
pretending that the device doesn't support key attestation.
|
||||||
|
|
||||||
|
Key attestation has only been blocked for SafetyNet specifically, as
|
||||||
|
Google Play Services and other apps have many valid reasons to use it.
|
||||||
|
For example, it appears to be involved in Google's mobile security key
|
||||||
|
ferature.
|
||||||
|
|
||||||
|
Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||||
|
.../security/keystore/AndroidKeyStoreSpi.java | 4 ++++
|
||||||
|
2 files changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 621156eb84b9..fe12dfe02a9f 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
|
||||||
|
+ private static volatile boolean sIsGms = false;
|
||||||
|
+
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
private static void setBuildField(String key, String value) {
|
||||||
|
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ private static boolean isCallerSafetyNet() {
|
||||||
|
+ return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ .anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void onEngineGetCertificateChain() {
|
||||||
|
+ // Check stack for SafetyNet
|
||||||
|
+ if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
index 51c42520ccc9..b77ddc711492 100644
|
||||||
|
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
|
||||||
|
@@ -30,6 +30,8 @@ import android.security.keystore.SecureKeyImportUnavailableException;
|
||||||
|
import android.security.keystore.WrappedKeyEntry;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import libcore.util.EmptyArray;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
@@ -113,6 +115,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
|
+ AttestationHooks.onEngineGetCertificateChain();
|
||||||
|
+
|
||||||
|
if (alias == null) {
|
||||||
|
throw new NullPointerException("alias == null");
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||||
|
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||||
|
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||||
|
>=33
|
||||||
|
|
||||||
|
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||||
|
Setting it to 32 allows for software attestation and passing CTS.
|
||||||
|
|
||||||
|
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index fe12dfe02a9f..f512adc3985b 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static void setVersionField(String key, Integer value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name to avoid hardware attestation enforcement
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||||
|
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||||
|
|
||||||
|
The unstable process is where SafetyNet attestation actually runs, so
|
||||||
|
we only need to spoof the model in that process. Leaving other processes
|
||||||
|
fixes various issues caused by model detection and flag provisioning,
|
||||||
|
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||||
|
weather and settings on Android 12, and more.
|
||||||
|
|
||||||
|
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index f512adc3985b..c1021dd2eb22 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
|
||||||
|
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||||
|
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||||
|
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||||
|
aswell
|
||||||
|
|
||||||
|
Play Store is used for the new Play Integrity API, extend the hack
|
||||||
|
to it aswell
|
||||||
|
|
||||||
|
Test: Device Integrity and Basic Integrity passes.
|
||||||
|
|
||||||
|
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index c1021dd2eb22..6a4aab000fe0 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||||
|
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
+ private static volatile boolean sIsFinsky = false;
|
||||||
|
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
+ sIsFinsky = true;
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||||
|
if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Check stack for PlayIntegrity
|
||||||
|
+ if (sIsFinsky) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||||
|
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||||
|
|
||||||
|
Google seems to have patched the KM block to Play Store in record time,
|
||||||
|
but is still not enforced for anything under android N.
|
||||||
|
|
||||||
|
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||||
|
anymore, however the KM block is still needed.
|
||||||
|
|
||||||
|
Test: Run Play Intregrity Attestation
|
||||||
|
|
||||||
|
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
- // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
sIsFinsky = true;
|
||||||
|
- spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||||
|
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||||
|
|
||||||
|
The logic behind CTS and Play Integrity has been updated today it now
|
||||||
|
checks the product and model names against the fingerprint and if
|
||||||
|
they do not match the CTS profile will fail.
|
||||||
|
|
||||||
|
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||||
|
for key attestation blocking for debugging.
|
||||||
|
|
||||||
|
Test: Boot, check for CTS and Play Integrity
|
||||||
|
|
||||||
|
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||||
|
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
- setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
- }
|
||||||
|
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
+ setBuildField("PRODUCT", "marlin");
|
||||||
|
+ setBuildField("DEVICE", "marlin");
|
||||||
|
+ setBuildField("MODEL", "Pixel XL");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ return sIsGms && Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
.anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onEngineGetCertificateChain() {
|
||||||
|
- // Check stack for SafetyNet
|
||||||
|
- if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
- throw new UnsupportedOperationException();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // Check stack for PlayIntegrity
|
||||||
|
- if (sIsFinsky) {
|
||||||
|
+ // Check stack for SafetyNet or Play Integrity
|
||||||
|
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||||
|
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Davide Garberi <dade.garberi@gmail.com>
|
||||||
|
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||||
|
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||||
|
|
||||||
|
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index b10cb04cb4f3..04a536d8073d 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
- setBuildField("PRODUCT", "marlin");
|
||||||
|
- setBuildField("DEVICE", "marlin");
|
||||||
|
- setBuildField("MODEL", "Pixel XL");
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
+ setBuildField("DEVICE", "bullhead");
|
||||||
|
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||||
|
+ setBuildField("MODEL", "Nexus 5X");
|
||||||
|
+ setBuildField("PRODUCT", "bullhead");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
59
Patches/LineageOS-18.1/android_system_core/snet-18.patch
Normal file
59
Patches/LineageOS-18.1/android_system_core/snet-18.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||||
|
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||||
|
|
||||||
|
Google's SafetyNet integrity checks will check the values of these
|
||||||
|
properties when performing basic attestation. Setting fake values helps
|
||||||
|
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||||
|
|
||||||
|
Note that these properties need to be set very early, before parsing the
|
||||||
|
kernel command-line, as they are read-only properties that the bootloader
|
||||||
|
sets using androidboot kernel arguments. The bootloader's real values
|
||||||
|
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||||
|
software because the verified boot chain is broken in that case.
|
||||||
|
|
||||||
|
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||||
|
|
||||||
|
- Also don't set these in recovery
|
||||||
|
|
||||||
|
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||||
|
---
|
||||||
|
init/property_service.cpp | 17 +++++++++++++++++
|
||||||
|
1 file changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||||
|
index 42dd5afcb..a2c7c2db6 100644
|
||||||
|
--- a/init/property_service.cpp
|
||||||
|
+++ b/init/property_service.cpp
|
||||||
|
@@ -1064,6 +1064,15 @@ static void ProcessKernelCmdline() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void SetSafetyNetProps() {
|
||||||
|
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||||
|
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||||
|
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||||
|
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||||
|
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||||
|
+ InitPropertySet("ro.warranty_bit", "0");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void PropertyInit() {
|
||||||
|
selinux_callback cb;
|
||||||
|
cb.func_audit = PropertyAuditCallback;
|
||||||
|
@@ -1078,6 +1087,14 @@ void PropertyInit() {
|
||||||
|
LOG(FATAL) << "Failed to load serialized property info file";
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||||
|
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||||
|
+ // these properties are read-only and will be set to invalid values with
|
||||||
|
+ // androidboot cmdline arguments.
|
||||||
|
+ if (!IsRecoveryMode()) {
|
||||||
|
+ SetSafetyNetProps();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// If arguments are passed both on the command line and in DT,
|
||||||
|
// properties set in DT always have priority over the command-line ones.
|
||||||
|
ProcessKernelDt();
|
510
Patches/LineageOS-19.1/android_frameworks_base/snet-19.patch
Normal file
510
Patches/LineageOS-19.1/android_frameworks_base/snet-19.patch
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||||
|
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||||
|
enforcement
|
||||||
|
|
||||||
|
As of September 2, Google is enforcing SafetyNet's previously
|
||||||
|
opportunistic hardware-backed attestation based on device information.
|
||||||
|
Append a space to the device model name in order to avoid such
|
||||||
|
enforcement.
|
||||||
|
|
||||||
|
Also contains:
|
||||||
|
Spoof build fingerprint for Google Play Services
|
||||||
|
|
||||||
|
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||||
|
matches that of the device's stock OS, which has passed CTS testing.
|
||||||
|
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||||
|
|
||||||
|
We used to set the real system build fingerprint to the stock one, but
|
||||||
|
Android relies on each build having a unique fingerprint in order to
|
||||||
|
clear the correct caches and update persistent state for system changes.
|
||||||
|
On devices that no longer receive updates from the OEM, the build
|
||||||
|
fingerprint never changes and Android doesn't account for updates
|
||||||
|
correctly, which causes issues when updating without wiping data.
|
||||||
|
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||||
|
|
||||||
|
Corresponding vendor commit:
|
||||||
|
"Only use stock build fingerprint for Google Play Services"
|
||||||
|
|
||||||
|
NB: This code is under the gmscompat package, but it does not depend on
|
||||||
|
any code from gmscompat.
|
||||||
|
|
||||||
|
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||||
|
|
||||||
|
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||||
|
use the Build field spoofing code it added for model
|
||||||
|
|
||||||
|
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||||
|
---
|
||||||
|
core/java/android/app/Instrumentation.java | 4 ++
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||||
|
2 files changed, 63 insertions(+)
|
||||||
|
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
|
||||||
|
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||||
|
index fd6fa57b9e8d..05d840dca223 100644
|
||||||
|
--- a/core/java/android/app/Instrumentation.java
|
||||||
|
+++ b/core/java/android/app/Instrumentation.java
|
||||||
|
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
|
import com.android.internal.content.ReferrerIntent;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
@@ -1188,6 +1190,7 @@ public class Instrumentation {
|
||||||
|
Application app = getFactory(context.getPackageName())
|
||||||
|
.instantiateApplication(cl, className);
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1205,6 +1208,7 @@ public class Instrumentation {
|
||||||
|
ClassNotFoundException {
|
||||||
|
Application app = (Application)clazz.newInstance();
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..621156eb84b9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2021 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.internal.gmscompat;
|
||||||
|
+
|
||||||
|
+import android.app.Application;
|
||||||
|
+import android.os.Build;
|
||||||
|
+import android.os.SystemProperties;
|
||||||
|
+import android.util.Log;
|
||||||
|
+
|
||||||
|
+import java.lang.reflect.Field;
|
||||||
|
+
|
||||||
|
+/** @hide */
|
||||||
|
+public final class AttestationHooks {
|
||||||
|
+ private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+
|
||||||
|
+ private AttestationHooks() { }
|
||||||
|
+
|
||||||
|
+ private static void setBuildField(String key, String value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void spoofBuildGms() {
|
||||||
|
+ // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||||
|
Subject: [PATCH 2/8] keystore: Block key attestation for SafetyNet
|
||||||
|
|
||||||
|
SafetyNet (part of Google Play Services) opportunistically uses
|
||||||
|
hardware-backed key attestation via KeyStore as a strong integrity
|
||||||
|
check. This causes SafetyNet to fail on custom ROMs because the verified
|
||||||
|
boot key and bootloader unlock state can be detected from attestation
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
As a workaround, we can take advantage of the fact that SafetyNet's
|
||||||
|
usage of key attestation is opportunistic (i.e. falls back to basic
|
||||||
|
integrity checks if it fails) and prevent it from getting the
|
||||||
|
attestation certificate chain from KeyStore. This is done by checking
|
||||||
|
the stack for DroidGuard, which is the codename for SafetyNet, and
|
||||||
|
pretending that the device doesn't support key attestation.
|
||||||
|
|
||||||
|
Key attestation has only been blocked for SafetyNet specifically, as
|
||||||
|
Google Play Services and other apps have many valid reasons to use it.
|
||||||
|
For example, it appears to be involved in Google's mobile security key
|
||||||
|
ferature.
|
||||||
|
|
||||||
|
Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||||
|
.../security/keystore2/AndroidKeyStoreSpi.java | 3 +++
|
||||||
|
2 files changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 621156eb84b9..fe12dfe02a9f 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
|
||||||
|
+ private static volatile boolean sIsGms = false;
|
||||||
|
+
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
private static void setBuildField(String key, String value) {
|
||||||
|
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ private static boolean isCallerSafetyNet() {
|
||||||
|
+ return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ .anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void onEngineGetCertificateChain() {
|
||||||
|
+ // Check stack for SafetyNet
|
||||||
|
+ if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
|
||||||
|
index 33411e1ec5b9..133a4094d434 100644
|
||||||
|
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
|
||||||
|
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
|
||||||
|
@@ -42,6 +42,7 @@ import android.system.keystore2.ResponseCode;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
@@ -164,6 +165,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
|
+ AttestationHooks.onEngineGetCertificateChain();
|
||||||
|
+
|
||||||
|
KeyEntryResponse response = getKeyMetadata(alias);
|
||||||
|
|
||||||
|
if (response == null || response.metadata.certificate == null) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||||
|
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||||
|
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||||
|
>=33
|
||||||
|
|
||||||
|
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||||
|
Setting it to 32 allows for software attestation and passing CTS.
|
||||||
|
|
||||||
|
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index fe12dfe02a9f..f512adc3985b 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static void setVersionField(String key, Integer value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name to avoid hardware attestation enforcement
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||||
|
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||||
|
|
||||||
|
The unstable process is where SafetyNet attestation actually runs, so
|
||||||
|
we only need to spoof the model in that process. Leaving other processes
|
||||||
|
fixes various issues caused by model detection and flag provisioning,
|
||||||
|
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||||
|
weather and settings on Android 12, and more.
|
||||||
|
|
||||||
|
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index f512adc3985b..c1021dd2eb22 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
|
||||||
|
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||||
|
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||||
|
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||||
|
aswell
|
||||||
|
|
||||||
|
Play Store is used for the new Play Integrity API, extend the hack
|
||||||
|
to it aswell
|
||||||
|
|
||||||
|
Test: Device Integrity and Basic Integrity passes.
|
||||||
|
|
||||||
|
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index c1021dd2eb22..6a4aab000fe0 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||||
|
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
+ private static volatile boolean sIsFinsky = false;
|
||||||
|
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
+ sIsFinsky = true;
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||||
|
if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Check stack for PlayIntegrity
|
||||||
|
+ if (sIsFinsky) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||||
|
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||||
|
|
||||||
|
Google seems to have patched the KM block to Play Store in record time,
|
||||||
|
but is still not enforced for anything under android N.
|
||||||
|
|
||||||
|
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||||
|
anymore, however the KM block is still needed.
|
||||||
|
|
||||||
|
Test: Run Play Intregrity Attestation
|
||||||
|
|
||||||
|
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
- // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
sIsFinsky = true;
|
||||||
|
- spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||||
|
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||||
|
|
||||||
|
The logic behind CTS and Play Integrity has been updated today it now
|
||||||
|
checks the product and model names against the fingerprint and if
|
||||||
|
they do not match the CTS profile will fail.
|
||||||
|
|
||||||
|
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||||
|
for key attestation blocking for debugging.
|
||||||
|
|
||||||
|
Test: Boot, check for CTS and Play Integrity
|
||||||
|
|
||||||
|
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||||
|
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
- setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
- }
|
||||||
|
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
+ setBuildField("PRODUCT", "marlin");
|
||||||
|
+ setBuildField("DEVICE", "marlin");
|
||||||
|
+ setBuildField("MODEL", "Pixel XL");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ return sIsGms && Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
.anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onEngineGetCertificateChain() {
|
||||||
|
- // Check stack for SafetyNet
|
||||||
|
- if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
- throw new UnsupportedOperationException();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // Check stack for PlayIntegrity
|
||||||
|
- if (sIsFinsky) {
|
||||||
|
+ // Check stack for SafetyNet or Play Integrity
|
||||||
|
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||||
|
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Davide Garberi <dade.garberi@gmail.com>
|
||||||
|
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||||
|
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||||
|
|
||||||
|
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index b10cb04cb4f3..04a536d8073d 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
- setBuildField("PRODUCT", "marlin");
|
||||||
|
- setBuildField("DEVICE", "marlin");
|
||||||
|
- setBuildField("MODEL", "Pixel XL");
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
+ setBuildField("DEVICE", "bullhead");
|
||||||
|
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||||
|
+ setBuildField("MODEL", "Nexus 5X");
|
||||||
|
+ setBuildField("PRODUCT", "bullhead");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
85
Patches/LineageOS-19.1/android_system_core/snet-19.patch
Normal file
85
Patches/LineageOS-19.1/android_system_core/snet-19.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||||
|
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||||
|
|
||||||
|
Google's SafetyNet integrity checks will check the values of these
|
||||||
|
properties when performing basic attestation. Setting fake values helps
|
||||||
|
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||||
|
|
||||||
|
Note that these properties need to be set very early, before parsing the
|
||||||
|
kernel command-line, as they are read-only properties that the bootloader
|
||||||
|
sets using androidboot kernel arguments. The bootloader's real values
|
||||||
|
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||||
|
software because the verified boot chain is broken in that case.
|
||||||
|
|
||||||
|
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||||
|
|
||||||
|
fastboot: Revert to Android 11 method of checking lock status
|
||||||
|
|
||||||
|
Now that we're setting system-wide properties for SafetyNet, which
|
||||||
|
includes ro.boot.verifiedbootstate=green, fastbootd always detects the
|
||||||
|
bootloader as being locked. Revert to the Android 11 method of reading
|
||||||
|
directly from the kernel cmdline to work arround the issue.
|
||||||
|
|
||||||
|
- Also don't set these in recovery
|
||||||
|
|
||||||
|
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||||
|
---
|
||||||
|
fastboot/device/utility.cpp | 7 ++++++-
|
||||||
|
init/property_service.cpp | 17 +++++++++++++++++
|
||||||
|
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
|
||||||
|
index b8b3119ac..f9267e0eb 100644
|
||||||
|
--- a/fastboot/device/utility.cpp
|
||||||
|
+++ b/fastboot/device/utility.cpp
|
||||||
|
@@ -204,7 +204,12 @@ std::vector<std::string> ListPartitions(FastbootDevice* device) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetDeviceLockStatus() {
|
||||||
|
- return android::base::GetProperty("ro.boot.verifiedbootstate", "") == "green";
|
||||||
|
+ std::string cmdline;
|
||||||
|
+ // Return lock status true if unable to read kernel command line.
|
||||||
|
+ if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return cmdline.find("androidboot.verifiedbootstate=orange") == std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateAllPartitionMetadata(FastbootDevice* device, const std::string& super_name,
|
||||||
|
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||||
|
index d429fc762..c73a2fa5d 100644
|
||||||
|
--- a/init/property_service.cpp
|
||||||
|
+++ b/init/property_service.cpp
|
||||||
|
@@ -1251,6 +1251,15 @@ static void ProcessBootconfig() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void SetSafetyNetProps() {
|
||||||
|
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||||
|
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||||
|
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||||
|
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||||
|
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||||
|
+ InitPropertySet("ro.warranty_bit", "0");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void PropertyInit() {
|
||||||
|
selinux_callback cb;
|
||||||
|
cb.func_audit = PropertyAuditCallback;
|
||||||
|
@@ -1265,6 +1274,14 @@ void PropertyInit() {
|
||||||
|
LOG(FATAL) << "Failed to load serialized property info file";
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||||
|
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||||
|
+ // these properties are read-only and will be set to invalid values with
|
||||||
|
+ // androidboot cmdline arguments.
|
||||||
|
+ if (!IsRecoveryMode()) {
|
||||||
|
+ SetSafetyNetProps();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// If arguments are passed both on the command line and in DT,
|
||||||
|
// properties set in DT always have priority over the command-line ones.
|
||||||
|
ProcessKernelDt();
|
510
Patches/LineageOS-20.0/android_frameworks_base/snet-20.patch
Normal file
510
Patches/LineageOS-20.0/android_frameworks_base/snet-20.patch
Normal file
@ -0,0 +1,510 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 19:59:51 -0700
|
||||||
|
Subject: [PATCH 1/8] Alter model name to avoid SafetyNet HW attestation
|
||||||
|
enforcement
|
||||||
|
|
||||||
|
As of September 2, Google is enforcing SafetyNet's previously
|
||||||
|
opportunistic hardware-backed attestation based on device information.
|
||||||
|
Append a space to the device model name in order to avoid such
|
||||||
|
enforcement.
|
||||||
|
|
||||||
|
Also contains:
|
||||||
|
Spoof build fingerprint for Google Play Services
|
||||||
|
|
||||||
|
SafetyNet's CTS profile attestation checks whether Build.FINGERPRINT
|
||||||
|
matches that of the device's stock OS, which has passed CTS testing.
|
||||||
|
Spoof the fingerprint for Google Play Services to help pass SafetyNet.
|
||||||
|
|
||||||
|
We used to set the real system build fingerprint to the stock one, but
|
||||||
|
Android relies on each build having a unique fingerprint in order to
|
||||||
|
clear the correct caches and update persistent state for system changes.
|
||||||
|
On devices that no longer receive updates from the OEM, the build
|
||||||
|
fingerprint never changes and Android doesn't account for updates
|
||||||
|
correctly, which causes issues when updating without wiping data.
|
||||||
|
Only spoofing the fingerprint for Google Play Services fixes this issue.
|
||||||
|
|
||||||
|
Corresponding vendor commit:
|
||||||
|
"Only use stock build fingerprint for Google Play Services"
|
||||||
|
|
||||||
|
NB: This code is under the gmscompat package, but it does not depend on
|
||||||
|
any code from gmscompat.
|
||||||
|
|
||||||
|
Change-Id: I26a2498eb2e2163933303b03f6d516e5fb30fe51
|
||||||
|
|
||||||
|
* We don't need to spoof the fingerprint here since we do it globally, but we
|
||||||
|
use the Build field spoofing code it added for model
|
||||||
|
|
||||||
|
Change-Id: Ib7779e0aae40cab3730a56785e9231896917ab0a
|
||||||
|
---
|
||||||
|
core/java/android/app/Instrumentation.java | 4 ++
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 59 +++++++++++++++++++
|
||||||
|
2 files changed, 63 insertions(+)
|
||||||
|
create mode 100644 core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
|
||||||
|
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
|
||||||
|
index 556058b567f9..44449588bbab 100644
|
||||||
|
--- a/core/java/android/app/Instrumentation.java
|
||||||
|
+++ b/core/java/android/app/Instrumentation.java
|
||||||
|
@@ -57,6 +57,8 @@ import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
|
import com.android.internal.content.ReferrerIntent;
|
||||||
|
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
+
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
@@ -1242,6 +1244,7 @@ public class Instrumentation {
|
||||||
|
Application app = getFactory(context.getPackageName())
|
||||||
|
.instantiateApplication(cl, className);
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1259,6 +1262,7 @@ public class Instrumentation {
|
||||||
|
ClassNotFoundException {
|
||||||
|
Application app = (Application)clazz.newInstance();
|
||||||
|
app.attach(context);
|
||||||
|
+ AttestationHooks.initApplicationBeforeOnCreate(app);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000000..621156eb84b9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -0,0 +1,59 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2021 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.internal.gmscompat;
|
||||||
|
+
|
||||||
|
+import android.app.Application;
|
||||||
|
+import android.os.Build;
|
||||||
|
+import android.os.SystemProperties;
|
||||||
|
+import android.util.Log;
|
||||||
|
+
|
||||||
|
+import java.lang.reflect.Field;
|
||||||
|
+
|
||||||
|
+/** @hide */
|
||||||
|
+public final class AttestationHooks {
|
||||||
|
+ private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
+ private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+
|
||||||
|
+ private AttestationHooks() { }
|
||||||
|
+
|
||||||
|
+ private static void setBuildField(String key, String value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static void spoofBuildGms() {
|
||||||
|
+ // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 11 Oct 2021 20:00:44 -0700
|
||||||
|
Subject: [PATCH 2/8] keystore: Block key attestation for SafetyNet
|
||||||
|
|
||||||
|
SafetyNet (part of Google Play Services) opportunistically uses
|
||||||
|
hardware-backed key attestation via KeyStore as a strong integrity
|
||||||
|
check. This causes SafetyNet to fail on custom ROMs because the verified
|
||||||
|
boot key and bootloader unlock state can be detected from attestation
|
||||||
|
certificates.
|
||||||
|
|
||||||
|
As a workaround, we can take advantage of the fact that SafetyNet's
|
||||||
|
usage of key attestation is opportunistic (i.e. falls back to basic
|
||||||
|
integrity checks if it fails) and prevent it from getting the
|
||||||
|
attestation certificate chain from KeyStore. This is done by checking
|
||||||
|
the stack for DroidGuard, which is the codename for SafetyNet, and
|
||||||
|
pretending that the device doesn't support key attestation.
|
||||||
|
|
||||||
|
Key attestation has only been blocked for SafetyNet specifically, as
|
||||||
|
Google Play Services and other apps have many valid reasons to use it.
|
||||||
|
For example, it appears to be involved in Google's mobile security key
|
||||||
|
ferature.
|
||||||
|
|
||||||
|
Change-Id: I5146439d47f42dc6231cb45c4dab9f61540056f6
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 16 ++++++++++++++++
|
||||||
|
.../security/keystore2/AndroidKeyStoreSpi.java | 3 +++
|
||||||
|
2 files changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 621156eb84b9..fe12dfe02a9f 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -22,12 +22,15 @@ import android.os.SystemProperties;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
+import java.util.Arrays;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
|
||||||
|
+ private static volatile boolean sIsGms = false;
|
||||||
|
+
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
private static void setBuildField(String key, String value) {
|
||||||
|
@@ -53,7 +56,20 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ private static boolean isCallerSafetyNet() {
|
||||||
|
+ return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ .anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void onEngineGetCertificateChain() {
|
||||||
|
+ // Check stack for SafetyNet
|
||||||
|
+ if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
|
||||||
|
index 33411e1ec5b9..133a4094d434 100644
|
||||||
|
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
|
||||||
|
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
|
||||||
|
@@ -42,6 +42,7 @@ import android.system.keystore2.ResponseCode;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
+import com.android.internal.gmscompat.AttestationHooks;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
@@ -164,6 +165,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
|
+ AttestationHooks.onEngineGetCertificateChain();
|
||||||
|
+
|
||||||
|
KeyEntryResponse response = getKeyMetadata(alias);
|
||||||
|
|
||||||
|
if (response == null || response.metadata.certificate == null) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anirudh Gupta <anirudhgupta109@aosip.dev>
|
||||||
|
Date: Wed, 4 Jan 2023 18:20:56 +0000
|
||||||
|
Subject: [PATCH 3/8] AttestationHooks: Set shipping level to 32 for devices
|
||||||
|
>=33
|
||||||
|
|
||||||
|
If ro.product.first_api_level is 33, it's forced to use HW attestation.
|
||||||
|
Setting it to 32 allows for software attestation and passing CTS.
|
||||||
|
|
||||||
|
Change-Id: Ie47fd00b009c93580ec8c950d223c60ed63a0d2f
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index fe12dfe02a9f..f512adc3985b 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -49,9 +49,28 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static void setVersionField(String key, Integer value) {
|
||||||
|
+ try {
|
||||||
|
+ // Unlock
|
||||||
|
+ Field field = Build.VERSION.class.getDeclaredField(key);
|
||||||
|
+ field.setAccessible(true);
|
||||||
|
+
|
||||||
|
+ // Edit
|
||||||
|
+ field.set(null, value);
|
||||||
|
+
|
||||||
|
+ // Lock
|
||||||
|
+ field.setAccessible(false);
|
||||||
|
+ } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
+ Log.e(TAG, "Failed to spoof Build.VERSION." + key, e);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name to avoid hardware attestation enforcement
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
+ if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Mon, 1 Nov 2021 20:06:48 -0700
|
||||||
|
Subject: [PATCH 4/8] Limit SafetyNet workarounds to unstable GMS process
|
||||||
|
|
||||||
|
The unstable process is where SafetyNet attestation actually runs, so
|
||||||
|
we only need to spoof the model in that process. Leaving other processes
|
||||||
|
fixes various issues caused by model detection and flag provisioning,
|
||||||
|
including screen-off Voice Match in Google Assistant, broken At a Glance
|
||||||
|
weather and settings on Android 12, and more.
|
||||||
|
|
||||||
|
Change-Id: Idcf663907a6c3d0408dbd45b1ac53c9eb4200df8
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index f512adc3985b..c1021dd2eb22 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,6 +28,7 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
|
||||||
|
@@ -74,7 +75,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
- if (PACKAGE_GMS.equals(app.getPackageName())) {
|
||||||
|
+ if (PACKAGE_GMS.equals(app.getPackageName()) &&
|
||||||
|
+ PROCESS_UNSTABLE.equals(Application.getProcessName())) {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Tue, 23 Aug 2022 18:57:05 +0200
|
||||||
|
Subject: [PATCH 5/8] gmscompat: Apply the SafetyNet workaround to Play Store
|
||||||
|
aswell
|
||||||
|
|
||||||
|
Play Store is used for the new Play Integrity API, extend the hack
|
||||||
|
to it aswell
|
||||||
|
|
||||||
|
Test: Device Integrity and Basic Integrity passes.
|
||||||
|
|
||||||
|
Change-Id: Id607cdff0b902f285a6c1b769c0a4ee4202842b1
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index c1021dd2eb22..6a4aab000fe0 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -28,9 +28,11 @@ import java.util.Arrays;
|
||||||
|
public final class AttestationHooks {
|
||||||
|
private static final String TAG = "GmsCompat/Attestation";
|
||||||
|
private static final String PACKAGE_GMS = "com.google.android.gms";
|
||||||
|
+ private static final String PACKAGE_FINSKY = "com.android.vending";
|
||||||
|
private static final String PROCESS_UNSTABLE = "com.google.android.gms.unstable";
|
||||||
|
|
||||||
|
private static volatile boolean sIsGms = false;
|
||||||
|
+ private static volatile boolean sIsFinsky = false;
|
||||||
|
|
||||||
|
private AttestationHooks() { }
|
||||||
|
|
||||||
|
@@ -80,6 +82,11 @@ public final class AttestationHooks {
|
||||||
|
sIsGms = true;
|
||||||
|
spoofBuildGms();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
+ sIsFinsky = true;
|
||||||
|
+ spoofBuildGms();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
@@ -92,5 +99,10 @@ public final class AttestationHooks {
|
||||||
|
if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Check stack for PlayIntegrity
|
||||||
|
+ if (sIsFinsky) {
|
||||||
|
+ throw new UnsupportedOperationException();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Thu, 8 Sep 2022 14:39:52 +0200
|
||||||
|
Subject: [PATCH 6/8] gmscompat: Use Nexus 6P fingerprint for CTS/Integrity
|
||||||
|
|
||||||
|
Google seems to have patched the KM block to Play Store in record time,
|
||||||
|
but is still not enforced for anything under android N.
|
||||||
|
|
||||||
|
Since we moved to angler FP we don't need to spoof model to Play Store
|
||||||
|
anymore, however the KM block is still needed.
|
||||||
|
|
||||||
|
Test: Run Play Intregrity Attestation
|
||||||
|
|
||||||
|
Change-Id: Ic2401a6e40ddfc4318a1d0faa87e42eb118ac3d1
|
||||||
|
---
|
||||||
|
.../java/com/android/internal/gmscompat/AttestationHooks.java | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6a4aab000fe0..6bd12a1c1e03 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -69,7 +69,8 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
- // Alter model name to avoid hardware attestation enforcement
|
||||||
|
+ // Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
+ setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
@@ -85,7 +86,6 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
if (PACKAGE_FINSKY.equals(app.getPackageName())) {
|
||||||
|
sIsFinsky = true;
|
||||||
|
- spoofBuildGms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dyneteve <dyneteve@hentaios.com>
|
||||||
|
Date: Wed, 8 Feb 2023 15:21:01 +0000
|
||||||
|
Subject: [PATCH 7/8] gmscompat: Make CTS/Play Integrity pass again
|
||||||
|
|
||||||
|
The logic behind CTS and Play Integrity has been updated today it now
|
||||||
|
checks the product and model names against the fingerprint and if
|
||||||
|
they do not match the CTS profile will fail.
|
||||||
|
|
||||||
|
Also while we are at it use a newer FP from Pixel XL and add logging
|
||||||
|
for key attestation blocking for debugging.
|
||||||
|
|
||||||
|
Test: Boot, check for CTS and Play Integrity
|
||||||
|
|
||||||
|
Change-Id: I089d5ef935bba40338e10c795ea7d181103ffd15
|
||||||
|
---
|
||||||
|
.../internal/gmscompat/AttestationHooks.java | 22 ++++++++-----------
|
||||||
|
1 file changed, 9 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index 6bd12a1c1e03..b10cb04cb4f3 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/angler/angler:6.0/MDB08L/2343525:user/release-keys");
|
||||||
|
- setBuildField("MODEL", Build.MODEL + " ");
|
||||||
|
- if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.S_V2);
|
||||||
|
- }
|
||||||
|
+ setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
+ setBuildField("PRODUCT", "marlin");
|
||||||
|
+ setBuildField("DEVICE", "marlin");
|
||||||
|
+ setBuildField("MODEL", "Pixel XL");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
||||||
|
@@ -90,18 +90,14 @@ public final class AttestationHooks {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCallerSafetyNet() {
|
||||||
|
- return Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
+ return sIsGms && Arrays.stream(Thread.currentThread().getStackTrace())
|
||||||
|
.anyMatch(elem -> elem.getClassName().contains("DroidGuard"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onEngineGetCertificateChain() {
|
||||||
|
- // Check stack for SafetyNet
|
||||||
|
- if (sIsGms && isCallerSafetyNet()) {
|
||||||
|
- throw new UnsupportedOperationException();
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- // Check stack for PlayIntegrity
|
||||||
|
- if (sIsFinsky) {
|
||||||
|
+ // Check stack for SafetyNet or Play Integrity
|
||||||
|
+ if (isCallerSafetyNet() || sIsFinsky) {
|
||||||
|
+ Log.i(TAG, "Blocked key attestation sIsGms=" + sIsGms + " sIsFinsky=" + sIsFinsky);
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Davide Garberi <dade.garberi@gmail.com>
|
||||||
|
Date: Wed, 8 Nov 2023 21:36:02 +0100
|
||||||
|
Subject: [PATCH 8/8] gmscompat: Use new info
|
||||||
|
|
||||||
|
Change-Id: I3cb0c55d28249b73ecc53be83bed030304c782d9
|
||||||
|
---
|
||||||
|
.../android/internal/gmscompat/AttestationHooks.java | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/core/java/com/android/internal/gmscompat/AttestationHooks.java b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
index b10cb04cb4f3..04a536d8073d 100644
|
||||||
|
--- a/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
+++ b/core/java/com/android/internal/gmscompat/AttestationHooks.java
|
||||||
|
@@ -70,11 +70,11 @@ public final class AttestationHooks {
|
||||||
|
|
||||||
|
private static void spoofBuildGms() {
|
||||||
|
// Alter model name and fingerprint to avoid hardware attestation enforcement
|
||||||
|
- setBuildField("FINGERPRINT", "google/marlin/marlin:7.1.2/NJH47F/4146041:user/release-keys");
|
||||||
|
- setBuildField("PRODUCT", "marlin");
|
||||||
|
- setBuildField("DEVICE", "marlin");
|
||||||
|
- setBuildField("MODEL", "Pixel XL");
|
||||||
|
- setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N_MR1);
|
||||||
|
+ setBuildField("DEVICE", "bullhead");
|
||||||
|
+ setBuildField("FINGERPRINT", "google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys");
|
||||||
|
+ setBuildField("MODEL", "Nexus 5X");
|
||||||
|
+ setBuildField("PRODUCT", "bullhead");
|
||||||
|
+ setVersionField("DEVICE_INITIAL_SDK_INT", Build.VERSION_CODES.N);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initApplicationBeforeOnCreate(Application app) {
|
85
Patches/LineageOS-20.0/android_system_core/snet-20.patch
Normal file
85
Patches/LineageOS-20.0/android_system_core/snet-20.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Danny Lin <danny@kdrag0n.dev>
|
||||||
|
Date: Wed, 7 Oct 2020 00:24:54 -0700
|
||||||
|
Subject: [PATCH] init: Set properties to make SafetyNet pass
|
||||||
|
|
||||||
|
Google's SafetyNet integrity checks will check the values of these
|
||||||
|
properties when performing basic attestation. Setting fake values helps
|
||||||
|
us pass basic SafetyNet with no Magisk Hide or kernel patches necessary.
|
||||||
|
|
||||||
|
Note that these properties need to be set very early, before parsing the
|
||||||
|
kernel command-line, as they are read-only properties that the bootloader
|
||||||
|
sets using androidboot kernel arguments. The bootloader's real values
|
||||||
|
cause SafetyNet to fail with an unlocked bootloader and/or custom
|
||||||
|
software because the verified boot chain is broken in that case.
|
||||||
|
|
||||||
|
Change-Id: I66d23fd91d82906b00d5eb020668f01ae83ec31f
|
||||||
|
|
||||||
|
fastboot: Revert to Android 11 method of checking lock status
|
||||||
|
|
||||||
|
Now that we're setting system-wide properties for SafetyNet, which
|
||||||
|
includes ro.boot.verifiedbootstate=green, fastbootd always detects the
|
||||||
|
bootloader as being locked. Revert to the Android 11 method of reading
|
||||||
|
directly from the kernel cmdline to work arround the issue.
|
||||||
|
|
||||||
|
- Also don't set these in recovery
|
||||||
|
|
||||||
|
Change-Id: I57f6d48acddb29748778053edf354d7bd8994bd7
|
||||||
|
---
|
||||||
|
fastboot/device/utility.cpp | 7 ++++++-
|
||||||
|
init/property_service.cpp | 17 +++++++++++++++++
|
||||||
|
2 files changed, 23 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
|
||||||
|
index 2d9b71213..a14eea376 100644
|
||||||
|
--- a/fastboot/device/utility.cpp
|
||||||
|
+++ b/fastboot/device/utility.cpp
|
||||||
|
@@ -196,7 +196,12 @@ std::vector<std::string> ListPartitions(FastbootDevice* device) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetDeviceLockStatus() {
|
||||||
|
- return android::base::GetProperty("ro.boot.verifiedbootstate", "") == "green";
|
||||||
|
+ std::string cmdline;
|
||||||
|
+ // Return lock status true if unable to read kernel command line.
|
||||||
|
+ if (!android::base::ReadFileToString("/proc/cmdline", &cmdline)) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ return cmdline.find("androidboot.verifiedbootstate=orange") == std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateAllPartitionMetadata(FastbootDevice* device, const std::string& super_name,
|
||||||
|
diff --git a/init/property_service.cpp b/init/property_service.cpp
|
||||||
|
index 7fd64b389..06709cb7c 100644
|
||||||
|
--- a/init/property_service.cpp
|
||||||
|
+++ b/init/property_service.cpp
|
||||||
|
@@ -1286,6 +1286,15 @@ static void ProcessBootconfig() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void SetSafetyNetProps() {
|
||||||
|
+ InitPropertySet("ro.boot.flash.locked", "1");
|
||||||
|
+ InitPropertySet("ro.boot.verifiedbootstate", "green");
|
||||||
|
+ InitPropertySet("ro.boot.veritymode", "enforcing");
|
||||||
|
+ InitPropertySet("ro.boot.vbmeta.device_state", "locked");
|
||||||
|
+ InitPropertySet("ro.boot.warranty_bit", "0");
|
||||||
|
+ InitPropertySet("ro.warranty_bit", "0");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void PropertyInit() {
|
||||||
|
selinux_callback cb;
|
||||||
|
cb.func_audit = PropertyAuditCallback;
|
||||||
|
@@ -1300,6 +1309,14 @@ void PropertyInit() {
|
||||||
|
LOG(FATAL) << "Failed to load serialized property info file";
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Report a valid verified boot chain to make Google SafetyNet integrity
|
||||||
|
+ // checks pass. This needs to be done before parsing the kernel cmdline as
|
||||||
|
+ // these properties are read-only and will be set to invalid values with
|
||||||
|
+ // androidboot cmdline arguments.
|
||||||
|
+ if (!IsRecoveryMode()) {
|
||||||
|
+ SetSafetyNetProps();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// If arguments are passed both on the command line and in DT,
|
||||||
|
// properties set in DT always have priority over the command-line ones.
|
||||||
|
ProcessKernelDt();
|
@ -247,6 +247,8 @@ processRelease() {
|
|||||||
--extra_apex_payload_key com.android.adbd.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.adbd.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.adservices.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.adservices.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.adservices.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.adservices.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.adservices.api.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.adservices.api.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.apex.cts.shim.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.apex.cts.shim.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.apex.cts.shim.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.apex.cts.shim.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.appsearch.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.appsearch.apex="$KEY_DIR/releasekey" \
|
||||||
@ -261,20 +263,44 @@ processRelease() {
|
|||||||
--extra_apex_payload_key com.android.cellbroadcast.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.cellbroadcast.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.compos.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.compos.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.compos.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.compos.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.configinfrastructure.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.configinfrastructure.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.connectivity.resources.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.connectivity.resources.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.conscrypt.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.conscrypt.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.conscrypt.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.conscrypt.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.devicelock.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.devicelock.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.extservices.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.extservices.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.extservices.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.extservices.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.graphics.pdf.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.graphics.pdf.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.hardware.biometrics.face.virtual.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.hardware.biometrics.face.virtual.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.hardware.biometrics.fingerprint.virtual.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.hardware.biometrics.fingerprint.virtual.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.hardware.cas.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.hardware.cas.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.hardware.wifi.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.hardware.wifi.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.healthfitness.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.healthfitness.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.hotspot2.osulogin.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.hotspot2.osulogin.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.i18n.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.i18n.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.i18n.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.i18n.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.ipsec.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.ipsec.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.ipsec.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.ipsec.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.media.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.media.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.media.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.media.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.media.swcodec.apex="$KEY_DIR/releasekey" \
|
|
||||||
--extra_apex_payload_key com.android.media.swcodec.apex="$KEY_DIR/avb.pem" \
|
|
||||||
--extra_apks com.android.mediaprovider.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.mediaprovider.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.mediaprovider.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.mediaprovider.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.media.swcodec.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.media.swcodec.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.nearby.halfsheet.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.nearby.halfsheet.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.networkstack.tethering.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.networkstack.tethering.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.neuralnetworks.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.neuralnetworks.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.neuralnetworks.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.neuralnetworks.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.ondevicepersonalization.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.ondevicepersonalization.apex="$KEY_DIR/releasekey" \
|
||||||
@ -285,30 +311,52 @@ processRelease() {
|
|||||||
--extra_apex_payload_key com.android.permission.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.permission.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.resolv.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.resolv.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.resolv.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.resolv.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.rkpd.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.rkpd.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.runtime.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.runtime.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.runtime.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.runtime.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.safetycenter.resources.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.safetycenter.resources.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.scheduling.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.scheduling.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.scheduling.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.scheduling.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.sdkext.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.sdkext.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.sdkext.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.sdkext.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.support.apexer.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.support.apexer.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.telephony.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.telephony.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.telephonymodules.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.telephonymodules.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.tethering.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.tethering.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.tethering.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.tethering.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.tzdata.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.tzdata.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.tzdata.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.tzdata.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.uwb.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.uwb.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.uwb.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.uwb.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.uwb.resources.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.uwb.resources.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.vibrator.drv2624.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.vibrator.drv2624.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.vibrator.sunfish.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.vibrator.sunfish.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.virt.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.virt.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.virt.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.virt.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.vndk.current.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.vndk.current.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.vndk.current.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.vndk.current.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.vndk.current.on_vendor.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.vndk.current.on_vendor.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.wifi.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.android.wifi.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.wifi.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.android.wifi.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.wifi.dialog.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.wifi.dialog.apex="$KEY_DIR/avb.pem" \
|
||||||
|
--extra_apks com.android.wifi.resources.apex="$KEY_DIR/releasekey" \
|
||||||
|
--extra_apex_payload_key com.android.wifi.resources.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.google.pixel.camera.hal.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.google.pixel.camera.hal.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.google.pixel.camera.hal.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.google.pixel.camera.hal.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.vibrator.sunfish.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.google.pixel.vibrator.hal.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.vibrator.sunfish.apex="$KEY_DIR/avb.pem" \
|
--extra_apex_payload_key com.google.pixel.vibrator.hal.apex="$KEY_DIR/avb.pem" \
|
||||||
--extra_apks com.android.vibrator.drv2624.apex="$KEY_DIR/releasekey" \
|
--extra_apks com.qorvo.uwb.apex="$KEY_DIR/releasekey" \
|
||||||
--extra_apex_payload_key com.android.vibrator.drv2624.apex="$KEY_DIR/avb.pem");
|
--extra_apex_payload_key com.qorvo.uwb.apex="$KEY_DIR/avb.pem");
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
#Malware Scan
|
#Malware Scan
|
||||||
@ -881,8 +929,10 @@ export -f changeDefaultDNS;
|
|||||||
|
|
||||||
editKernelLocalversion() {
|
editKernelLocalversion() {
|
||||||
local defconfigPath=$(getDefconfig)
|
local defconfigPath=$(getDefconfig)
|
||||||
sed -i 's/CONFIG_LOCALVERSION=".*"/CONFIG_LOCALVERSION="'"$1"'"/' $defconfigPath &>/dev/null || true;
|
local replacement=$1;
|
||||||
sed -zi '/CONFIG_LOCALVERSION="'"$1"'"/!s/$/\nCONFIG_LOCALVERSION="'"$1"'"/' $defconfigPath &>/dev/null;
|
if [ "$DOS_SNET" = true ]; then local replacement="-oink"; fi;
|
||||||
|
sed -i 's/CONFIG_LOCALVERSION=".*"/CONFIG_LOCALVERSION="'"$replacement"'"/' $defconfigPath &>/dev/null || true;
|
||||||
|
sed -zi '/CONFIG_LOCALVERSION="'"$replacement"'"/!s/$/\nCONFIG_LOCALVERSION="'"$replacement"'"/' $defconfigPath &>/dev/null;
|
||||||
}
|
}
|
||||||
export -f editKernelLocalversion;
|
export -f editKernelLocalversion;
|
||||||
|
|
||||||
@ -896,7 +946,7 @@ getDefconfig() {
|
|||||||
else
|
else
|
||||||
#grep TARGET_KERNEL_CONFIG Build/*/device/ -Rih | sed 's|TARGET_KERNEL_CONFIG .= |arch/arm\*/configs/|' | grep -v lineage | sort -u
|
#grep TARGET_KERNEL_CONFIG Build/*/device/ -Rih | sed 's|TARGET_KERNEL_CONFIG .= |arch/arm\*/configs/|' | grep -v lineage | sort -u
|
||||||
#grep TARGET_KERNEL_VARIANT_CONFIG Build/*/device/ -Rih | sed 's|TARGET_KERNEL_VARIANT_CONFIG .= |arch/arm\*/configs/|' | grep -v lineage | sort -u
|
#grep TARGET_KERNEL_VARIANT_CONFIG Build/*/device/ -Rih | sed 's|TARGET_KERNEL_VARIANT_CONFIG .= |arch/arm\*/configs/|' | grep -v lineage | sort -u
|
||||||
local defconfigPath="arch/arm*/configs/lineage*defconfig arch/arm*/configs/vendor/lineage*defconfig arch/arm*/configs/apollo_defconfig arch/arm*/configs/apq8084_sec_defconfig arch/arm*/configs/apq8084_sec_kccat6_eur_defconfig arch/arm*/configs/apq8084_sec_lentislte_skt_defconfig arch/arm*/configs/athene_defconfig arch/arm*/configs/aura_defconfig arch/arm*/configs/b1c1_defconfig arch/arm*/configs/beryllium_defconfig arch/arm*/configs/bonito_defconfig arch/arm*/configs/clark_defconfig arch/arm*/configs/cloudripper_gki_defconfig arch/arm*/configs/discovery_defconfig arch/arm*/configs/enchilada_defconfig arch/arm*/configs/exynos8890-hero2lte_defconfig arch/arm*/configs/exynos8890-herolte_defconfig arch/arm*/configs/exynos9810-crownlte_defconfig arch/arm*/configs/exynos9810-star2lte_defconfig arch/arm*/configs/exynos9810-starlte_defconfig arch/arm*/configs/floral_defconfig arch/arm*/configs/FP4_defconfig arch/arm*/configs/griffin_defconfig arch/arm*/configs/grouper_defconfig arch/arm*/configs/harpia_defconfig arch/arm*/configs/jactive_eur_defconfig arch/arm*/configs/jf_att_defconfig arch/arm*/configs/jf_eur_defconfig arch/arm*/configs/jf_spr_defconfig arch/arm*/configs/jfve_eur_defconfig arch/arm*/configs/jf_vzw_defconfig arch/arm*/configs/kirin_defconfig arch/arm*/configs/lavender_defconfig arch/arm*/configs/m1s1_defconfig arch/arm*/configs/m7_defconfig arch/arm*/configs/m8_defconfig arch/arm*/configs/m8dug_defconfig arch/arm*/configs/merlin_defconfig arch/arm*/configs/mermaid_defconfig arch/arm*/configs/msm8930_serrano_eur_3g_defconfig arch/arm*/configs/msm8930_serrano_eur_lte_defconfig arch/arm*/configs/msm8974-hdx_defconfig arch/arm*/configs/msm8974-hdx-perf_defconfig arch/arm*/configs/oneplus2_defconfig arch/arm*/configs/osprey_defconfig arch/arm*/configs/pioneer_defconfig arch/arm*/configs/platina_defconfig arch/arm*/configs/redbull_defconfig arch/arm*/configs/samsung_serrano_defconfig arch/arm*/configs/samsung_serrano_usa_defconfig arch/arm*/configs/shamu_defconfig arch/arm*/configs/slider_gki_defconfig arch/arm*/configs/sunfish_defconfig arch/arm*/configs/surnia_defconfig arch/arm*/configs/tama_akari_defconfig arch/arm*/configs/tama_akatsuki_defconfig arch/arm*/configs/tama_apollo_defconfig arch/arm*/configs/tama_aurora_defconfig arch/arm*/configs/thor_defconfig arch/arm*/configs/tulip_defconfig arch/arm*/configs/tuna_defconfig arch/arm*/configs/twrp_defconfig arch/arm*/configs/vendor/alioth_defconfig arch/arm*/configs/vendor/apollo_defconfig arch/arm*/configs/vendor/davinci.config arch/arm*/configs/vendor/fairphone/FP4.config arch/arm*/configs/vendor/kona-perf_defconfig arch/arm*/configs/vendor/lahaina-qgki_defconfig arch/arm*/configs/vendor/lito-perf_defconfig arch/arm*/configs/vendor/lmi_defconfig arch/arm*/configs/vendor/msm8937-perf_defconfig arch/arm*/configs/vendor/raphael_defconfig arch/arm*/configs/vendor/sdmsteppe-perf_defconfig arch/arm*/configs/vendor/sm8150-perf_defconfig arch/arm*/configs/vendor/vayu_defconfig arch/arm*/configs/vendor/vendor/fairphone/FP4.config arch/arm*/configs/vendor/vendor/xiaomi/sm8250-common.config arch/arm*/configs/vendor/xiaomi/alioth.config arch/arm*/configs/vendor/xiaomi/apollo.config arch/arm*/configs/vendor/xiaomi/beryllium.config arch/arm*/configs/vendor/xiaomi/dipper.config arch/arm*/configs/vendor/xiaomi/equuleus.config arch/arm*/configs/vendor/xiaomi/lmi.config arch/arm*/configs/vendor/xiaomi/mi845_defconfig arch/arm*/configs/vendor/xiaomi/polaris.config arch/arm*/configs/vendor/xiaomi/sm8150-common.config arch/arm*/configs/vendor/xiaomi/sm8250-common.config arch/arm*/configs/vendor/xiaomi/ursa.config arch/arm*/configs/vendor/xiaomi/vayu.config arch/arm*/configs/voyager_defconfig arch/arm*/configs/wayne_defconfig arch/arm*/configs/whyred_defconfig arch/arm*/configs/yellowstone_defconfig arch/arm*/configs/Z00T_defconfig arch/arm*/configs/z2_plus_defconfig arch/arm*/configs/zenfone3-perf_defconfig";
|
local defconfigPath="arch/arm*/configs/lineage*defconfig arch/arm*/configs/vendor/lineage*defconfig arch/arm*/configs/apollo_defconfig arch/arm*/configs/apq8084_sec_defconfig arch/arm*/configs/apq8084_sec_kccat6_eur_defconfig arch/arm*/configs/apq8084_sec_lentislte_skt_defconfig arch/arm*/configs/athene_defconfig arch/arm*/configs/aura_defconfig arch/arm*/configs/b1c1_defconfig arch/arm*/configs/beryllium_defconfig arch/arm*/configs/bonito_defconfig arch/arm*/configs/clark_defconfig arch/arm*/configs/cloudripper_gki_defconfig arch/arm*/configs/discovery_defconfig arch/arm*/configs/enchilada_defconfig arch/arm*/configs/exynos8890-hero2lte_defconfig arch/arm*/configs/exynos8890-herolte_defconfig arch/arm*/configs/exynos9810-crownlte_defconfig arch/arm*/configs/exynos9810-star2lte_defconfig arch/arm*/configs/exynos9810-starlte_defconfig arch/arm*/configs/floral_defconfig arch/arm*/configs/FP4_defconfig arch/arm*/configs/griffin_defconfig arch/arm*/configs/grouper_defconfig arch/arm*/configs/harpia_defconfig arch/arm*/configs/jactive_eur_defconfig arch/arm*/configs/jf_att_defconfig arch/arm*/configs/jf_eur_defconfig arch/arm*/configs/jf_spr_defconfig arch/arm*/configs/jfve_eur_defconfig arch/arm*/configs/jf_vzw_defconfig arch/arm*/configs/kirin_defconfig arch/arm*/configs/lavender_defconfig arch/arm*/configs/m1s1_defconfig arch/arm*/configs/m7_defconfig arch/arm*/configs/m8_defconfig arch/arm*/configs/m8dug_defconfig arch/arm*/configs/merlin_defconfig arch/arm*/configs/mermaid_defconfig arch/arm*/configs/msm8930_serrano_eur_3g_defconfig arch/arm*/configs/msm8930_serrano_eur_lte_defconfig arch/arm*/configs/msm8974-hdx_defconfig arch/arm*/configs/msm8974-hdx-perf_defconfig arch/arm*/configs/oneplus2_defconfig arch/arm*/configs/osprey_defconfig arch/arm*/configs/pioneer_defconfig arch/arm*/configs/platina_defconfig arch/arm*/configs/redbull_defconfig arch/arm*/configs/samsung_serrano_defconfig arch/arm*/configs/samsung_serrano_usa_defconfig arch/arm*/configs/shamu_defconfig arch/arm*/configs/slider_gki_defconfig arch/arm*/configs/sunfish_defconfig arch/arm*/configs/surnia_defconfig arch/arm*/configs/tama_akari_defconfig arch/arm*/configs/tama_akatsuki_defconfig arch/arm*/configs/tama_apollo_defconfig arch/arm*/configs/tama_aurora_defconfig arch/arm*/configs/thor_defconfig arch/arm*/configs/tulip_defconfig arch/arm*/configs/tuna_defconfig arch/arm*/configs/twrp_defconfig arch/arm*/configs/vendor/alioth_defconfig arch/arm*/configs/vendor/apollo_defconfig arch/arm*/configs/vendor/davinci.config arch/arm*/configs/vendor/fairphone/FP4.config arch/arm*/configs/vendor/kona-perf_defconfig arch/arm*/configs/vendor/lahaina-qgki_defconfig arch/arm*/configs/vendor/lito-perf_defconfig arch/arm*/configs/vendor/lmi_defconfig arch/arm*/configs/vendor/msm8937-perf_defconfig arch/arm*/configs/vendor/raphael_defconfig arch/arm*/configs/vendor/sdmsteppe-perf_defconfig arch/arm*/configs/vendor/sm8150-perf_defconfig arch/arm*/configs/vendor/vayu_defconfig arch/arm*/configs/vendor/vendor/fairphone/FP4.config arch/arm*/configs/vendor/vendor/xiaomi/sm8150-common.config arch/arm*/configs/vendor/vendor/xiaomi/sm8250-common.config arch/arm*/configs/vendor/xiaomi/alioth.config arch/arm*/configs/vendor/xiaomi/apollo.config arch/arm*/configs/vendor/xiaomi/beryllium.config arch/arm*/configs/vendor/xiaomi/dipper.config arch/arm*/configs/vendor/xiaomi/equuleus.config arch/arm*/configs/vendor/xiaomi/lmi.config arch/arm*/configs/vendor/xiaomi/mi845_defconfig arch/arm*/configs/vendor/xiaomi/polaris.config arch/arm*/configs/vendor/xiaomi/sm8150-common.config arch/arm*/configs/vendor/xiaomi/sm8250-common.config arch/arm*/configs/vendor/xiaomi/ursa.config arch/arm*/configs/vendor/xiaomi/vayu.config arch/arm*/configs/voyager_defconfig arch/arm*/configs/wayne_defconfig arch/arm*/configs/whyred_defconfig arch/arm*/configs/yellowstone_defconfig arch/arm*/configs/Z00T_defconfig arch/arm*/configs/z2_plus_defconfig arch/arm*/configs/zenfone3-perf_defconfig";
|
||||||
fi;
|
fi;
|
||||||
echo $defconfigPath;
|
echo $defconfigPath;
|
||||||
}
|
}
|
||||||
|
@ -196,6 +196,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0013-Sensors_Permission.patch";
|
|||||||
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/0014-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
|
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/0014-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
|
||||||
#if [ "$DOS_MICROG_SUPPORT" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/0021-Unprivileged_microG_Handling.patch"; fi; #Unprivileged microG handling (heavily based off of a CalyxOS patch)
|
#if [ "$DOS_MICROG_SUPPORT" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_base/0021-Unprivileged_microG_Handling.patch"; fi; #Unprivileged microG handling (heavily based off of a CalyxOS patch)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET" = true ]; then git am "$DOS_PATCHES/android_frameworks_base/snet-16.patch"; fi;
|
||||||
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
||||||
sed -i 's/DEFAULT_MAX_FILES_LOWRAM = 300;/DEFAULT_MAX_FILES_LOWRAM = 0;/' services/core/java/com/android/server/DropBoxManagerService.java;
|
sed -i 's/DEFAULT_MAX_FILES_LOWRAM = 300;/DEFAULT_MAX_FILES_LOWRAM = 0;/' services/core/java/com/android/server/DropBoxManagerService.java;
|
||||||
sed -i 's/(notif.needNotify)/(true)/' location/java/com/android/internal/location/GpsNetInitiatedHandler.java; #Notify the user if their location is requested via SUPL
|
sed -i 's/(notif.needNotify)/(true)/' location/java/com/android/internal/location/GpsNetInitiatedHandler.java; #Notify the user if their location is requested via SUPL
|
||||||
@ -381,6 +382,7 @@ applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts
|
|||||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||||
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
||||||
#applyPatch "$DOS_PATCHES/android_system_core/0004-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
#applyPatch "$DOS_PATCHES/android_system_core/0004-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-16.patch"; fi;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "system/extras"; then
|
if enterAndClear "system/extras"; then
|
||||||
|
@ -219,6 +219,7 @@ if [ "$DOS_MICROG_SUPPORT" = true ]; then applyPatch "$DOS_PATCHES/android_frame
|
|||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0006-Do-not-throw-in-setAppOnInterfaceLocked.patch"; #Fix random reboots on broken kernels when an app has data restricted XXX: ugly (DivestOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0006-Do-not-throw-in-setAppOnInterfaceLocked.patch"; #Fix random reboots on broken kernels when an app has data restricted XXX: ugly (DivestOS)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET" = true ]; then git am "$DOS_PATCHES/android_frameworks_base/snet-17.patch"; fi;
|
||||||
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
||||||
sed -i 's/DEFAULT_MAX_FILES_LOWRAM = 300;/DEFAULT_MAX_FILES_LOWRAM = 0;/' services/core/java/com/android/server/DropBoxManagerService.java;
|
sed -i 's/DEFAULT_MAX_FILES_LOWRAM = 300;/DEFAULT_MAX_FILES_LOWRAM = 0;/' services/core/java/com/android/server/DropBoxManagerService.java;
|
||||||
sed -i 's/(notif.needNotify)/(true)/' location/java/com/android/internal/location/GpsNetInitiatedHandler.java; #Notify the user if their location is requested via SUPL
|
sed -i 's/(notif.needNotify)/(true)/' location/java/com/android/internal/location/GpsNetInitiatedHandler.java; #Notify the user if their location is requested via SUPL
|
||||||
@ -430,6 +431,7 @@ applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts
|
|||||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||||
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_system_core/0004-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_system_core/0004-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-17.patch"; fi;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "system/extras"; then
|
if enterAndClear "system/extras"; then
|
||||||
|
@ -124,6 +124,7 @@ patchWorkspaceReal() {
|
|||||||
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-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";
|
||||||
|
@ -126,8 +126,6 @@ fi;
|
|||||||
|
|
||||||
if enterAndClear "frameworks/base"; then
|
if enterAndClear "frameworks/base"; then
|
||||||
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/389013.patch"; #S_asb_2024-04 isUserInLockDown can be true when there are other strong auth requirements
|
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/389014-backport.patch"; #S_asb_2024-04 Fix security vulnerability that creates user with no restrictions when accountOptions are too long.
|
|
||||||
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)
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0009-SystemUI_No_Permission_Review.patch"; #Allow SystemUI to directly manage Bluetooth/WiFi (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0009-SystemUI_No_Permission_Review.patch"; #Allow SystemUI to directly manage Bluetooth/WiFi (GrapheneOS)
|
||||||
@ -174,6 +172,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0025-tile_restrictions.patch";
|
|||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0006-Do-not-throw-in-setAppOnInterfaceLocked.patch"; #Fix random reboots on broken kernels when an app has data restricted XXX: ugly (DivestOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0006-Do-not-throw-in-setAppOnInterfaceLocked.patch"; #Fix random reboots on broken kernels when an app has data restricted XXX: ugly (DivestOS)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET" = true ]; then git am "$DOS_PATCHES/android_frameworks_base/snet-18.patch"; fi;
|
||||||
hardenLocationConf services/core/java/com/android/server/location/gps_debug.conf; #Harden the default GPS config
|
hardenLocationConf services/core/java/com/android/server/location/gps_debug.conf; #Harden the default GPS config
|
||||||
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
||||||
sed -i 's/DEFAULT_USE_FREEZER = false;/DEFAULT_USE_FREEZER = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app freezer by default (GrapheneOS)
|
sed -i 's/DEFAULT_USE_FREEZER = false;/DEFAULT_USE_FREEZER = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app freezer by default (GrapheneOS)
|
||||||
@ -401,6 +400,7 @@ applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts
|
|||||||
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||||
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0004-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0004-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-18.patch"; fi;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "system/extras"; then
|
if enterAndClear "system/extras"; then
|
||||||
|
@ -182,6 +182,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0032-tile_restrictions.patch";
|
|||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0033-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0033-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0007-ABI_Warning.patch"; #Warn when running activity from 32 bit app on ARM64 devices. (AOSP)
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||||
|
if [ "$DOS_SNET" = true ]; then git am "$DOS_PATCHES/android_frameworks_base/snet-19.patch"; fi;
|
||||||
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
|
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
|
||||||
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
||||||
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
sed -i 's/DEFAULT_MAX_FILES = 1000;/DEFAULT_MAX_FILES = 0;/' services/core/java/com/android/server/DropBoxManagerService.java; #Disable DropBox internal logging service
|
||||||
@ -403,6 +404,7 @@ git revert --no-edit 07adb89d0f8c966c88869d1abffc57da0e707568; #insanity
|
|||||||
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||||
|
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-19.patch"; fi;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "system/extras"; then
|
if enterAndClear "system/extras"; then
|
||||||
|
@ -197,6 +197,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_base/0039-package_hooks.patch"; #Add
|
|||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0040-euicc-restrictions.patch"; #Integrate Google's EuiccSupportPixel package (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0040-euicc-restrictions.patch"; #Integrate Google's EuiccSupportPixel package (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0041-tile_restrictions.patch"; #SystemUI: Require unlocking to use sensitive QS tiles (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0041-tile_restrictions.patch"; #SystemUI: Require unlocking to use sensitive QS tiles (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0042-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0042-minimal_screenshot_exif.patch"; #Put bare minimum metadata in screenshots (CalyxOS)
|
||||||
|
if [ "$DOS_SNET" = true ]; then git am "$DOS_PATCHES/android_frameworks_base/snet-20.patch"; fi;
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_frameworks_base/0008-No_Crash_GSF.patch"; #Don't crash apps that depend on missing Gservices provider (GrapheneOS)
|
||||||
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
|
hardenLocationConf services/core/java/com/android/server/location/gnss/gps_debug.conf; #Harden the default GPS config
|
||||||
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
sed -i 's/DEFAULT_USE_COMPACTION = false;/DEFAULT_USE_COMPACTION = true;/' services/core/java/com/android/server/am/CachedAppOptimizer.java; #Enable app compaction by default (GrapheneOS)
|
||||||
@ -418,6 +419,7 @@ git revert --no-edit 942dd2ac9eed11d0ff31fb734de46c2da24b4b9b; #unknown impact
|
|||||||
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; #Add a property for controlling ptrace_scope (GrapheneOS)
|
||||||
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
|
||||||
|
if [ "$DOS_SNET_EXTRA" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/snet-20.patch"; fi;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "system/extras"; then
|
if enterAndClear "system/extras"; then
|
||||||
|
@ -67,6 +67,8 @@ export DOS_GRAPHENE_EXEC=true; #Enables use of GrapheneOS' exec spawning feature
|
|||||||
export DOS_HOSTS_BLOCKING=true; #Set false to prevent inclusion of a HOSTS file
|
export DOS_HOSTS_BLOCKING=true; #Set false to prevent inclusion of a HOSTS file
|
||||||
export DOS_HOSTS_BLOCKING_LIST="https://divested.dev/hosts-wildcards"; #Must be in the format "127.0.0.1 bad.domain.tld"
|
export DOS_HOSTS_BLOCKING_LIST="https://divested.dev/hosts-wildcards"; #Must be in the format "127.0.0.1 bad.domain.tld"
|
||||||
export DOS_MICROG_SUPPORT=true; #Opt-in unprivileged microG support on 17.1+18.1+19.1+20.0
|
export DOS_MICROG_SUPPORT=true; #Opt-in unprivileged microG support on 17.1+18.1+19.1+20.0
|
||||||
|
export DOS_SNET=false; #Selectively spoof select build properties
|
||||||
|
export DOS_SNET_EXTRA=false; #Globally spoof select bootloader properties
|
||||||
export DOS_SENSORS_PERM=false; #Set true to provide a per-app sensors permission for 14.1/15.1 #XXX: can break things like camera
|
export DOS_SENSORS_PERM=false; #Set true to provide a per-app sensors permission for 14.1/15.1 #XXX: can break things like camera
|
||||||
export DOS_STRONG_ENCRYPTION_ENABLED=false; #Set true to enable AES 256-bit FDE encryption on 14.1+15.1 #XXX: THIS WILL **DESTROY** EXISTING INSTALLS!
|
export DOS_STRONG_ENCRYPTION_ENABLED=false; #Set true to enable AES 256-bit FDE encryption on 14.1+15.1 #XXX: THIS WILL **DESTROY** EXISTING INSTALLS!
|
||||||
export DOS_USE_KSM=false; #Set true to use KSM for increased memory efficiency at the cost of easier side-channel attacks and increased CPU usage #XXX: testing only
|
export DOS_USE_KSM=false; #Set true to use KSM for increased memory efficiency at the cost of easier side-channel attacks and increased CPU usage #XXX: testing only
|
||||||
@ -145,6 +147,11 @@ if [ ! -d "$DOS_BUILD_BASE" ]; then
|
|||||||
return 1;
|
return 1;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
|
if [ "$DOS_MICROG_SUPPORT" = false ]; then
|
||||||
|
export DOS_SNET=false;
|
||||||
|
export DOS_SNET_EXTRA=false;
|
||||||
|
fi;
|
||||||
|
|
||||||
export DOS_TMP_DIR="/tmp/dos_tmp";
|
export DOS_TMP_DIR="/tmp/dos_tmp";
|
||||||
mkdir -p "$DOS_TMP_DIR";
|
mkdir -p "$DOS_TMP_DIR";
|
||||||
export DOS_HOSTS_FILE="$DOS_TMP_DIR/hosts";
|
export DOS_HOSTS_FILE="$DOS_TMP_DIR/hosts";
|
||||||
|
Loading…
Reference in New Issue
Block a user