diff --git a/Manifests/Manifest_LAOS-21.0.xml b/Manifests/Manifest_LAOS-21.0.xml new file mode 100644 index 00000000..48aa56a3 --- /dev/null +++ b/Manifests/Manifest_LAOS-21.0.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Patches/LineageOS-21.0/android_art/0001-constify_JNINativeMethod.patch b/Patches/LineageOS-21.0/android_art/0001-constify_JNINativeMethod.patch new file mode 100644 index 00000000..7cabbef0 --- /dev/null +++ b/Patches/LineageOS-21.0/android_art/0001-constify_JNINativeMethod.patch @@ -0,0 +1,539 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Thu, 5 Oct 2023 08:27:35 -0400 +Subject: [PATCH] constify JNINativeMethod tables + +--- + benchmark/micro-native/micro_native.cc | 8 ++++---- + runtime/native/dalvik_system_BaseDexClassLoader.cc | 2 +- + runtime/native/dalvik_system_DexFile.cc | 2 +- + runtime/native/dalvik_system_VMDebug.cc | 2 +- + runtime/native/dalvik_system_VMRuntime.cc | 2 +- + runtime/native/dalvik_system_VMStack.cc | 2 +- + runtime/native/dalvik_system_ZygoteHooks.cc | 2 +- + runtime/native/java_lang_Class.cc | 2 +- + runtime/native/java_lang_Object.cc | 2 +- + runtime/native/java_lang_StackStreamFactory.cc | 2 +- + runtime/native/java_lang_String.cc | 2 +- + runtime/native/java_lang_StringFactory.cc | 2 +- + runtime/native/java_lang_System.cc | 2 +- + runtime/native/java_lang_Thread.cc | 2 +- + runtime/native/java_lang_Throwable.cc | 2 +- + runtime/native/java_lang_VMClassLoader.cc | 2 +- + runtime/native/java_lang_invoke_MethodHandle.cc | 2 +- + runtime/native/java_lang_invoke_MethodHandleImpl.cc | 2 +- + runtime/native/java_lang_ref_FinalizerReference.cc | 2 +- + runtime/native/java_lang_ref_Reference.cc | 2 +- + runtime/native/java_lang_reflect_Array.cc | 2 +- + runtime/native/java_lang_reflect_Constructor.cc | 2 +- + runtime/native/java_lang_reflect_Executable.cc | 2 +- + runtime/native/java_lang_reflect_Field.cc | 2 +- + runtime/native/java_lang_reflect_Method.cc | 2 +- + runtime/native/java_lang_reflect_Parameter.cc | 2 +- + runtime/native/java_lang_reflect_Proxy.cc | 2 +- + runtime/native/java_util_concurrent_atomic_AtomicLong.cc | 2 +- + runtime/native/jdk_internal_misc_Unsafe.cc | 2 +- + runtime/native/libcore_io_Memory.cc | 2 +- + runtime/native/libcore_util_CharsetUtils.cc | 2 +- + .../native/org_apache_harmony_dalvik_ddmc_DdmServer.cc | 2 +- + .../org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc | 2 +- + runtime/native/sun_misc_Unsafe.cc | 2 +- + test/004-JniTest/jni_test.cc | 2 +- + test/139-register-natives/regnative.cc | 2 +- + 36 files changed, 39 insertions(+), 39 deletions(-) + +diff --git a/benchmark/micro-native/micro_native.cc b/benchmark/micro-native/micro_native.cc +index dffbf3b11d..e70366cc48 100644 +--- a/benchmark/micro-native/micro_native.cc ++++ b/benchmark/micro-native/micro_native.cc +@@ -38,7 +38,7 @@ + static void NativeMethods_emptyJniStaticSynchronizedMethod0(JNIEnv*, jclass) { } + static void NativeMethods_emptyJniSynchronizedMethod0(JNIEnv*, jclass) { } + +-static JNINativeMethod gMethods_NormalOnly[] = { ++static const JNINativeMethod gMethods_NormalOnly[] = { + NATIVE_METHOD(NativeMethods, emptyJniStaticSynchronizedMethod0, "()V"), + NATIVE_METHOD(NativeMethods, emptyJniSynchronizedMethod0, "()V"), + }; +@@ -53,7 +53,7 @@ static void NativeMethods_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarra + static void NativeMethods_emptyJniStaticMethod0(JNIEnv*, jclass) { } + static void NativeMethods_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(NativeMethods, emptyJniMethod0, "()V"), + NATIVE_METHOD(NativeMethods, emptyJniMethod6, "(IIIIII)V"), + NATIVE_METHOD(NativeMethods, emptyJniMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), +@@ -72,7 +72,7 @@ static void NativeMethods_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, + static void NativeMethods_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { } + static void NativeMethods_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { } + +-static JNINativeMethod gMethods_Fast[] = { ++static const JNINativeMethod gMethods_Fast[] = { + NATIVE_METHOD(NativeMethods, emptyJniMethod0_Fast, "()V"), + NATIVE_METHOD(NativeMethods, emptyJniMethod6_Fast, "(IIIIII)V"), + NATIVE_METHOD(NativeMethods, emptyJniMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"), +@@ -88,7 +88,7 @@ DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod0_1Critical)() { } + DEFINE_NORMAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(JNIEnv*, jclass, int, int, int, int, int, int) { } + DEFINE_CRITICAL_JNI_METHOD(void, emptyJniStaticMethod6_1Critical)(int, int, int, int, int, int) { } + +-static JNINativeMethod gMethods_Critical[] = { ++static const JNINativeMethod gMethods_Critical[] = { + // Don't use NATIVE_METHOD because the name is mangled differently. + { "emptyJniStaticMethod0_Critical", "()V", + reinterpret_cast(NAME_CRITICAL_JNI_METHOD(emptyJniStaticMethod0_1Critical)) }, +diff --git a/runtime/native/dalvik_system_BaseDexClassLoader.cc b/runtime/native/dalvik_system_BaseDexClassLoader.cc +index a4f702c28d..01ea613b1c 100644 +--- a/runtime/native/dalvik_system_BaseDexClassLoader.cc ++++ b/runtime/native/dalvik_system_BaseDexClassLoader.cc +@@ -69,7 +69,7 @@ static jobjectArray BaseDexClassLoader_computeClassLoaderContextsNative(JNIEnv* + return soa.AddLocalReference(array.Get()); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(BaseDexClassLoader, computeClassLoaderContextsNative, + "()[Ljava/lang/String;"), + }; +diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc +index f602f73630..8539ed8082 100644 +--- a/runtime/native/dalvik_system_DexFile.cc ++++ b/runtime/native/dalvik_system_DexFile.cc +@@ -994,7 +994,7 @@ static void DexFile_setTrusted(JNIEnv* env, jclass, jobject j_cookie) { + } + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(DexFile, closeDexFile, "(Ljava/lang/Object;)Z"), + NATIVE_METHOD(DexFile, + defineClassNative, +diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc +index cf2b25d6a2..d6fdb84873 100644 +--- a/runtime/native/dalvik_system_VMDebug.cc ++++ b/runtime/native/dalvik_system_VMDebug.cc +@@ -514,7 +514,7 @@ static void VMDebug_setAllocTrackerStackDepth(JNIEnv* env, jclass, jint stack_de + } + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"), + NATIVE_METHOD(VMDebug, countInstancesOfClasses, "([Ljava/lang/Class;Z)[J"), + NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;I)V"), +diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc +index f1561a2530..a1de2b5936 100644 +--- a/runtime/native/dalvik_system_VMRuntime.cc ++++ b/runtime/native/dalvik_system_VMRuntime.cc +@@ -536,7 +536,7 @@ static jobject VMRuntime_getBaseApkOptimizationInfo(JNIEnv* env, [[maybe_unused] + return env->NewObject(cls.get(), ctor, j_compiler_filter.get(), j_compilation_reason.get()); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(VMRuntime, addressOf, "(Ljava/lang/Object;)J"), + NATIVE_METHOD(VMRuntime, bootClassPath, "()Ljava/lang/String;"), + NATIVE_METHOD(VMRuntime, clampGrowthLimit, "()V"), +diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc +index 71078c9ad2..457d3887df 100644 +--- a/runtime/native/dalvik_system_VMStack.cc ++++ b/runtime/native/dalvik_system_VMStack.cc +@@ -168,7 +168,7 @@ static jobjectArray VMStack_getAnnotatedThreadStackTrace(JNIEnv* env, jclass, jo + return GetThreadStack(soa, javaThread, fn); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(VMStack, fillStackTraceElements, "(Ljava/lang/Thread;[Ljava/lang/StackTraceElement;)I"), + FAST_NATIVE_METHOD(VMStack, getCallingClassLoader, "()Ljava/lang/ClassLoader;"), + FAST_NATIVE_METHOD(VMStack, getClosestUserClassLoader, "()Ljava/lang/ClassLoader;"), +diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc +index dd44e2ec4b..22e35360a3 100644 +--- a/runtime/native/dalvik_system_ZygoteHooks.cc ++++ b/runtime/native/dalvik_system_ZygoteHooks.cc +@@ -466,7 +466,7 @@ static jboolean ZygoteHooks_nativeZygoteLongSuspendOk([[maybe_unused]] JNIEnv* e + return (isJitZygote || explicitlyDisabled) ? JNI_FALSE : JNI_TRUE; + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(ZygoteHooks, nativePreFork, "()J"), + NATIVE_METHOD(ZygoteHooks, nativePostZygoteFork, "()V"), + NATIVE_METHOD(ZygoteHooks, nativePostForkSystemServer, "(I)V"), +diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc +index 2abc4935e0..2abe4545a6 100644 +--- a/runtime/native/java_lang_Class.cc ++++ b/runtime/native/java_lang_Class.cc +@@ -971,7 +971,7 @@ static jobject Class_newInstance(JNIEnv* env, jobject javaThis) { + return soa.AddLocalReference(receiver.Get()); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Class, classForName, + "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"), + FAST_NATIVE_METHOD(Class, ensureExtDataPresent, "()Ldalvik/system/ClassExt;"), +diff --git a/runtime/native/java_lang_Object.cc b/runtime/native/java_lang_Object.cc +index 8fc10d1114..8740755199 100644 +--- a/runtime/native/java_lang_Object.cc ++++ b/runtime/native/java_lang_Object.cc +@@ -54,7 +54,7 @@ static jint Object_identityHashCodeNative(JNIEnv* env, jclass, jobject javaObjec + return static_cast(o->IdentityHashCode()); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Object, internalClone, "()Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Object, notify, "()V"), + FAST_NATIVE_METHOD(Object, notifyAll, "()V"), +diff --git a/runtime/native/java_lang_StackStreamFactory.cc b/runtime/native/java_lang_StackStreamFactory.cc +index f876c1014b..f62670350f 100644 +--- a/runtime/native/java_lang_StackStreamFactory.cc ++++ b/runtime/native/java_lang_StackStreamFactory.cc +@@ -41,7 +41,7 @@ static jint StackStreamFactory_nativeFetchStackFrameInfo(JNIEnv* env, jclass, + startLevel, batchSize, startBufferIndex, frameBuffer); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(StackStreamFactory, nativeGetStackAnchor, "()Ljava/lang/Object;"), + FAST_NATIVE_METHOD(StackStreamFactory, nativeFetchStackFrameInfo, "(JLjava/lang/Object;III[Ljava/lang/Object;)I"), + }; +diff --git a/runtime/native/java_lang_String.cc b/runtime/native/java_lang_String.cc +index f70a188e79..e982c4e3c9 100644 +--- a/runtime/native/java_lang_String.cc ++++ b/runtime/native/java_lang_String.cc +@@ -133,7 +133,7 @@ static jstring String_doRepeat(JNIEnv* env, jobject java_this, jint count) { + return soa.AddLocalReference(result); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(String, charAt, "(I)C"), + FAST_NATIVE_METHOD(String, compareTo, "(Ljava/lang/String;)I"), + FAST_NATIVE_METHOD(String, concat, "(Ljava/lang/String;)Ljava/lang/String;"), +diff --git a/runtime/native/java_lang_StringFactory.cc b/runtime/native/java_lang_StringFactory.cc +index 2fbebc0941..62f3fcd566 100644 +--- a/runtime/native/java_lang_StringFactory.cc ++++ b/runtime/native/java_lang_StringFactory.cc +@@ -294,7 +294,7 @@ static jstring StringFactory_newStringFromUtf8Bytes(JNIEnv* env, jclass, jbyteAr + return soa.AddLocalReference(result); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(StringFactory, newStringFromBytes, "([BIII)Ljava/lang/String;"), + FAST_NATIVE_METHOD(StringFactory, newStringFromChars, "(II[C)Ljava/lang/String;"), + FAST_NATIVE_METHOD(StringFactory, newStringFromString, "(Ljava/lang/String;)Ljava/lang/String;"), +diff --git a/runtime/native/java_lang_System.cc b/runtime/native/java_lang_System.cc +index 63cbd2c815..e7b3894aad 100644 +--- a/runtime/native/java_lang_System.cc ++++ b/runtime/native/java_lang_System.cc +@@ -239,7 +239,7 @@ static void System_arraycopyBooleanUnchecked(JNIEnv* env, + javaDst, dstPos, count); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(System, arraycopy, "(Ljava/lang/Object;ILjava/lang/Object;II)V"), + FAST_NATIVE_METHOD(System, arraycopyCharUnchecked, "([CI[CII)V"), + FAST_NATIVE_METHOD(System, arraycopyByteUnchecked, "([BI[BII)V"), +diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc +index 570c554782..f90db08a8d 100644 +--- a/runtime/native/java_lang_Thread.cc ++++ b/runtime/native/java_lang_Thread.cc +@@ -195,7 +195,7 @@ static void Thread_yield(JNIEnv*, jobject) { + sched_yield(); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Thread, currentThread, "()Ljava/lang/Thread;"), + FAST_NATIVE_METHOD(Thread, interrupted, "()Z"), + FAST_NATIVE_METHOD(Thread, isInterrupted, "()Z"), +diff --git a/runtime/native/java_lang_Throwable.cc b/runtime/native/java_lang_Throwable.cc +index b89e287481..5cdd70c513 100644 +--- a/runtime/native/java_lang_Throwable.cc ++++ b/runtime/native/java_lang_Throwable.cc +@@ -38,7 +38,7 @@ static jobjectArray Throwable_nativeGetStackTrace(JNIEnv* env, jclass, jobject j + return Thread::InternalStackTraceToStackTraceElementArray(soa, javaStackState); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Throwable, nativeFillInStackTrace, "()Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Throwable, nativeGetStackTrace, "(Ljava/lang/Object;)[Ljava/lang/StackTraceElement;"), + }; +diff --git a/runtime/native/java_lang_VMClassLoader.cc b/runtime/native/java_lang_VMClassLoader.cc +index 4dad46fb8c..3208a65c8e 100644 +--- a/runtime/native/java_lang_VMClassLoader.cc ++++ b/runtime/native/java_lang_VMClassLoader.cc +@@ -164,7 +164,7 @@ static jobjectArray VMClassLoader_getBootClassPathEntries(JNIEnv* env, jclass) { + MakeTransformRange(Filter(path, dchecked_is_base_dex), get_location))); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(VMClassLoader, findLoadedClass, "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;"), + NATIVE_METHOD(VMClassLoader, getBootClassPathEntries, "()[Ljava/lang/String;"), + }; +diff --git a/runtime/native/java_lang_invoke_MethodHandle.cc b/runtime/native/java_lang_invoke_MethodHandle.cc +index 5309a28a09..ed2d5ae126 100644 +--- a/runtime/native/java_lang_invoke_MethodHandle.cc ++++ b/runtime/native/java_lang_invoke_MethodHandle.cc +@@ -37,7 +37,7 @@ static void MethodHandle_invokeExactWithFrame(JNIEnv* env, jobject thiz, jobject + MethodHandleInvokeExactWithFrame(soa.Self(), handle, frame); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(MethodHandle, invokeExactWithFrame, "(Ldalvik/system/EmulatedStackFrame;)V") + }; + +diff --git a/runtime/native/java_lang_invoke_MethodHandleImpl.cc b/runtime/native/java_lang_invoke_MethodHandleImpl.cc +index 00ce01f11a..fc53b82d36 100644 +--- a/runtime/native/java_lang_invoke_MethodHandleImpl.cc ++++ b/runtime/native/java_lang_invoke_MethodHandleImpl.cc +@@ -63,7 +63,7 @@ static jobject MethodHandleImpl_getMemberInternal(JNIEnv* env, jobject thiz) { + return soa.AddLocalReference(h_object.Get()); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(MethodHandleImpl, getMemberInternal, "()Ljava/lang/reflect/Member;"), + }; + +diff --git a/runtime/native/java_lang_ref_FinalizerReference.cc b/runtime/native/java_lang_ref_FinalizerReference.cc +index 535b243411..0a8dfb6c09 100644 +--- a/runtime/native/java_lang_ref_FinalizerReference.cc ++++ b/runtime/native/java_lang_ref_FinalizerReference.cc +@@ -42,7 +42,7 @@ static jobject FinalizerReference_getReferent(JNIEnv* env, jobject javaThis) { + return soa.AddLocalReference(referent); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(FinalizerReference, makeCircularListIfUnenqueued, "()Z"), + FAST_NATIVE_METHOD(FinalizerReference, getReferent, "()Ljava/lang/Object;"), + }; +diff --git a/runtime/native/java_lang_ref_Reference.cc b/runtime/native/java_lang_ref_Reference.cc +index bd7235e14f..c2ee0f4c22 100644 +--- a/runtime/native/java_lang_ref_Reference.cc ++++ b/runtime/native/java_lang_ref_Reference.cc +@@ -76,7 +76,7 @@ static void Reference_clearReferent(JNIEnv* env, jobject javaThis) { + Runtime::Current()->GetHeap()->GetReferenceProcessor()->ClearReferent(ref); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Reference, getReferent, "()Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Reference, clearReferent, "()V"), + FAST_NATIVE_METHOD(Reference, refersTo0, "(Ljava/lang/Object;)Z"), +diff --git a/runtime/native/java_lang_reflect_Array.cc b/runtime/native/java_lang_reflect_Array.cc +index ff94593cdf..e359e7d8a8 100644 +--- a/runtime/native/java_lang_reflect_Array.cc ++++ b/runtime/native/java_lang_reflect_Array.cc +@@ -74,7 +74,7 @@ static jobject Array_createObjectArray(JNIEnv* env, jclass, jclass javaElementCl + return soa.AddLocalReference(new_array); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Array, createMultiArray, "(Ljava/lang/Class;[I)Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Array, createObjectArray, "(Ljava/lang/Class;I)Ljava/lang/Object;"), + }; +diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc +index 98afddc260..5f8196a4e5 100644 +--- a/runtime/native/java_lang_reflect_Constructor.cc ++++ b/runtime/native/java_lang_reflect_Constructor.cc +@@ -129,7 +129,7 @@ static jobject Constructor_newInstanceFromSerialization(JNIEnv* env, + return env->NewObject(allocClass, ctor); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Constructor, getExceptionTypes, "()[Ljava/lang/Class;"), + FAST_NATIVE_METHOD(Constructor, newInstance0, "([Ljava/lang/Object;)Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Constructor, newInstanceFromSerialization, "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;"), +diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc +index 87c9f6c341..db54200ef0 100644 +--- a/runtime/native/java_lang_reflect_Executable.cc ++++ b/runtime/native/java_lang_reflect_Executable.cc +@@ -363,7 +363,7 @@ static jint Executable_getParameterCountInternal(JNIEnv* env, jobject javaMethod + } + + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Executable, compareMethodParametersInternal, + "(Ljava/lang/reflect/Method;)I"), + FAST_NATIVE_METHOD(Executable, getAnnotationNative, +diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc +index f2603d4c48..e1b91c6de2 100644 +--- a/runtime/native/java_lang_reflect_Field.cc ++++ b/runtime/native/java_lang_reflect_Field.cc +@@ -549,7 +549,7 @@ static jboolean Field_isAnnotationPresentNative(JNIEnv* env, + return annotations::IsFieldAnnotationPresent(field, klass); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Field, get, "(Ljava/lang/Object;)Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Field, getBoolean, "(Ljava/lang/Object;)Z"), + FAST_NATIVE_METHOD(Field, getByte, "(Ljava/lang/Object;)B"), +diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc +index 5f02ad0fd9..e2440d3dc8 100644 +--- a/runtime/native/java_lang_reflect_Method.cc ++++ b/runtime/native/java_lang_reflect_Method.cc +@@ -86,7 +86,7 @@ static jobject Method_invoke(JNIEnv* env, jobject javaMethod, jobject javaReceiv + return InvokeMethod(soa, javaMethod, javaReceiver, javaArgs); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Method, getDefaultValue, "()Ljava/lang/Object;"), + FAST_NATIVE_METHOD(Method, getExceptionTypes, "()[Ljava/lang/Class;"), + FAST_NATIVE_METHOD(Method, invoke, "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"), +diff --git a/runtime/native/java_lang_reflect_Parameter.cc b/runtime/native/java_lang_reflect_Parameter.cc +index 263a56796f..92bf9078a4 100644 +--- a/runtime/native/java_lang_reflect_Parameter.cc ++++ b/runtime/native/java_lang_reflect_Parameter.cc +@@ -98,7 +98,7 @@ static jobject Parameter_getAnnotationNative(JNIEnv* env, + annotations::GetAnnotationForMethodParameter(method, parameterIndex, klass)); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD( + Parameter, + getAnnotationNative, +diff --git a/runtime/native/java_lang_reflect_Proxy.cc b/runtime/native/java_lang_reflect_Proxy.cc +index f723ed223d..c2b533de5d 100644 +--- a/runtime/native/java_lang_reflect_Proxy.cc ++++ b/runtime/native/java_lang_reflect_Proxy.cc +@@ -37,7 +37,7 @@ static jclass Proxy_generateProxy(JNIEnv* env, jclass, jstring name, jobjectArra + soa, name, interfaces, loader, methods, throws)); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Proxy, generateProxy, "(Ljava/lang/String;[Ljava/lang/Class;Ljava/lang/ClassLoader;[Ljava/lang/reflect/Method;[[Ljava/lang/Class;)Ljava/lang/Class;"), + }; + +diff --git a/runtime/native/java_util_concurrent_atomic_AtomicLong.cc b/runtime/native/java_util_concurrent_atomic_AtomicLong.cc +index fa288edcb8..299ac5a61d 100644 +--- a/runtime/native/java_util_concurrent_atomic_AtomicLong.cc ++++ b/runtime/native/java_util_concurrent_atomic_AtomicLong.cc +@@ -30,7 +30,7 @@ static jboolean AtomicLong_VMSupportsCS8(JNIEnv*, jclass) { + return QuasiAtomic::LongAtomicsUseMutexes(kRuntimeISA) ? JNI_FALSE : JNI_TRUE; + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(AtomicLong, VMSupportsCS8, "()Z"), + }; + +diff --git a/runtime/native/jdk_internal_misc_Unsafe.cc b/runtime/native/jdk_internal_misc_Unsafe.cc +index 9b2021d176..c9de0a1862 100644 +--- a/runtime/native/jdk_internal_misc_Unsafe.cc ++++ b/runtime/native/jdk_internal_misc_Unsafe.cc +@@ -506,7 +506,7 @@ static void Unsafe_unpark(JNIEnv* env, jobject, jobject jthread) { + } + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Unsafe, compareAndSwapInt, "(Ljava/lang/Object;JII)Z"), + FAST_NATIVE_METHOD(Unsafe, compareAndSwapLong, "(Ljava/lang/Object;JJJ)Z"), + FAST_NATIVE_METHOD( +diff --git a/runtime/native/libcore_io_Memory.cc b/runtime/native/libcore_io_Memory.cc +index 5e38280259..8648ea3799 100644 +--- a/runtime/native/libcore_io_Memory.cc ++++ b/runtime/native/libcore_io_Memory.cc +@@ -181,7 +181,7 @@ static void Memory_peekShortArray(JNIEnv* env, + } + + // The remaining Memory methods are contained in libcore/luni/src/main/native/libcore_io_Memory.cpp +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Memory, peekByteArray, "(J[BII)V"), + FAST_NATIVE_METHOD(Memory, peekCharArray, "(J[CIIZ)V"), + FAST_NATIVE_METHOD(Memory, peekDoubleArray, "(J[DIIZ)V"), +diff --git a/runtime/native/libcore_util_CharsetUtils.cc b/runtime/native/libcore_util_CharsetUtils.cc +index 46f8993a10..0c053dfb28 100644 +--- a/runtime/native/libcore_util_CharsetUtils.cc ++++ b/runtime/native/libcore_util_CharsetUtils.cc +@@ -137,7 +137,7 @@ static jbyteArray CharsetUtils_toUtf8Bytes(JNIEnv* env, jclass, jstring java_str + return soa.AddLocalReference(result); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(CharsetUtils, asciiBytesToChars, "([BII[C)V"), + FAST_NATIVE_METHOD(CharsetUtils, toAsciiBytes, "(Ljava/lang/String;II)[B"), + FAST_NATIVE_METHOD(CharsetUtils, toIsoLatin1Bytes, "(Ljava/lang/String;II)[B"), +diff --git a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc +index 419aed8578..ccbef4f3f4 100644 +--- a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc ++++ b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc +@@ -38,7 +38,7 @@ static void DdmServer_nativeSendChunk(JNIEnv* env, jclass, jint type, + Runtime::Current()->GetRuntimeCallbacks()->DdmPublishChunk(static_cast(type), chunk); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(DdmServer, nativeSendChunk, "(I[BII)V"), + }; + +diff --git a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc +index 081ec2043a..a84d522e23 100644 +--- a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc ++++ b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc +@@ -211,7 +211,7 @@ static jbyteArray DdmVmInternal_getThreadStats(JNIEnv* env, jclass) { + return result; + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(DdmVmInternal, setRecentAllocationsTrackingEnabled, "(Z)V"), + NATIVE_METHOD(DdmVmInternal, setThreadNotifyEnabled, "(Z)V"), + NATIVE_METHOD(DdmVmInternal, getStackTraceById, "(I)[Ljava/lang/StackTraceElement;"), +diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc +index f1e47ee100..d2f3a00897 100644 +--- a/runtime/native/sun_misc_Unsafe.cc ++++ b/runtime/native/sun_misc_Unsafe.cc +@@ -546,7 +546,7 @@ static void Unsafe_unpark(JNIEnv* env, jobject, jobject jthread) { + } + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + FAST_NATIVE_METHOD(Unsafe, compareAndSwapInt, "(Ljava/lang/Object;JII)Z"), + FAST_NATIVE_METHOD(Unsafe, compareAndSwapLong, "(Ljava/lang/Object;JJJ)Z"), + FAST_NATIVE_METHOD(Unsafe, compareAndSwapObject, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"), +diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc +index 429bd94fe0..1518f931ab 100644 +--- a/test/004-JniTest/jni_test.cc ++++ b/test/004-JniTest/jni_test.cc +@@ -33,7 +33,7 @@ static JavaVM* jvm = nullptr; + static jint Java_Main_intFastNativeMethod(JNIEnv*, jclass, jint a, jint b, jint c); + static jint Java_Main_intCriticalNativeMethod(jint a, jint b, jint c); + +-static JNINativeMethod sMainMethods[] = { ++static const JNINativeMethod sMainMethods[] = { + {"intFastNativeMethod", "(III)I", reinterpret_cast(Java_Main_intFastNativeMethod) }, + {"intCriticalNativeMethod", "(III)I", reinterpret_cast(Java_Main_intCriticalNativeMethod) }, + }; +diff --git a/test/139-register-natives/regnative.cc b/test/139-register-natives/regnative.cc +index d9c8b31ac7..083c14c1ec 100644 +--- a/test/139-register-natives/regnative.cc ++++ b/test/139-register-natives/regnative.cc +@@ -22,7 +22,7 @@ namespace art { + static void foo(JNIEnv*, jclass) { + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "foo", "()V", reinterpret_cast(foo) } + }; + diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-No_GWP_ASan.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-No_GWP_ASan.patch new file mode 100644 index 00000000..f5dc9abf --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-No_GWP_ASan.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Wed, 1 Nov 2023 21:27:18 +0200 +Subject: [PATCH] never enable GWP-ASan + +It weakens hardened_malloc protections, especially when memory tagging is enabled. +--- + libc/bionic/gwp_asan_wrappers.h | 7 ------- + libc/bionic/malloc_common.cpp | 8 -------- + libc/bionic/malloc_common_dynamic.cpp | 10 ---------- + 3 files changed, 25 deletions(-) + +diff --git a/libc/bionic/gwp_asan_wrappers.h b/libc/bionic/gwp_asan_wrappers.h +index 219da9fc5..9053d4aa4 100644 +--- a/libc/bionic/gwp_asan_wrappers.h ++++ b/libc/bionic/gwp_asan_wrappers.h +@@ -35,13 +35,6 @@ + #include "private/bionic_globals.h" + #include "private/bionic_malloc_dispatch.h" + +-// Enable GWP-ASan, used by android_mallopt. Should always be called in a +-// single-threaded context. +-bool EnableGwpAsan(const android_mallopt_gwp_asan_options_t& options); +- +-// Hooks for libc to possibly install GWP-ASan. +-bool MaybeInitGwpAsanFromLibc(libc_globals* globals); +- + // Returns whether GWP-ASan is the provided dispatch table pointer. Used in + // heapprofd's signal-initialization sequence to determine the intermediate + // dispatch pointer to use when initing. +diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp +index 1ab4861af..9363d7b63 100644 +--- a/libc/bionic/malloc_common.cpp ++++ b/libc/bionic/malloc_common.cpp +@@ -340,14 +340,6 @@ extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) { + if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) { + return LimitEnable(arg, arg_size); + } +- if (opcode == M_INITIALIZE_GWP_ASAN) { +- if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) { +- errno = EINVAL; +- return false; +- } +- +- return EnableGwpAsan(*reinterpret_cast(arg)); +- } + if (opcode == M_MEMTAG_STACK_IS_ON) { + if (arg == nullptr || arg_size != sizeof(bool)) { + errno = EINVAL; +diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp +index 2cafe9249..84be92ee1 100644 +--- a/libc/bionic/malloc_common_dynamic.cpp ++++ b/libc/bionic/malloc_common_dynamic.cpp +@@ -383,8 +383,6 @@ static void MallocInitImpl(libc_globals* globals) { + char prop[PROP_VALUE_MAX]; + char* options = prop; + +- MaybeInitGwpAsanFromLibc(globals); +- + #if defined(USE_SCUDO) + __libc_shared_globals()->scudo_stack_depot = __scudo_get_stack_depot_addr(); + __libc_shared_globals()->scudo_region_info = __scudo_get_region_info_addr(); +@@ -533,14 +531,6 @@ extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) { + } + return FreeMallocLeakInfo(reinterpret_cast(arg)); + } +- if (opcode == M_INITIALIZE_GWP_ASAN) { +- if (arg == nullptr || arg_size != sizeof(android_mallopt_gwp_asan_options_t)) { +- errno = EINVAL; +- return false; +- } +- +- return EnableGwpAsan(*reinterpret_cast(arg)); +- } + if (opcode == M_MEMTAG_STACK_IS_ON) { + if (arg == nullptr || arg_size != sizeof(bool)) { + errno = EINVAL; diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-1.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-1.patch new file mode 100644 index 00000000..fff89b3f --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-1.patch @@ -0,0 +1,99 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Sun, 14 Aug 2022 15:13:01 +0300 +Subject: [PATCH] add a runtime option to disable hardened_malloc + +--- + libc/bionic/malloc_common.cpp | 50 +++++++++++++++++++++++++++ + libc/bionic/malloc_common.h | 1 + + libc/bionic/malloc_common_dynamic.cpp | 4 +++ + 3 files changed, 55 insertions(+) + +diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp +index 3c4884b2c..86e6fdcf9 100644 +--- a/libc/bionic/malloc_common.cpp ++++ b/libc/bionic/malloc_common.cpp +@@ -393,6 +393,56 @@ static constexpr MallocDispatch __libc_malloc_default_dispatch __attribute__((un + Malloc(malloc_info), + }; + ++#if defined(BOTH_H_MALLOC_AND_SCUDO) ++ ++#define ScudoMalloc(function) scudo_ ## function ++ ++static constexpr MallocDispatch __scudo_malloc_dispatch __attribute__((unused)) = { ++ ScudoMalloc(calloc), ++ ScudoMalloc(free), ++ ScudoMalloc(mallinfo), ++ ScudoMalloc(malloc), ++ ScudoMalloc(malloc_usable_size), ++ ScudoMalloc(memalign), ++ ScudoMalloc(posix_memalign), ++#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) ++ ScudoMalloc(pvalloc), ++#endif ++ ScudoMalloc(realloc), ++#if defined(HAVE_DEPRECATED_MALLOC_FUNCS) ++ ScudoMalloc(valloc), ++#endif ++ ScudoMalloc(malloc_iterate), ++ ScudoMalloc(malloc_disable), ++ ScudoMalloc(malloc_enable), ++ ScudoMalloc(mallopt), ++ ScudoMalloc(aligned_alloc), ++ ScudoMalloc(malloc_info), ++}; ++ ++static const MallocDispatch* native_allocator_dispatch; ++ ++void InitNativeAllocatorDispatch(libc_globals* globals) { ++ const bool hardened_impl = getenv("DISABLE_HARDENED_MALLOC") == nullptr; ++ ++ const MallocDispatch* table = hardened_impl ? ++ &__libc_malloc_default_dispatch : ++ &__scudo_malloc_dispatch; ++ ++ if (!hardened_impl) { ++ globals->malloc_dispatch_table = __scudo_malloc_dispatch; ++ globals->current_dispatch_table = &globals->malloc_dispatch_table; ++ globals->default_dispatch_table = &globals->malloc_dispatch_table; ++ } ++ ++ native_allocator_dispatch = table; ++} ++ ++const MallocDispatch* NativeAllocatorDispatch() { ++ return native_allocator_dispatch; ++} ++#else + const MallocDispatch* NativeAllocatorDispatch() { + return &__libc_malloc_default_dispatch; + } ++#endif +diff --git a/libc/bionic/malloc_common.h b/libc/bionic/malloc_common.h +index 8852c85a2..ef4b1a4be 100644 +--- a/libc/bionic/malloc_common.h ++++ b/libc/bionic/malloc_common.h +@@ -68,6 +68,7 @@ __END_DECLS + + #if defined(USE_SCUDO) + #include "scudo.h" ++void InitNativeAllocatorDispatch(libc_globals* globals); + #endif + + #define BOTH_H_MALLOC_AND_SCUDO +diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp +index a6bf7a7bb..2cafe9249 100644 +--- a/libc/bionic/malloc_common_dynamic.cpp ++++ b/libc/bionic/malloc_common_dynamic.cpp +@@ -376,6 +376,10 @@ extern "C" size_t __scudo_get_stack_depot_size(); + + // Initializes memory allocation framework once per process. + static void MallocInitImpl(libc_globals* globals) { ++#if defined(BOTH_H_MALLOC_AND_SCUDO) ++ InitNativeAllocatorDispatch(globals); ++#endif ++ + char prop[PROP_VALUE_MAX]; + char* options = prop; + diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-2.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-2.patch new file mode 100644 index 00000000..f3add8f4 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-2.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Tue, 2 May 2023 16:45:26 +0300 +Subject: [PATCH] support assigning ID to path of current executable + +--- + libc/bionic/libc_init_dynamic.cpp | 27 ++++++++++++++++++++++++++- + libc/include/stdlib.h | 3 +++ + libc/libc.map.txt | 1 + + libc/private/bionic_globals.h | 1 + + 4 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp +index c61810e34..804e586e2 100644 +--- a/libc/bionic/libc_init_dynamic.cpp ++++ b/libc/bionic/libc_init_dynamic.cpp +@@ -72,6 +72,28 @@ extern "C" __attribute__((weak)) void __hwasan_library_unloaded(ElfW(Addr) base, + const ElfW(Phdr)* phdr, + ElfW(Half) phnum); + ++static void init_prog_id(libc_globals* globals) { ++ char exe_path[500]; ++ ssize_t readlink_res = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1 /* space for NUL terminator */); ++ if (readlink_res <= 0) { ++ return; ++ } ++ exe_path[readlink_res] = '\0'; ++ ++ int prog_id = 0; ++ ++#define IS(prog) (!strcmp(exe_path, prog)) ++ ++#undef IS ++ ++ // libc_globals struct is write-protected ++ globals->prog_id = prog_id; ++} ++ ++int get_prog_id() { ++ return __libc_globals->prog_id; ++} ++ + // We need a helper function for __libc_preinit because compiling with LTO may + // inline functions requiring a stack protector check, but __stack_chk_guard is + // not initialized at the start of __libc_preinit. __libc_preinit_impl will run +@@ -103,7 +125,10 @@ static void __libc_preinit_impl() { + #endif + + // Hooks for various libraries to let them know that we're starting up. +- __libc_globals.mutate(__libc_init_malloc); ++ __libc_globals.mutate([](libc_globals* globals) { ++ init_prog_id(globals); ++ __libc_init_malloc(globals); ++ }); + + // Install reserved signal handlers for assisting the platform's profilers. + __libc_init_profiling_handlers(); +diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h +index 2830a493d..5ce8f9103 100644 +--- a/libc/include/stdlib.h ++++ b/libc/include/stdlib.h +@@ -210,6 +210,9 @@ long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, i + // Implemented as static inlines before 26. + #endif + ++int get_prog_id(); ++#define is_prog(id) (get_prog_id() == id) ++ + __END_DECLS + + #include +diff --git a/libc/libc.map.txt b/libc/libc.map.txt +index 156e9ee32..5d87cd8ef 100644 +--- a/libc/libc.map.txt ++++ b/libc/libc.map.txt +@@ -420,6 +420,7 @@ LIBC { + get_nprocs; # introduced=23 + get_nprocs_conf; # introduced=23 + get_phys_pages; # introduced=23 ++ get_prog_id; + getaddrinfo; + getauxval; # introduced-arm=18 introduced-arm64=21 introduced-x86=18 introduced-x86_64=21 + getc; +diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h +index 8ea7d4d66..66f8d84b0 100644 +--- a/libc/private/bionic_globals.h ++++ b/libc/private/bionic_globals.h +@@ -65,6 +65,7 @@ struct libc_globals { + // limit is enabled and some other hook is enabled at the same time. + _Atomic(const MallocDispatch*) default_dispatch_table; + MallocDispatch malloc_dispatch_table; ++ int prog_id; + }; + + struct memtag_dynamic_entries_t { diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-3.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-3.patch new file mode 100644 index 00000000..eb0bc4b9 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-Runtime_Control-3.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Tue, 2 May 2023 16:46:56 +0300 +Subject: [PATCH] support disabling hardened_malloc for specific program IDs + +--- + libc/bionic/malloc_common.cpp | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp +index 86e6fdcf9..3d3e8ef61 100644 +--- a/libc/bionic/malloc_common.cpp ++++ b/libc/bionic/malloc_common.cpp +@@ -423,7 +423,11 @@ static constexpr MallocDispatch __scudo_malloc_dispatch __attribute__((unused)) + static const MallocDispatch* native_allocator_dispatch; + + void InitNativeAllocatorDispatch(libc_globals* globals) { +- const bool hardened_impl = getenv("DISABLE_HARDENED_MALLOC") == nullptr; ++ bool hardened_impl = true; ++ switch (get_prog_id()) { ++ default: ++ hardened_impl = getenv("DISABLE_HARDENED_MALLOC") == nullptr; ++ } + + const MallocDispatch* table = hardened_impl ? + &__libc_malloc_default_dispatch : diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-Use_HM.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-Use_HM.patch new file mode 100644 index 00000000..39367a0b --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-Use_HM.patch @@ -0,0 +1,189 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 5 Dec 2018 08:51:56 +0200 +Subject: [PATCH] use Scudo on 32-bit and hardened_malloc on 64-bit + +64-bit Scudo can be swithed to at runtime, see the next commit. + +Squashed with 6562b94dfc6dec13e1df79a1b029e6c78f4aa9ad + +Co-authored-by: anupritaisno1 +--- + libc/Android.bp | 45 ++++++++++++++++++++++------ + libc/bionic/h_malloc_wrapper.cpp | 51 ++++++++++++++++++++++++++++++++ + libc/bionic/malloc_common.h | 25 +++++++++------- + 3 files changed, 102 insertions(+), 19 deletions(-) + create mode 100644 libc/bionic/h_malloc_wrapper.cpp + +diff --git a/libc/Android.bp b/libc/Android.bp +index 71d8ee556..13cefe94f 100644 +--- a/libc/Android.bp ++++ b/libc/Android.bp +@@ -76,6 +76,8 @@ libc_common_flags = [ + // ever touch 0, 1, or 2 bytes into a call to memset, which was never going + // to amortize.) + "-fno-builtin", ++ ++ "-DH_MALLOC_PREFIX", + ] + + // Define some common cflags +@@ -159,13 +161,30 @@ libc_scudo_product_variables = { + // ======================================================== + cc_defaults { + name: "libc_native_allocator_defaults", ++ whole_static_libs: ["libc_jemalloc_wrapper"], ++ multilib: { ++ lib32: { ++ cflags: ["-DUSE_SCUDO"], ++ whole_static_libs: ["libscudo"], ++ exclude_static_libs: [ ++ "libjemalloc5", ++ "libc_jemalloc_wrapper", ++ ], ++ }, ++ lib64: { ++ cflags: [ ++ "-DH_MALLOC_PREFIX", ++ "-DUSE_H_MALLOC", ++ "-DUSE_SCUDO", ++ ], ++ whole_static_libs: [ ++ "libhardened_malloc", ++ "libscudo", ++ ], ++ }, ++ }, + +- whole_static_libs: [ +- "libjemalloc5", +- "libc_jemalloc_wrapper", +- ], + header_libs: ["gwp_asan_headers"], +- product_variables: libc_scudo_product_variables, + } + + // Functions not implemented by jemalloc directly, or that need to +@@ -173,12 +192,20 @@ cc_defaults { + cc_library_static { + name: "libc_jemalloc_wrapper", + defaults: ["libc_defaults"], +- srcs: ["bionic/jemalloc_wrapper.cpp"], ++ multilib: { ++ lib32: { ++ // Used to pull in the jemalloc/hardened_malloc include directory so that if the ++ // library is removed, the include directory is also removed. ++ srcs: ["bionic/jemalloc_wrapper.cpp"], ++ static_libs: ["libjemalloc5"], ++ }, ++ lib64: { ++ srcs: ["bionic/h_malloc_wrapper.cpp"], ++ static_libs: ["libhardened_malloc"], ++ }, ++ }, + cflags: ["-fvisibility=hidden"], + +- // Used to pull in the jemalloc include directory so that if the +- // library is removed, the include directory is also removed. +- static_libs: ["libjemalloc5"], + } + + // ======================================================== +diff --git a/libc/bionic/h_malloc_wrapper.cpp b/libc/bionic/h_malloc_wrapper.cpp +new file mode 100644 +index 000000000..5fb0968c2 +--- /dev/null ++++ b/libc/bionic/h_malloc_wrapper.cpp +@@ -0,0 +1,51 @@ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "h_malloc.h" ++ ++__BEGIN_DECLS ++int h_malloc_info(int options, FILE* fp); ++__END_DECLS ++ ++int h_malloc_info(int options, FILE* fp) { ++ if (options != 0) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ fflush(fp); ++ int fd = fileno(fp); ++ MallocXmlElem root(fd, "malloc", "version=\"jemalloc-1\""); ++ ++ // Dump all of the large allocations in the arenas. ++ for (size_t i = 0; i < h_mallinfo_narenas(); i++) { ++ struct mallinfo mi = h_mallinfo_arena_info(i); ++ if (mi.hblkhd != 0) { ++ MallocXmlElem arena_elem(fd, "heap", "nr=\"%d\"", i); ++ { ++ MallocXmlElem(fd, "allocated-large").Contents("%zu", mi.ordblks); ++ MallocXmlElem(fd, "allocated-huge").Contents("%zu", mi.uordblks); ++ MallocXmlElem(fd, "allocated-bins").Contents("%zu", mi.fsmblks); ++ ++ size_t total = 0; ++ for (size_t j = 0; j < h_mallinfo_nbins(); j++) { ++ struct mallinfo mi = h_mallinfo_bin_info(i, j); ++ if (mi.ordblks != 0) { ++ MallocXmlElem bin_elem(fd, "bin", "nr=\"%d\"", j); ++ MallocXmlElem(fd, "allocated").Contents("%zu", mi.ordblks); ++ MallocXmlElem(fd, "nmalloc").Contents("%zu", mi.uordblks); ++ MallocXmlElem(fd, "ndalloc").Contents("%zu", mi.fordblks); ++ total += mi.ordblks; ++ } ++ } ++ MallocXmlElem(fd, "bins-total").Contents("%zu", total); ++ } ++ } ++ } ++ ++ return 0; ++} +diff --git a/libc/bionic/malloc_common.h b/libc/bionic/malloc_common.h +index 4afcc4a8d..8852c85a2 100644 +--- a/libc/bionic/malloc_common.h ++++ b/libc/bionic/malloc_common.h +@@ -55,21 +55,26 @@ __END_DECLS + + #else // __has_feature(hwaddress_sanitizer) + +-#if defined(USE_SCUDO) +- +-#include "scudo.h" +-#define Malloc(function) scudo_ ## function ++#ifdef __LP64__ ++#ifndef USE_H_MALLOC ++#error missing USE_H_MALLOC ++#endif + +-#elif defined(USE_SCUDO_SVELTE) ++#include "h_malloc.h" ++#define Malloc(function) h_ ## function ++__BEGIN_DECLS ++int h_malloc_info(int options, FILE* fp); ++__END_DECLS + ++#if defined(USE_SCUDO) + #include "scudo.h" +-#define Malloc(function) scudo_svelte_ ## function +- +-#else ++#endif + +-#include "jemalloc.h" +-#define Malloc(function) je_ ## function ++#define BOTH_H_MALLOC_AND_SCUDO + ++#else // 32-bit ++#include "scudo.h" ++#define Malloc(function) scudo_ ## function + #endif + + #endif diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-Workaround-1.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-Workaround-1.patch new file mode 100644 index 00000000..e314c767 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-Workaround-1.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Tue, 2 May 2023 16:47:49 +0300 +Subject: [PATCH] disable hardened_malloc for Pixel camera provider service + +--- + libc/bionic/libc_init_dynamic.cpp | 3 +++ + libc/bionic/malloc_common.cpp | 3 +++ + libc/include/stdlib.h | 1 + + 3 files changed, 7 insertions(+) + +diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp +index 804e586e2..7097a70b0 100644 +--- a/libc/bionic/libc_init_dynamic.cpp ++++ b/libc/bionic/libc_init_dynamic.cpp +@@ -84,6 +84,9 @@ static void init_prog_id(libc_globals* globals) { + + #define IS(prog) (!strcmp(exe_path, prog)) + ++ if (IS("/apex/com.google.pixel.camera.hal/bin/hw/android.hardware.camera.provider@2.7-service-google")) { ++ prog_id = PROG_PIXEL_CAMERA_PROVIDER_SERVICE; ++ } + #undef IS + + // libc_globals struct is write-protected +diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp +index 3d3e8ef61..9b7310347 100644 +--- a/libc/bionic/malloc_common.cpp ++++ b/libc/bionic/malloc_common.cpp +@@ -425,6 +425,9 @@ static const MallocDispatch* native_allocator_dispatch; + void InitNativeAllocatorDispatch(libc_globals* globals) { + bool hardened_impl = true; + switch (get_prog_id()) { ++ case PROG_PIXEL_CAMERA_PROVIDER_SERVICE: ++ hardened_impl = false; ++ break; + default: + hardened_impl = getenv("DISABLE_HARDENED_MALLOC") == nullptr; + } +diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h +index 5ce8f9103..cb8d3d3b2 100644 +--- a/libc/include/stdlib.h ++++ b/libc/include/stdlib.h +@@ -213,6 +213,7 @@ long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, i + int get_prog_id(); + #define is_prog(id) (get_prog_id() == id) + ++#define PROG_PIXEL_CAMERA_PROVIDER_SERVICE 1 + __END_DECLS + + #include diff --git a/Patches/LineageOS-21.0/android_bionic/0001-HM-Workaround-2.patch b/Patches/LineageOS-21.0/android_bionic/0001-HM-Workaround-2.patch new file mode 100644 index 00000000..d65d7cd3 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0001-HM-Workaround-2.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Tue, 12 Dec 2023 20:37:48 +0200 +Subject: [PATCH] disable hardened_malloc for surfaceflinger + +--- + libc/bionic/libc_init_dynamic.cpp | 3 +++ + libc/bionic/malloc_common.cpp | 1 + + libc/include/stdlib.h | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp +index 7097a70b0..f83d24ea7 100644 +--- a/libc/bionic/libc_init_dynamic.cpp ++++ b/libc/bionic/libc_init_dynamic.cpp +@@ -87,6 +87,9 @@ static void init_prog_id(libc_globals* globals) { + if (IS("/apex/com.google.pixel.camera.hal/bin/hw/android.hardware.camera.provider@2.7-service-google")) { + prog_id = PROG_PIXEL_CAMERA_PROVIDER_SERVICE; + } ++ else if (IS("/system/bin/surfaceflinger")) { ++ prog_id = PROG_SURFACEFLINGER; ++ } + #undef IS + + // libc_globals struct is write-protected +diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp +index 9b7310347..1ab4861af 100644 +--- a/libc/bionic/malloc_common.cpp ++++ b/libc/bionic/malloc_common.cpp +@@ -426,6 +426,7 @@ void InitNativeAllocatorDispatch(libc_globals* globals) { + bool hardened_impl = true; + switch (get_prog_id()) { + case PROG_PIXEL_CAMERA_PROVIDER_SERVICE: ++ case PROG_SURFACEFLINGER: + hardened_impl = false; + break; + default: +diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h +index cb8d3d3b2..5dd67daa4 100644 +--- a/libc/include/stdlib.h ++++ b/libc/include/stdlib.h +@@ -214,6 +214,7 @@ int get_prog_id(); + #define is_prog(id) (get_prog_id() == id) + + #define PROG_PIXEL_CAMERA_PROVIDER_SERVICE 1 ++#define PROG_SURFACEFLINGER 3 + __END_DECLS + + #include diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch new file mode 100644 index 00000000..146b75fc --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch @@ -0,0 +1,92 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: anupritaisno1 +Date: Wed, 13 Oct 2021 12:30:25 +0300 +Subject: [PATCH] add a real explicit_bzero implementation + +Clang, GCC and other compilers special-case standard C functions like +memset. Calls to memset will be optimized out. + +OpenBSD provides explicit_bzero to work around this but Android simply +defines it as memset so nothing prevents it from being optimized away. + +This implementation uses a memory read constraint via empty inline +assembly rather than something that may be broken via link-time +optimization in the future. + +Signed-off-by: anupritaisno1 +Change-Id: Ia021e30f86ee4b998d541fbf7262110f9d1d6fbf +Signed-off-by: anupritaisno1 +--- + libc/Android.bp | 1 + + libc/bionic/explicit_bzero.cpp | 7 +++++++ + libc/include/string.h | 2 ++ + libc/libc.map.txt | 1 + + libc/upstream-openbsd/android/include/openbsd-compat.h | 4 ---- + 5 files changed, 11 insertions(+), 4 deletions(-) + create mode 100644 libc/bionic/explicit_bzero.cpp + +diff --git a/libc/Android.bp b/libc/Android.bp +index 13cefe94f..9f8b689af 100644 +--- a/libc/Android.bp ++++ b/libc/Android.bp +@@ -1127,6 +1127,7 @@ cc_library_static { + "bionic/eventfd.cpp", + "bionic/exec.cpp", + "bionic/execinfo.cpp", ++ "bionic/explicit_bzero.cpp", + "bionic/faccessat.cpp", + "bionic/fchmod.cpp", + "bionic/fchmodat.cpp", +diff --git a/libc/bionic/explicit_bzero.cpp b/libc/bionic/explicit_bzero.cpp +new file mode 100644 +index 000000000..dd43f9c00 +--- /dev/null ++++ b/libc/bionic/explicit_bzero.cpp +@@ -0,0 +1,7 @@ ++#include ++ ++void* _Nonnull explicit_bzero(void* _Nonnull s, size_t n) { ++ void *ptr = memset(s, 0, n); ++ __asm__ __volatile__("" : : "r"(ptr) : "memory"); ++ return ptr; ++} +diff --git a/libc/include/string.h b/libc/include/string.h +index 47bdd7271..e601ea022 100644 +--- a/libc/include/string.h ++++ b/libc/include/string.h +@@ -64,6 +64,8 @@ void* _Nonnull memmove(void* _Nonnull __dst, const void* _Nonnull __src, size_t + */ + void* _Nonnull memset(void* _Nonnull __dst, int __ch, size_t __n); + ++void* _Nonnull explicit_bzero(void* _Nonnull s, size_t n); ++ + /** + * [memset_explicit(3)](http://man7.org/linux/man-pages/man3/memset_explicit.3.html) + * writes the bottom 8 bits of the given int to the next `n` bytes of `dst`, +diff --git a/libc/libc.map.txt b/libc/libc.map.txt +index 5d87cd8ef..dd2e6c6f7 100644 +--- a/libc/libc.map.txt ++++ b/libc/libc.map.txt +@@ -332,6 +332,7 @@ LIBC { + execvp; + execvpe; # introduced=21 + exit; ++ explicit_bzero; # introduced=33 + faccessat; + fallocate; # introduced=21 + fallocate64; # introduced=21 +diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h +index 8e6f87da8..26dc01863 100644 +--- a/libc/upstream-openbsd/android/include/openbsd-compat.h ++++ b/libc/upstream-openbsd/android/include/openbsd-compat.h +@@ -57,10 +57,6 @@ extern const char* __progname; + /* OpenBSD has this, but we can't really implement it correctly on Linux. */ + #define issetugid() 0 + +-#if !defined(ANDROID_HOST_MUSL) +-#define explicit_bzero(p, s) memset(p, 0, s) +-#endif +- + #if defined(ANDROID_HOST_MUSL) + #define __LIBC_HIDDEN__ __attribute__((visibility("hidden"))) + #endif diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch new file mode 100644 index 00000000..999f642f --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch @@ -0,0 +1,84 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 2 Dec 2015 23:37:28 -0500 +Subject: [PATCH] switch pthread_atfork handler allocation to mmap + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_atfork.cpp | 35 ++++++++++++++++++++++++++++------ + 1 file changed, 29 insertions(+), 6 deletions(-) + +diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp +index 0dcabdfb2..6306052ee 100644 +--- a/libc/bionic/pthread_atfork.cpp ++++ b/libc/bionic/pthread_atfork.cpp +@@ -29,6 +29,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include "platform/bionic/macros.h" + +@@ -43,6 +46,8 @@ struct atfork_t { + void* dso_handle; + }; + ++static atfork_t* pool; ++ + class atfork_list_t { + public: + constexpr atfork_list_t() : first_(nullptr), last_(nullptr) {} +@@ -101,7 +106,8 @@ class atfork_list_t { + last_ = entry->prev; + } + +- free(entry); ++ entry->next = pool; ++ pool = entry; + } + + atfork_t* first_; +@@ -154,18 +160,35 @@ void __bionic_atfork_run_parent() { + // __register_atfork is the name used by glibc + extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void), + void(*child)(void), void* dso) { +- atfork_t* entry = reinterpret_cast(malloc(sizeof(atfork_t))); +- if (entry == nullptr) { +- return ENOMEM; ++ pthread_mutex_lock(&g_atfork_list_mutex); ++ ++ if (!pool) { ++ size_t page_size = getpagesize(); ++ char* page = static_cast(mmap(NULL, page_size, PROT_READ|PROT_WRITE, ++ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)); ++ if (page == MAP_FAILED) { ++ pthread_mutex_unlock(&g_atfork_list_mutex); ++ return ENOMEM; ++ } ++ ++ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, page_size, ++ "atfork handlers"); ++ ++ for (char* it = page; it < page + page_size - sizeof(atfork_t); it += sizeof(atfork_t)) { ++ atfork_t* node = reinterpret_cast(it); ++ node->next = pool; ++ pool = node; ++ } + } + ++ atfork_t* entry = pool; ++ pool = entry->next; ++ + entry->prepare = prepare; + entry->parent = parent; + entry->child = child; + entry->dso_handle = dso; + +- pthread_mutex_lock(&g_atfork_list_mutex); +- + g_atfork_list.push_back(entry); + + pthread_mutex_unlock(&g_atfork_list_mutex); diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch new file mode 100644 index 00000000..b8635e8d --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch @@ -0,0 +1,95 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Thu, 3 Dec 2015 12:58:31 -0500 +Subject: [PATCH] add memory protection for pthread_atfork handlers + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_atfork.cpp | 34 ++++++++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp +index 6306052ee..d59f3ae54 100644 +--- a/libc/bionic/pthread_atfork.cpp ++++ b/libc/bionic/pthread_atfork.cpp +@@ -47,6 +47,7 @@ struct atfork_t { + }; + + static atfork_t* pool; ++static atfork_t* page_list; + + class atfork_list_t { + public: +@@ -160,13 +161,22 @@ void __bionic_atfork_run_parent() { + // __register_atfork is the name used by glibc + extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void), + void(*child)(void), void* dso) { ++ size_t page_size = getpagesize(); ++ + pthread_mutex_lock(&g_atfork_list_mutex); + ++ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) { ++ mprotect(page_it, page_size, PROT_READ|PROT_WRITE); ++ } ++ + if (!pool) { +- size_t page_size = getpagesize(); + char* page = static_cast(mmap(NULL, page_size, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)); + if (page == MAP_FAILED) { ++ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) { ++ mprotect(page_it, page_size, PROT_READ); ++ } ++ + pthread_mutex_unlock(&g_atfork_list_mutex); + return ENOMEM; + } +@@ -174,11 +184,15 @@ extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void), + prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, page_size, + "atfork handlers"); + +- for (char* it = page; it < page + page_size - sizeof(atfork_t); it += sizeof(atfork_t)) { ++ for (char* it = page + sizeof(atfork_t); it < page + page_size - sizeof(atfork_t); it += sizeof(atfork_t)) { + atfork_t* node = reinterpret_cast(it); + node->next = pool; + pool = node; + } ++ ++ atfork_t* page_node = reinterpret_cast(page); ++ page_node->next = page_list; ++ page_list = page_node; + } + + atfork_t* entry = pool; +@@ -191,6 +205,10 @@ extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void), + + g_atfork_list.push_back(entry); + ++ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) { ++ mprotect(page_it, page_size, PROT_READ); ++ } ++ + pthread_mutex_unlock(&g_atfork_list_mutex); + + return 0; +@@ -198,8 +216,20 @@ extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void), + + extern "C" __LIBC_HIDDEN__ void __unregister_atfork(void* dso) { + pthread_mutex_lock(&g_atfork_list_mutex); ++ ++ size_t page_size = getpagesize(); ++ ++ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) { ++ mprotect(page_it, page_size, PROT_READ|PROT_WRITE); ++ } ++ + g_atfork_list.remove_if([&](const atfork_t* entry) { + return entry->dso_handle == dso; + }); ++ ++ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) { ++ mprotect(page_it, page_size, PROT_READ); ++ } ++ + pthread_mutex_unlock(&g_atfork_list_mutex); + } diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch new file mode 100644 index 00000000..e1c1c7a9 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch @@ -0,0 +1,87 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 27 Jan 2016 18:02:15 -0500 +Subject: [PATCH] add XOR mangling mitigation for thread-local dtors + +memtag_stack struct member is required to be at its exact position by static_assert below. + +Signed-off-by: anupritaisno1 +--- + libc/bionic/__cxa_thread_atexit_impl.cpp | 8 +++++--- + libc/bionic/libc_init_common.cpp | 2 ++ + libc/private/bionic_globals.h | 1 + + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/libc/bionic/__cxa_thread_atexit_impl.cpp b/libc/bionic/__cxa_thread_atexit_impl.cpp +index 99077c101..74608513e 100644 +--- a/libc/bionic/__cxa_thread_atexit_impl.cpp ++++ b/libc/bionic/__cxa_thread_atexit_impl.cpp +@@ -13,15 +13,17 @@ + * See the License for the specific language governing permissions and + * limitations under the License. + */ ++#include + #include + + #include ++#include + + #include "pthread_internal.h" + + class thread_local_dtor { + public: +- void (*func) (void *); ++ uintptr_t func; + void *arg; + void *dso_handle; // unused... + thread_local_dtor* next; +@@ -35,7 +37,7 @@ __BIONIC_WEAK_FOR_NATIVE_BRIDGE + int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) { + thread_local_dtor* dtor = new thread_local_dtor(); + +- dtor->func = func; ++ dtor->func = __libc_globals->dtor_cookie ^ reinterpret_cast(func); + dtor->arg = arg; + dtor->dso_handle = dso_handle; + +@@ -54,7 +56,7 @@ extern "C" __LIBC_HIDDEN__ void __cxa_thread_finalize() { + thread_local_dtor* current = thread->thread_local_dtors; + thread->thread_local_dtors = current->next; + +- current->func(current->arg); ++ (reinterpret_cast(__libc_globals->dtor_cookie ^ current->func))(current->arg); + if (__loader_remove_thread_local_dtor != nullptr) { + __loader_remove_thread_local_dtor(current->dso_handle); + } +diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp +index 7ef79b61a..9c946b077 100644 +--- a/libc/bionic/libc_init_common.cpp ++++ b/libc/bionic/libc_init_common.cpp +@@ -46,6 +46,7 @@ + #include "heap_tagging.h" + #include "private/ScopedPthreadMutexLocker.h" + #include "private/WriteProtected.h" ++#include "private/bionic_arc4random.h" + #include "private/bionic_defs.h" + #include "private/bionic_globals.h" + #include "private/bionic_tls.h" +@@ -70,6 +71,7 @@ void __libc_init_globals() { + __libc_globals.mutate([](libc_globals* globals) { + __libc_init_vdso(globals); + __libc_init_setjmp_cookie(globals); ++ arc4random_buf(&globals->dtor_cookie, sizeof(globals->dtor_cookie)); + }); + } + +diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h +index 66f8d84b0..bd34e3a08 100644 +--- a/libc/private/bionic_globals.h ++++ b/libc/private/bionic_globals.h +@@ -50,6 +50,7 @@ struct libc_globals { + uintptr_t heap_pointer_tag; + _Atomic(bool) memtag_stack; + _Atomic(bool) decay_time_enabled; ++ long dtor_cookie; + + // In order to allow a complete switch between dispatch tables without + // the need for copying each function by function in the structure, diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch new file mode 100644 index 00000000..6cebd2ea --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Fri, 29 Jan 2016 20:20:09 -0500 +Subject: [PATCH] use a better pthread_attr junk filling pattern + +Guarantee that junk filled pointers will fault, at least on pure 64-bit. + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_attr.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp +index de4cc9e8d..7e74b8a80 100644 +--- a/libc/bionic/pthread_attr.cpp ++++ b/libc/bionic/pthread_attr.cpp +@@ -54,7 +54,7 @@ int pthread_attr_init(pthread_attr_t* attr) { + + __BIONIC_WEAK_FOR_NATIVE_BRIDGE + int pthread_attr_destroy(pthread_attr_t* attr) { +- memset(attr, 0x42, sizeof(pthread_attr_t)); ++ memset(attr, 0xdf, sizeof(pthread_attr_t)); + return 0; + } + diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch new file mode 100644 index 00000000..6c7645bb --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch @@ -0,0 +1,82 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Renlord +Date: Thu, 12 Sep 2019 14:51:51 +1000 +Subject: [PATCH] add guard page(s) between static_tls and stack + +--- + libc/bionic/pthread_create.cpp | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index 194db1821..88e57f973 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -212,9 +212,10 @@ int __init_thread(pthread_internal_t* thread) { + ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) { + const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout; + +- // Allocate in order: stack guard, stack, static TLS, guard page. ++ // Allocate in order: stack guard, stack, guard page, static TLS, guard page. + size_t mmap_size; + if (__builtin_add_overflow(stack_size, stack_guard_size, &mmap_size)) return {}; ++ if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, layout.size(), &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; + +@@ -223,8 +224,8 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + mmap_size = __BIONIC_ALIGN(mmap_size, page_size()); + if (mmap_size < unaligned_size) return {}; + +- // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out a +- // read+write area in the middle. ++ // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out ++ // read+write areas for the stack and static TLS + const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; + char* const space = static_cast(mmap(nullptr, mmap_size, PROT_NONE, flags, -1, 0)); + if (space == MAP_FAILED) { +@@ -233,7 +234,6 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + mmap_size); + return {}; + } +- const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; + int prot = PROT_READ | PROT_WRITE; + const char* prot_str = "R+W"; + #ifdef __aarch64__ +@@ -242,11 +242,22 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + prot_str = "R+W+MTE"; + } + #endif +- if (mprotect(space + stack_guard_size, writable_size, prot) != 0) { ++ if (mprotect(space + stack_guard_size, stack_size, prot) != 0) { ++ async_safe_format_log( ++ ANDROID_LOG_WARN, "libc", ++ "pthread_create failed: couldn't mprotect %s %zu-byte stack mapping region: %m", prot_str, ++ stack_size); ++ munmap(space, mmap_size); ++ return {}; ++ } ++ ++ char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ ++ if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log( + ANDROID_LOG_WARN, "libc", +- "pthread_create failed: couldn't mprotect %s %zu-byte thread mapping region: %m", prot_str, +- writable_size); ++ "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %m", ++ layout.size()); + munmap(space, mmap_size); + return {}; + } +@@ -256,9 +267,9 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + result.mmap_size = mmap_size; + result.mmap_base_unguarded = space + stack_guard_size; + result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; +- result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size(); ++ result.static_tls = static_tls_space; + result.stack_base = space; +- result.stack_top = result.static_tls; ++ result.stack_top = space + stack_guard_size + stack_size; + return result; + } + diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch new file mode 100644 index 00000000..a3eb9a5f --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Fri, 11 Oct 2019 05:52:49 +0300 +Subject: [PATCH] move pthread_internal_t behind guard page + +--- + libc/bionic/pthread_create.cpp | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index 88e57f973..f21e3a63f 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -212,10 +212,13 @@ int __init_thread(pthread_internal_t* thread) { + ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) { + const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout; + +- // Allocate in order: stack guard, stack, guard page, static TLS, guard page. ++ size_t thread_page_size = __BIONIC_ALIGN(sizeof(pthread_internal_t), PAGE_SIZE); ++ ++ // Allocate in order: stack guard, stack, guard page, pthread_internal_t, static TLS, guard page. + size_t mmap_size; + if (__builtin_add_overflow(stack_size, stack_guard_size, &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; ++ if (__builtin_add_overflow(mmap_size, thread_page_size, &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, layout.size(), &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; + +@@ -251,13 +254,14 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + return {}; + } + +- char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const thread = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const static_tls_space = thread + thread_page_size; + +- if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { ++ if (mprotect(thread, thread_page_size + layout.size(), PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log( + ANDROID_LOG_WARN, "libc", +- "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %m", +- layout.size()); ++ "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS and pthread_internal mapping region: %m", ++ thread_page_size + layout.size()); + munmap(space, mmap_size); + return {}; + } +@@ -299,13 +303,8 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi + stack_top = static_cast(attr->stack_base) + attr->stack_size; + } + +- // Carve out space from the stack for the thread's pthread_internal_t. This +- // memory isn't counted in pthread_attr_getstacksize. +- +- // To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary. +- stack_top = align_down(stack_top - sizeof(pthread_internal_t), 16); +- +- pthread_internal_t* thread = reinterpret_cast(stack_top); ++ pthread_internal_t* thread = reinterpret_cast( ++ mapping.static_tls - __BIONIC_ALIGN(sizeof(pthread_internal_t), PAGE_SIZE)); + if (!stack_clean) { + // If thread was not allocated by mmap(), it may not have been cleared to zero. + // So assume the worst and zero it. diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-16.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-16.patch new file mode 100644 index 00000000..4f495cca --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-16.patch @@ -0,0 +1,97 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Renlord +Date: Sun, 20 Oct 2019 00:17:11 +0300 +Subject: [PATCH] add secondary stack randomization + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_create.cpp | 30 ++++++++++++++++++++++++++---- + libc/include/sys/cdefs.h | 1 + + 2 files changed, 27 insertions(+), 4 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index f21e3a63f..035967d3c 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -29,6 +29,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -212,12 +213,24 @@ int __init_thread(pthread_internal_t* thread) { + ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) { + const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout; + ++ // round up if the given stack size is not in multiples of PAGE_SIZE ++ stack_size = __BIONIC_ALIGN(stack_size, PAGE_SIZE); + size_t thread_page_size = __BIONIC_ALIGN(sizeof(pthread_internal_t), PAGE_SIZE); + +- // Allocate in order: stack guard, stack, guard page, pthread_internal_t, static TLS, guard page. ++ // Place a randomly sized gap above the stack, up to 10% as large as the stack ++ // on 32-bit and 50% on 64-bit where virtual memory is plentiful. ++#if __LP64__ ++ size_t max_gap_size = stack_size / 2; ++#else ++ size_t max_gap_size = stack_size / 10; ++#endif ++ // Make sure random stack top guard size are multiples of PAGE_SIZE. ++ size_t gap_size = __BIONIC_ALIGN(arc4random_uniform(max_gap_size), PAGE_SIZE); ++ ++ // Allocate in order: stack guard, stack, (random) guard page(s), pthread_internal_t, static TLS, guard page. + size_t mmap_size; + if (__builtin_add_overflow(stack_size, stack_guard_size, &mmap_size)) return {}; +- if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; ++ if (__builtin_add_overflow(mmap_size, gap_size, &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, thread_page_size, &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, layout.size(), &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; +@@ -245,6 +258,9 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + prot_str = "R+W+MTE"; + } + #endif ++ // Stack is at the lower end of mapped space, stack guard region is at the lower end of stack. ++ // Make the usable portion of the stack between the guard region and random gap readable and ++ // writable. + if (mprotect(space + stack_guard_size, stack_size, prot) != 0) { + async_safe_format_log( + ANDROID_LOG_WARN, "libc", +@@ -253,8 +269,11 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + munmap(space, mmap_size); + return {}; + } ++ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, space, stack_guard_size, "stack guard"); ++ char* const stack_top_guard = space + stack_guard_size + stack_size; ++ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, stack_top_guard, gap_size, "stack top guard"); + +- char* const thread = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const thread = space + stack_guard_size + stack_size + gap_size; + char* const static_tls_space = thread + thread_page_size; + + if (mprotect(thread, thread_page_size + layout.size(), PROT_READ | PROT_WRITE) != 0) { +@@ -273,7 +292,10 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; + result.static_tls = static_tls_space; + result.stack_base = space; +- result.stack_top = space + stack_guard_size + stack_size; ++ // Choose a random base within the first page of the stack. Waste no more ++ // than the space originally wasted by pthread_internal_t for compatibility. ++ result.stack_top = space + stack_guard_size + stack_size - arc4random_uniform(sizeof(pthread_internal_t)); ++ result.stack_top = reinterpret_cast(__BIONIC_ALIGN_DOWN(reinterpret_cast(result.stack_top), 16)); + return result; + } + +diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h +index a8fb6240a..dd95423c4 100644 +--- a/libc/include/sys/cdefs.h ++++ b/libc/include/sys/cdefs.h +@@ -61,6 +61,7 @@ + #endif + + #define __BIONIC_ALIGN(__value, __alignment) (((__value) + (__alignment)-1) & ~((__alignment)-1)) ++#define __BIONIC_ALIGN_DOWN(value, alignment) ((value) & ~((alignment) - 1)) + + /* + * The nullness constraints of this parameter or return value are diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch new file mode 100644 index 00000000..5cb8b39d --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch @@ -0,0 +1,76 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sun, 8 Feb 2015 01:18:54 -0500 +Subject: [PATCH] replace brk and sbrk with stubs + +Pretend that there is never room to grow the heap in order to prevent +usage of these unsafe legacy functions. There are likely no users of +these in practice as it is inherently broken to use them outside of +malloc. + +Signed-off-by: anupritaisno1 +--- + libc/bionic/brk.cpp | 48 ++++++++------------------------------------- + 1 file changed, 8 insertions(+), 40 deletions(-) + +diff --git a/libc/bionic/brk.cpp b/libc/bionic/brk.cpp +index 566c33a7a..ef9305513 100644 +--- a/libc/bionic/brk.cpp ++++ b/libc/bionic/brk.cpp +@@ -29,48 +29,16 @@ + #include + #include + +-#if defined(__LP64__) +-static void* __bionic_brk; +-#else +-void* __bionic_brk; // Accidentally exported by the NDK. ++#if !defined(__LP64__) ++void* __bionic_brk = reinterpret_cast(-1); // Accidentally exported by the NDK. + #endif + +-extern "C" void* __brk(void* __addr); +- +-int brk(void* end_data) { +- __bionic_brk = __brk(end_data); +- if (__bionic_brk < end_data) { +- errno = ENOMEM; +- return -1; +- } +- return 0; ++int brk(void*) { ++ errno = ENOMEM; ++ return -1; + } + +-void* sbrk(ptrdiff_t increment) { +- // Initialize __bionic_brk if necessary. +- if (__bionic_brk == nullptr) { +- __bionic_brk = __brk(nullptr); +- } +- +- // Don't ask the kernel if we already know the answer. +- if (increment == 0) { +- return __bionic_brk; +- } +- +- // Avoid overflow. +- uintptr_t old_brk = reinterpret_cast(__bionic_brk); +- if ((increment > 0 && static_cast(increment) > (UINTPTR_MAX - old_brk)) || +- (increment < 0 && static_cast(-increment) > old_brk)) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- void* desired_brk = reinterpret_cast(old_brk + increment); +- __bionic_brk = __brk(desired_brk); +- if (__bionic_brk < desired_brk) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- return reinterpret_cast(old_brk); ++void* sbrk(ptrdiff_t) { ++ errno = ENOMEM; ++ return reinterpret_cast(-1); + } diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch new file mode 100644 index 00000000..303c4566 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Mon, 4 Mar 2019 04:26:04 -0500 +Subject: [PATCH] use blocking getrandom and avoid urandom fallback + +Signed-off-by: anupritaisno1 +--- + libc/bionic/getentropy.cpp | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/libc/bionic/getentropy.cpp b/libc/bionic/getentropy.cpp +index 9c93e713b..c9438ad2b 100644 +--- a/libc/bionic/getentropy.cpp ++++ b/libc/bionic/getentropy.cpp +@@ -33,22 +33,6 @@ + + #include "private/ScopedFd.h" + +-static int getentropy_urandom(void* buffer, size_t buffer_size, int saved_errno) { +- ScopedFd fd(TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_NOFOLLOW | O_CLOEXEC, 0))); +- if (fd.get() == -1) return -1; +- +- size_t collected = 0; +- while (collected < buffer_size) { +- ssize_t count = TEMP_FAILURE_RETRY(read(fd.get(), static_cast(buffer) + collected, +- buffer_size - collected)); +- if (count == -1) return -1; +- collected += count; +- } +- +- errno = saved_errno; +- return 0; +-} +- + int getentropy(void* buffer, size_t buffer_size) { + if (buffer_size > 256) { + errno = EIO; +@@ -59,16 +43,10 @@ int getentropy(void* buffer, size_t buffer_size) { + + size_t collected = 0; + while (collected < buffer_size) { +- long count = TEMP_FAILURE_RETRY(getrandom(static_cast(buffer) + collected, +- buffer_size - collected, GRND_NONBLOCK)); ++ long count = TEMP_FAILURE_RETRY( ++ getrandom(static_cast(buffer) + collected, buffer_size - collected, 0)); + if (count == -1) { +- // EAGAIN: there isn't enough entropy right now. +- // ENOSYS/EINVAL: getrandom(2) or GRND_NONBLOCK isn't supported. +- // EFAULT: `buffer` is invalid. +- // Try /dev/urandom regardless because it can't hurt, +- // and we don't need to optimize the EFAULT case. +- // See http://b/33059407 and http://b/67015565. +- return getentropy_urandom(buffer, buffer_size, saved_errno); ++ return -1; + } + collected += count; + } diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch new file mode 100644 index 00000000..f3959e32 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Mon, 19 Sep 2016 07:57:43 -0400 +Subject: [PATCH] fix undefined out-of-bounds accesses in sched.h + +Signed-off-by: anupritaisno1 +--- + libc/include/sched.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libc/include/sched.h b/libc/include/sched.h +index b1f18421b..20e25662f 100644 +--- a/libc/include/sched.h ++++ b/libc/include/sched.h +@@ -215,7 +215,10 @@ int sched_getcpu(void); + * statically-sized CPU set. See `CPU_ALLOC` for dynamically-sized CPU sets. + */ + typedef struct { +- __CPU_BITTYPE __bits[ CPU_SETSIZE / __CPU_BITS ]; ++ union { ++ __CPU_BITTYPE __bits_minimum[ CPU_SETSIZE / __CPU_BITS ]; ++ __CPU_BITTYPE __bits[0]; ++ }; + } cpu_set_t; + + /** diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch new file mode 100644 index 00000000..99b01441 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 16 Jul 2016 23:55:16 -0400 +Subject: [PATCH] replace VLA formatting with dprintf-like function + +Signed-off-by: anupritaisno1 +--- + libc/bionic/bionic_systrace.cpp | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp +index 227cb84c3..25ae76a89 100644 +--- a/libc/bionic/bionic_systrace.cpp ++++ b/libc/bionic/bionic_systrace.cpp +@@ -29,8 +29,6 @@ + #include + #include // For ATRACE_TAG_BIONIC. + +-#define WRITE_OFFSET 32 +- + static Lock g_lock; + static CachedProperty g_debug_atrace_tags_enableflags("debug.atrace.tags.enableflags"); + static uint64_t g_tags; +@@ -67,15 +65,9 @@ static void trace_begin_internal(const char* message) { + return; + } + +- // If bionic tracing has been enabled, then write the message to the +- // kernel trace_marker. +- int length = strlen(message); +- char buf[length + WRITE_OFFSET]; +- size_t len = async_safe_format_buffer(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message); +- + // Tracing may stop just after checking property and before writing the message. + // So the write is acceptable to fail. See b/20666100. +- TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len)); ++ async_safe_format_fd(trace_marker_fd, "B|%d|%s", getpid(), message); + } + + void bionic_trace_begin(const char* message) { diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch new file mode 100644 index 00000000..498fcdb8 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Fri, 17 Jul 2015 21:32:05 -0400 +Subject: [PATCH] increase default pthread stack to 8MiB on 64-bit + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_internal.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h +index 3b9e6a481..c4d124e8e 100644 +--- a/libc/bionic/pthread_internal.h ++++ b/libc/bionic/pthread_internal.h +@@ -256,7 +256,11 @@ __LIBC_HIDDEN__ void pthread_key_clean_all(void); + // stack overflows, we subtracted the same amount we were using there + // from the default thread stack size. This should keep memory usage + // roughly constant. ++#ifdef __LP64__ ++#define PTHREAD_STACK_SIZE_DEFAULT ((8 * 1024 * 1024) - SIGNAL_STACK_SIZE_WITHOUT_GUARD) ++#else + #define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGNAL_STACK_SIZE_WITHOUT_GUARD) ++#endif + + // Leave room for a guard page in the internally created signal stacks. + #define SIGNAL_STACK_SIZE (SIGNAL_STACK_SIZE_WITHOUT_GUARD + PTHREAD_GUARD_SIZE) diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch new file mode 100644 index 00000000..4de1f01e --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 1 Oct 2016 05:11:44 -0400 +Subject: [PATCH] make __stack_chk_guard read-only at runtime + +Signed-off-by: anupritaisno1 +--- + libc/bionic/__libc_init_main_thread.cpp | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp +index 1b539f274..a6ddc64d5 100644 +--- a/libc/bionic/__libc_init_main_thread.cpp ++++ b/libc/bionic/__libc_init_main_thread.cpp +@@ -28,6 +28,9 @@ + + #include "libc_init_common.h" + ++#include ++#include ++ + #include + + #include "private/KernelArgumentBlock.h" +@@ -35,14 +38,14 @@ + #include "private/bionic_defs.h" + #include "private/bionic_elf_tls.h" + #include "private/bionic_globals.h" +-#include "private/bionic_ssp.h" + #include "pthread_internal.h" + + extern "C" pid_t __getpid(); + extern "C" int __set_tid_address(int* tid_address); + + // Declared in "private/bionic_ssp.h". +-uintptr_t __stack_chk_guard = 0; ++__attribute__((aligned(PAGE_SIZE))) ++uintptr_t __stack_chk_guard[PAGE_SIZE / sizeof(uintptr_t)] = {0}; + + static pthread_internal_t main_thread; + +@@ -107,10 +110,16 @@ void __init_tcb_dtv(bionic_tcb* tcb) { + // Note in particular that it is not possible to return from any existing + // stack frame with stack protector enabled after this function is called. + extern "C" void android_reset_stack_guards() { ++ if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ|PROT_WRITE) == -1) { ++ async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno)); ++ } + // The TLS stack guard is set from the global, so ensure that we've initialized the global + // before we initialize the TLS. Dynamic executables will initialize their copy of the global + // stack protector from the one in the main thread's TLS. +- __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); ++ __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0])); ++ if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ) == -1) { ++ async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno)); ++ } + __init_tcb_stack_guard(__get_bionic_tcb()); + } + diff --git a/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch new file mode 100644 index 00000000..6bc20f8a --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sun, 12 Mar 2017 17:49:13 -0400 +Subject: [PATCH] on 64-bit, zero the leading stack canary byte + +This reduces entropy of the canary from 64-bit to 56-bit in exchange for +mitigating non-terminated C string overflows. + +Signed-off-by: anupritaisno1 +--- + libc/bionic/__libc_init_main_thread.cpp | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp +index a6ddc64d5..c03a8b79d 100644 +--- a/libc/bionic/__libc_init_main_thread.cpp ++++ b/libc/bionic/__libc_init_main_thread.cpp +@@ -49,6 +49,12 @@ uintptr_t __stack_chk_guard[PAGE_SIZE / sizeof(uintptr_t)] = {0}; + + static pthread_internal_t main_thread; + ++#if __LP64__ ++static const uintptr_t canary_mask = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? ++ 0xffffffffffffff00UL : ++ 0x00ffffffffffffffUL; ++#endif ++ + // Setup for the main thread. For dynamic executables, this is called by the + // linker _before_ libc is mapped in memory. This means that all writes to + // globals from this function will apply to linker-private copies and will not +@@ -117,6 +123,10 @@ extern "C" void android_reset_stack_guards() { + // before we initialize the TLS. Dynamic executables will initialize their copy of the global + // stack protector from the one in the main thread's TLS. + __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0])); ++#if __LP64__ ++ // Sacrifice 8 bits of entropy on 64-bit to mitigate non-terminated C string overflows ++ __stack_chk_guard[0] &= canary_mask; ++#endif + if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ) == -1) { + async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno)); + } diff --git a/Patches/LineageOS-21.0/android_bionic/0003-Hosts_Cache.patch b/Patches/LineageOS-21.0/android_bionic/0003-Hosts_Cache.patch new file mode 100644 index 00000000..85a4602d --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0003-Hosts_Cache.patch @@ -0,0 +1,639 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tom Marshall +Date: Fri, 17 Jun 2016 16:38:12 -0700 +Subject: [PATCH] bionic: Sort and cache hosts file data for fast lookup + +The hosts file is normally searched linearly. This is very slow when +the file is large. To mitigate this, read the hosts file and sort the +entries in an in-memory cache. When an address is requested via +gethostbyname or getaddrinfo, binary search the cache. + +In case where the cache is not available, return a suitable error code +and fall back to the existing lookup code. + +This has been written to behave as much like the existing lookup code as +possible. But note bionic and glibc differ in behavior for some corner +cases. Choose the most standard compliant behavior for these where +possible. Otherwise choose the behavior that seems most reasonable. + +RM-290 + +Change-Id: I3b322883cbc48b0d76a0ce9d149b59faaac1dc58 +(cherry picked from commit ed4c3a6bd449a4ed70645071a440ae146f194116) +--- + libc/dns/net/getaddrinfo.c | 10 + + libc/dns/net/hosts_cache.c | 520 +++++++++++++++++++++++++++++++++++++ + libc/dns/net/hosts_cache.h | 23 ++ + libc/dns/net/sethostent.c | 7 + + 4 files changed, 560 insertions(+) + create mode 100644 libc/dns/net/hosts_cache.c + create mode 100644 libc/dns/net/hosts_cache.h + +diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c +index d0c11d2b0..cc94b21e2 100644 +--- a/libc/dns/net/getaddrinfo.c ++++ b/libc/dns/net/getaddrinfo.c +@@ -109,6 +109,8 @@ + #include "nsswitch.h" + #include "private/bionic_defs.h" + ++#include "hosts_cache.h" ++ + typedef union sockaddr_union { + struct sockaddr generic; + struct sockaddr_in in; +@@ -2125,6 +2127,14 @@ _files_getaddrinfo(void *rv, void *cb_data, va_list ap) + name = va_arg(ap, char *); + pai = va_arg(ap, struct addrinfo *); + ++ memset(&sentinel, 0, sizeof(sentinel)); ++ cur = &sentinel; ++ int gai_error = hc_getaddrinfo(name, NULL, pai, &cur); ++ if (gai_error != EAI_SYSTEM) { ++ *((struct addrinfo **)rv) = sentinel.ai_next; ++ return (gai_error == 0 ? NS_SUCCESS : NS_NOTFOUND); ++ } ++ + // fprintf(stderr, "_files_getaddrinfo() name = '%s'\n", name); + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; +diff --git a/libc/dns/net/hosts_cache.c b/libc/dns/net/hosts_cache.c +new file mode 100644 +index 000000000..52d29e032 +--- /dev/null ++++ b/libc/dns/net/hosts_cache.c +@@ -0,0 +1,520 @@ ++/* ++ * Copyright (C) 2016 The CyanogenMod 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "hostent.h" ++#include "resolv_private.h" ++ ++#define MAX_ADDRLEN (INET6_ADDRSTRLEN - (1 + 5)) ++#define MAX_HOSTLEN MAXHOSTNAMELEN ++ ++#define ESTIMATED_LINELEN 32 ++#define HCFILE_ALLOC_SIZE 256 ++ ++/* ++ * Host cache entry for hcfile.c_data. ++ * Offsets are into hcfile.h_data. ++ * Strings are *not* terminated by NULL, but by whitespace (isspace) or '#'. ++ * Use hstr* functions with these. ++ */ ++struct hcent ++{ ++ uint32_t addr; ++ uint32_t name; ++}; ++ ++/* ++ * Overall host cache file state. ++ */ ++struct hcfile ++{ ++ int h_fd; ++ struct stat h_st; ++ char *h_data; ++ ++ uint32_t c_alloc; ++ uint32_t c_len; ++ struct hcent *c_data; ++}; ++static struct hcfile hcfile; ++static pthread_mutex_t hclock = PTHREAD_MUTEX_INITIALIZER; ++ ++static size_t hstrlen(const char *s) ++{ ++ const char *p = s; ++ while (*p && *p != '#' && !isspace(*p)) ++ ++p; ++ return p - s; ++} ++ ++static int hstrcmp(const char *a, const char *b) ++{ ++ size_t alen = hstrlen(a); ++ size_t blen = hstrlen(b); ++ int res = strncmp(a, b, MIN(alen, blen)); ++ if (res == 0) ++ res = alen - blen; ++ return res; ++} ++ ++static char *hstrcpy(char *dest, const char *src) ++{ ++ size_t len = hstrlen(src); ++ memcpy(dest, src, len); ++ dest[len] = '\0'; ++ return dest; ++} ++ ++static char *hstrdup(const char *s) ++{ ++ size_t len = hstrlen(s); ++ char *dest = (char *)malloc(len + 1); ++ if (!dest) ++ return NULL; ++ memcpy(dest, s, len); ++ dest[len] = '\0'; ++ return dest; ++} ++ ++static int cmp_hcent_name(const void *a, const void *b) ++{ ++ struct hcent *ea = (struct hcent *)a; ++ const char *na = hcfile.h_data + ea->name; ++ struct hcent *eb = (struct hcent *)b; ++ const char *nb = hcfile.h_data + eb->name; ++ ++ return hstrcmp(na, nb); ++} ++ ++static struct hcent *_hcfindname(const char *name) ++{ ++ size_t first, last, mid; ++ struct hcent *cur = NULL; ++ int cmp; ++ ++ if (hcfile.c_len == 0) ++ return NULL; ++ ++ first = 0; ++ last = hcfile.c_len - 1; ++ mid = (first + last) / 2; ++ while (first <= last) { ++ cur = hcfile.c_data + mid; ++ cmp = hstrcmp(hcfile.h_data + cur->name, name); ++ if (cmp == 0) ++ goto found; ++ if (cmp < 0) ++ first = mid + 1; ++ else { ++ if (mid > 0) ++ last = mid - 1; ++ else ++ return NULL; ++ } ++ mid = (first + last) / 2; ++ } ++ return NULL; ++ ++found: ++ while (cur > hcfile.c_data) { ++ struct hcent *prev = cur - 1; ++ cmp = cmp_hcent_name(cur, prev); ++ if (cmp) ++ break; ++ cur = prev; ++ } ++ ++ return cur; ++} ++ ++/* ++ * Find next name on line, if any. ++ * ++ * Assumes that line is terminated by LF. ++ */ ++static const char *_hcnextname(const char *name) ++{ ++ while (!isspace(*name)) { ++ if (*name == '#') ++ return NULL; ++ ++name; ++ } ++ while (isspace(*name)) { ++ if (*name == '\n') ++ return NULL; ++ ++name; ++ } ++ if (*name == '#') ++ return NULL; ++ return name; ++} ++ ++static int _hcfilemmap(void) ++{ ++ struct stat st; ++ int h_fd; ++ char *h_addr; ++ const char *p, *pend; ++ uint32_t c_alloc; ++ ++ h_fd = open(_PATH_HOSTS, O_RDONLY); ++ if (h_fd < 0) ++ return -1; ++ if (flock(h_fd, LOCK_EX) != 0) { ++ close(h_fd); ++ return -1; ++ } ++ ++ if (hcfile.h_data) { ++ memset(&st, 0, sizeof(st)); ++ if (fstat(h_fd, &st) == 0) { ++ if (st.st_size == hcfile.h_st.st_size && ++ st.st_mtime == hcfile.h_st.st_mtime) { ++ flock(h_fd, LOCK_UN); ++ close(h_fd); ++ return 0; ++ } ++ } ++ free(hcfile.c_data); ++ munmap(hcfile.h_data, hcfile.h_st.st_size); ++ close(hcfile.h_fd); ++ memset(&hcfile, 0, sizeof(struct hcfile)); ++ } ++ ++ if (fstat(h_fd, &st) != 0) { ++ flock(h_fd, LOCK_UN); ++ close(h_fd); ++ return -1; ++ } ++ h_addr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, h_fd, 0); ++ if (h_addr == MAP_FAILED) { ++ flock(h_fd, LOCK_UN); ++ close(h_fd); ++ return -1; ++ } ++ ++ hcfile.h_fd = h_fd; ++ hcfile.h_st = st; ++ hcfile.h_data = h_addr; ++ ++ c_alloc = 0; ++ /* ++ * Do an initial allocation if the file is "large". Estimate ++ * 32 bytes per line and define "large" as more than half of ++ * the alloc growth size (256 entries). ++ */ ++ if (st.st_size >= ESTIMATED_LINELEN * HCFILE_ALLOC_SIZE / 2) { ++ c_alloc = st.st_size / ESTIMATED_LINELEN; ++ hcfile.c_data = malloc(c_alloc * sizeof(struct hcent)); ++ if (!hcfile.c_data) { ++ goto oom; ++ } ++ } ++ ++ p = (const char *)h_addr; ++ pend = p + st.st_size; ++ while (p < pend) { ++ const char *eol, *addr, *name; ++ size_t len; ++ addr = p; ++ eol = memchr(p, '\n', pend - p); ++ if (!eol) ++ break; ++ p = eol + 1; ++ if (*addr == '#' || *addr == '\n') ++ continue; ++ len = hstrlen(addr); ++ if (len > MAX_ADDRLEN) ++ continue; ++ name = addr + len; ++ while (name < eol && isspace(*name)) ++ ++name; ++ while (name < eol) { ++ len = hstrlen(name); ++ if (len == 0) ++ break; ++ if (len < MAX_HOSTLEN) { ++ struct hcent *ent; ++ if (c_alloc <= hcfile.c_len) { ++ struct hcent *c_data; ++ c_alloc += HCFILE_ALLOC_SIZE; ++ c_data = realloc(hcfile.c_data, c_alloc * sizeof(struct hcent)); ++ if (!c_data) { ++ goto oom; ++ } ++ hcfile.c_data = c_data; ++ } ++ ent = hcfile.c_data + hcfile.c_len; ++ ent->addr = addr - h_addr; ++ ent->name = name - h_addr; ++ ++hcfile.c_len; ++ } ++ name += len; ++ while (name < eol && isspace(*name)) ++ ++name; ++ } ++ } ++ ++ qsort(hcfile.c_data, hcfile.c_len, ++ sizeof(struct hcent), cmp_hcent_name); ++ ++ flock(h_fd, LOCK_UN); ++ ++ return 0; ++ ++oom: ++ free(hcfile.c_data); ++ munmap(hcfile.h_data, hcfile.h_st.st_size); ++ flock(hcfile.h_fd, LOCK_UN); ++ close(hcfile.h_fd); ++ memset(&hcfile, 0, sizeof(struct hcfile)); ++ return -1; ++} ++ ++/* ++ * Caching version of getaddrinfo. ++ * ++ * If we find the requested host name in the cache, use getaddrinfo to ++ * populate the result for each address we find. ++ * ++ * Note glibc and bionic differ in the handling of ai_canonname. POSIX ++ * says that ai_canonname is only populated in the first result entry. ++ * glibc does this. bionic populates ai_canonname in all result entries. ++ * We choose the POSIX/glibc way here. ++ */ ++int hc_getaddrinfo(const char *host, const char *service, ++ const struct addrinfo *hints, ++ struct addrinfo **result) ++{ ++ int ret = 0; ++ struct hcent *ent, *cur; ++ struct addrinfo *ai; ++ struct addrinfo rhints; ++ struct addrinfo *last; ++ int canonname = 0; ++ int cmp; ++ ++ if (getenv("ANDROID_HOSTS_CACHE_DISABLE") != NULL) ++ return EAI_SYSTEM; ++ ++ /* Avoid needless work and recursion */ ++ if (hints && (hints->ai_flags & AI_NUMERICHOST)) ++ return EAI_SYSTEM; ++ if (!host) ++ return EAI_SYSTEM; ++ ++ pthread_mutex_lock(&hclock); ++ ++ if (_hcfilemmap() != 0) { ++ ret = EAI_SYSTEM; ++ goto out; ++ } ++ ent = _hcfindname(host); ++ if (!ent) { ++ ret = EAI_NONAME; ++ goto out; ++ } ++ ++ if (hints) { ++ canonname = (hints->ai_flags & AI_CANONNAME); ++ memcpy(&rhints, hints, sizeof(rhints)); ++ rhints.ai_flags &= ~AI_CANONNAME; ++ } ++ else { ++ memset(&rhints, 0, sizeof(rhints)); ++ } ++ rhints.ai_flags |= AI_NUMERICHOST; ++ ++ last = NULL; ++ cur = ent; ++ do { ++ char addrstr[MAX_ADDRLEN]; ++ struct addrinfo *res; ++ ++ hstrcpy(addrstr, hcfile.h_data + cur->addr); ++ ++ if (getaddrinfo(addrstr, service, &rhints, &res) == 0) { ++ if (!last) ++ (*result)->ai_next = res; ++ else ++ last->ai_next = res; ++ last = res; ++ while (last->ai_next) ++ last = last->ai_next; ++ } ++ ++ if(cur + 1 >= hcfile.c_data + hcfile.c_len) ++ break; ++ cmp = cmp_hcent_name(cur, cur + 1); ++ cur = cur + 1; ++ } ++ while (!cmp); ++ ++ if (last == NULL) { ++ /* This check is equivalent to (*result)->ai_next == NULL */ ++ ret = EAI_NODATA; ++ goto out; ++ } ++ ++ if (canonname) { ++ ai = (*result)->ai_next; ++ free(ai->ai_canonname); ++ ai->ai_canonname = hstrdup(hcfile.h_data + ent->name); ++ } ++ ++out: ++ pthread_mutex_unlock(&hclock); ++ return ret; ++} ++ ++/* ++ * Caching version of gethtbyname. ++ * ++ * Note glibc and bionic differ in the handling of aliases. glibc returns ++ * all aliases for all entries, regardless of whether they match h_addrtype. ++ * bionic returns only the aliases for the first hosts entry. We return all ++ * aliases for all IPv4 entries. ++ * ++ * Additionally, if an alias is IPv6 and the primary name for an alias also ++ * has an IPv4 entry, glibc will return the IPv4 address(es), but bionic ++ * will not. Neither do we. ++ */ ++int hc_gethtbyname(const char *host, int af, struct getnamaddr *info) ++{ ++ int ret = NETDB_SUCCESS; ++ struct hcent *ent, *cur; ++ int cmp; ++ size_t addrlen; ++ unsigned int naliases = 0; ++ char *aliases[MAXALIASES]; ++ unsigned int naddrs = 0; ++ char *addr_ptrs[MAXADDRS]; ++ unsigned int n; ++ ++ if (getenv("ANDROID_HOSTS_CACHE_DISABLE") != NULL) ++ return NETDB_INTERNAL; ++ ++ switch (af) { ++ case AF_INET: addrlen = NS_INADDRSZ; break; ++ case AF_INET6: addrlen = NS_IN6ADDRSZ; break; ++ default: ++ return NETDB_INTERNAL; ++ } ++ ++ pthread_mutex_lock(&hclock); ++ ++ if (_hcfilemmap() != 0) { ++ ret = NETDB_INTERNAL; ++ goto out; ++ } ++ ++ ent = _hcfindname(host); ++ if (!ent) { ++ ret = HOST_NOT_FOUND; ++ goto out; ++ } ++ ++ cur = ent; ++ do { ++ char addr[16]; ++ char addrstr[MAX_ADDRLEN]; ++ char namestr[MAX_HOSTLEN]; ++ const char *name; ++ ++ hstrcpy(addrstr, hcfile.h_data + cur->addr); ++ if (inet_pton(af, addrstr, &addr) == 1) { ++ char *aligned; ++ /* First match is considered the official hostname */ ++ if (naddrs == 0) { ++ hstrcpy(namestr, hcfile.h_data + cur->name); ++ HENT_SCOPY(info->hp->h_name, namestr, info->buf, info->buflen); ++ } ++ for (name = hcfile.h_data + cur->name; name; name = _hcnextname(name)) { ++ if (!hstrcmp(name, host)) ++ continue; ++ hstrcpy(namestr, name); ++ HENT_SCOPY(aliases[naliases], namestr, info->buf, info->buflen); ++ ++naliases; ++ if (naliases >= MAXALIASES) ++ goto nospc; ++ } ++ aligned = (char *)ALIGN(info->buf); ++ if (info->buf != aligned) { ++ if ((ptrdiff_t)info->buflen < (aligned - info->buf)) ++ goto nospc; ++ info->buflen -= (aligned - info->buf); ++ info->buf = aligned; ++ } ++ HENT_COPY(addr_ptrs[naddrs], addr, addrlen, info->buf, info->buflen); ++ ++naddrs; ++ if (naddrs >= MAXADDRS) ++ goto nospc; ++ } ++ ++ if(cur + 1 >= hcfile.c_data + hcfile.c_len) ++ break; ++ cmp = cmp_hcent_name(cur, cur + 1); ++ cur = cur + 1; ++ } ++ while (!cmp); ++ ++ if (naddrs == 0) { ++ ret = HOST_NOT_FOUND; ++ goto out; ++ } ++ ++ addr_ptrs[naddrs++] = NULL; ++ aliases[naliases++] = NULL; ++ ++ /* hp->h_name already populated */ ++ HENT_ARRAY(info->hp->h_aliases, naliases, info->buf, info->buflen); ++ for (n = 0; n < naliases; ++n) { ++ info->hp->h_aliases[n] = aliases[n]; ++ } ++ info->hp->h_addrtype = af; ++ info->hp->h_length = addrlen; ++ HENT_ARRAY(info->hp->h_addr_list, naddrs, info->buf, info->buflen); ++ for (n = 0; n < naddrs; ++n) { ++ info->hp->h_addr_list[n] = addr_ptrs[n]; ++ } ++ ++out: ++ pthread_mutex_unlock(&hclock); ++ *info->he = ret; ++ return ret; ++ ++nospc: ++ ret = NETDB_INTERNAL; ++ goto out; ++} +diff --git a/libc/dns/net/hosts_cache.h b/libc/dns/net/hosts_cache.h +new file mode 100644 +index 000000000..fa5488f51 +--- /dev/null ++++ b/libc/dns/net/hosts_cache.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2016 The CyanogenMod 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. ++ */ ++ ++struct getnamaddr; ++ ++int hc_getaddrinfo(const char *host, const char *service, ++ const struct addrinfo *hints, ++ struct addrinfo **result); ++ ++int hc_gethtbyname(const char *host, int af, struct getnamaddr *info); +diff --git a/libc/dns/net/sethostent.c b/libc/dns/net/sethostent.c +index 5c4bdb5ab..5e4e174fa 100644 +--- a/libc/dns/net/sethostent.c ++++ b/libc/dns/net/sethostent.c +@@ -55,6 +55,8 @@ __RCSID("$NetBSD: sethostent.c,v 1.20 2014/03/17 13:24:23 christos Exp $"); + #include "hostent.h" + #include "resolv_private.h" + ++#include "hosts_cache.h" ++ + #ifndef _REENTRANT + void res_close(void); + #endif +@@ -109,6 +111,11 @@ _hf_gethtbyname(void *rv, void *cb_data, va_list ap) + /* NOSTRICT skip string len */(void)va_arg(ap, int); + af = va_arg(ap, int); + ++ int rc = hc_gethtbyname(name, af, info); ++ if (rc != NETDB_INTERNAL) { ++ return (rc == NETDB_SUCCESS ? NS_SUCCESS : NS_NOTFOUND); ++ } ++ + #if 0 + { + res_state res = __res_get_state(); diff --git a/Patches/LineageOS-21.0/android_bionic/0003-Hosts_Wildcards.patch b/Patches/LineageOS-21.0/android_bionic/0003-Hosts_Wildcards.patch new file mode 100644 index 00000000..abadbc86 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0003-Hosts_Wildcards.patch @@ -0,0 +1,69 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tom Marshall +Date: Thu, 16 Jan 2020 13:07:04 -0800 +Subject: [PATCH] bionic: Support wildcards in cached hosts file + +If an exact name is not found in the hosts file and the host name +contains at least one dot, search for entries of the form "*.domain", +where domain is the portion of the host name after the first dot. If +that is not found, repeat using the domain. + +Example: a.b.c.example.com would search for the following in turn: + a.b.c.example.com + *.b.c.example.com + *.c.example.com + *.example.com + *.com + +Change-Id: I4b0bb81699151d5b371850daebf785e35ec9b180 +--- + libc/dns/net/hosts_cache.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/libc/dns/net/hosts_cache.c b/libc/dns/net/hosts_cache.c +index 52d29e032..fc6370d0c 100644 +--- a/libc/dns/net/hosts_cache.c ++++ b/libc/dns/net/hosts_cache.c +@@ -117,7 +117,7 @@ static int cmp_hcent_name(const void *a, const void *b) + return hstrcmp(na, nb); + } + +-static struct hcent *_hcfindname(const char *name) ++static struct hcent *_hcfindname_exact(const char *name) + { + size_t first, last, mid; + struct hcent *cur = NULL; +@@ -158,6 +158,33 @@ found: + return cur; + } + ++static struct hcent *_hcfindname(const char *name) ++{ ++ struct hcent *ent; ++ char namebuf[MAX_HOSTLEN]; ++ char *p; ++ char *dot; ++ ++ ent = _hcfindname_exact(name); ++ if (!ent && strlen(name) < sizeof(namebuf)) { ++ strcpy(namebuf, name); ++ p = namebuf; ++ do { ++ dot = strchr(p, '.'); ++ if (!dot) ++ break; ++ if (dot > p) { ++ *(dot - 1) = '*'; ++ ent = _hcfindname_exact(dot - 1); ++ } ++ p = dot + 1; ++ } ++ while (!ent); ++ } ++ ++ return ent; ++} ++ + /* + * Find next name on line, if any. + * diff --git a/Patches/LineageOS-21.0/android_bionic/0004-hosts_toggle.patch b/Patches/LineageOS-21.0/android_bionic/0004-hosts_toggle.patch new file mode 100644 index 00000000..3d8c3c90 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bionic/0004-hosts_toggle.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tad +Date: Wed, 20 Apr 2022 00:40:52 -0400 +Subject: [PATCH] Add a toggle to disable /etc/hosts lookup + +Signed-off-by: Tad +Change-Id: I92679c57e73228dc194e61a86ea1a18b2ac90e04 +--- + libc/dns/net/getaddrinfo.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c +index cc94b21e2..12294da04 100644 +--- a/libc/dns/net/getaddrinfo.c ++++ b/libc/dns/net/getaddrinfo.c +@@ -83,6 +83,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2127,6 +2128,11 @@ _files_getaddrinfo(void *rv, void *cb_data, va_list ap) + name = va_arg(ap, char *); + pai = va_arg(ap, struct addrinfo *); + ++ char value[PROP_VALUE_MAX] = { 0 }; ++ if (__system_property_get("persist.security.hosts_disable", value) != 0) ++ if (atoi(value) != 0 && strcmp(name, "localhost") != 0 && strcmp(name, "ip6-localhost") != 0) ++ return NS_NOTFOUND; ++ + memset(&sentinel, 0, sizeof(sentinel)); + cur = &sentinel; + int gai_error = hc_getaddrinfo(name, NULL, pai, &cur); diff --git a/Patches/LineageOS-21.0/android_bootable_recovery/0001-No_SerialNum_Restrictions.patch b/Patches/LineageOS-21.0/android_bootable_recovery/0001-No_SerialNum_Restrictions.patch new file mode 100644 index 00000000..a5413755 --- /dev/null +++ b/Patches/LineageOS-21.0/android_bootable_recovery/0001-No_SerialNum_Restrictions.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 19 Aug 2020 09:31:04 -0400 +Subject: [PATCH] reject updates with serialno constraints + +--- + install/install.cpp | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +diff --git a/install/install.cpp b/install/install.cpp +index 9906a41f..e85a95c5 100644 +--- a/install/install.cpp ++++ b/install/install.cpp +@@ -234,17 +234,8 @@ bool CheckPackageMetadata(const std::map& metadata, Ot + + auto pkg_serial_no = get_value(metadata, "serialno"); + if (!pkg_serial_no.empty()) { +- auto device_serial_no = android::base::GetProperty("ro.serialno", ""); +- bool serial_number_match = false; +- for (const auto& number : android::base::Split(pkg_serial_no, "|")) { +- if (device_serial_no == android::base::Trim(number)) { +- serial_number_match = true; +- } +- } +- if (!serial_number_match) { +- LOG(ERROR) << "Package is for serial " << pkg_serial_no; +- return false; +- } ++ LOG(ERROR) << "Serial number constraint not permitted: " << pkg_serial_no; ++ return INSTALL_ERROR; + } else if (ota_type == OtaType::BRICK) { + const auto device_build_tag = android::base::GetProperty("ro.build.tags", ""); + if (device_build_tag.empty()) { diff --git a/Patches/LineageOS-21.0/android_build/0001-Enable_fwrapv.patch b/Patches/LineageOS-21.0/android_build/0001-Enable_fwrapv.patch new file mode 100644 index 00000000..35fcfd39 --- /dev/null +++ b/Patches/LineageOS-21.0/android_build/0001-Enable_fwrapv.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 13 Sep 2016 22:05:56 -0400 +Subject: [PATCH] use -fwrapv when signed overflow checking is off + +Signed-off-by: anupritaisno1 +--- + core/config_sanitizers.mk | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/core/config_sanitizers.mk b/core/config_sanitizers.mk +index 3507961833..01cb295bfe 100644 +--- a/core/config_sanitizers.mk ++++ b/core/config_sanitizers.mk +@@ -572,3 +572,9 @@ ifneq ($(findstring fsanitize,$(my_cflags)),) + endif + endif + endif ++ ++ifeq ($(filter signed-integer-overflow integer undefined,$(my_sanitize)),) ++ ifeq ($(filter -ftrapv,$(my_cflags)),) ++ my_cflags += -fwrapv ++ endif ++endif diff --git a/Patches/LineageOS-21.0/android_build/0003-Exec_Based_Spawning.patch b/Patches/LineageOS-21.0/android_build/0003-Exec_Based_Spawning.patch new file mode 100644 index 00000000..c1a18ee7 --- /dev/null +++ b/Patches/LineageOS-21.0/android_build/0003-Exec_Based_Spawning.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Thu, 17 Sep 2020 10:53:00 -0400 +Subject: [PATCH] disable enforce RRO for mainline devices + +This is currently incompatible with exec-based spawning. This also +impacts the wrapper spawning model for the stock OS which is available +by default, making it an upstream bug rather than a missing feature for +exec-based spawning in GrapheneOS. + +Signed-off-by: anupritaisno1 +--- + target/product/generic_system.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/product/generic_system.mk b/target/product/generic_system.mk +index 08a7cdf83e..8ed85ab6fa 100644 +--- a/target/product/generic_system.mk ++++ b/target/product/generic_system.mk +@@ -112,7 +112,7 @@ PRODUCT_COPY_FILES += \ + # Enable dynamic partition size + PRODUCT_USE_DYNAMIC_PARTITION_SIZE := true + +-PRODUCT_ENFORCE_RRO_TARGETS := * ++#PRODUCT_ENFORCE_RRO_TARGETS := * + + PRODUCT_NAME := generic_system + PRODUCT_BRAND := generic diff --git a/Patches/LineageOS-21.0/android_build/0004-Selective_APEX.patch b/Patches/LineageOS-21.0/android_build/0004-Selective_APEX.patch new file mode 100644 index 00000000..315377ce --- /dev/null +++ b/Patches/LineageOS-21.0/android_build/0004-Selective_APEX.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: flawedworld +Date: Mon, 7 Mar 2022 01:38:23 +0000 +Subject: [PATCH] only enable APEX on 6th/7th gen Pixel devices + +Change-Id: Icffb72d8c3ed0e33e76538bb3427377c33c55ff9 +[tad@spotco.us]: adjusted for Lineage +--- + target/product/generic_system.mk | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/target/product/generic_system.mk b/target/product/generic_system.mk +index 8ed85ab6fa..7b9ed53281 100644 +--- a/target/product/generic_system.mk ++++ b/target/product/generic_system.mk +@@ -21,8 +21,10 @@ $(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk) + # Add adb keys to debuggable AOSP builds (if they exist) + $(call inherit-product-if-exists, vendor/google/security/adb/vendor_key.mk) + +-# Enable updating of APEXes +-$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk) ++# Enable updating of APEXes on 6th and 7th generation Pixel devices only ++ifneq (,$(filter lineage_cheetah lineage_panther lineage_oriole lineage_raven lineage_bluejay lineage_lynx lineage_tangorpro lineage_felix, $(TARGET_PRODUCT))) ++ $(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk) ++endif + + # Shared java libs + PRODUCT_PACKAGES += \ diff --git a/Patches/LineageOS-21.0/android_build_soong/0001-Enable_fwrapv.patch b/Patches/LineageOS-21.0/android_build_soong/0001-Enable_fwrapv.patch new file mode 100644 index 00000000..6290a2e7 --- /dev/null +++ b/Patches/LineageOS-21.0/android_build_soong/0001-Enable_fwrapv.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 23 Aug 2017 20:28:03 -0400 +Subject: [PATCH] use -fwrapv when signed overflow checking is off + +13: 62bea80ab9189b81a8728b71b284b7afba9d5969 +--- + cc/cc.go | 2 ++ + cc/cc_test.go | 2 +- + cc/sanitize.go | 14 ++++++++++++++ + 3 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/cc/cc.go b/cc/cc.go +index 9d5b8d894..01cae261a 100644 +--- a/cc/cc.go ++++ b/cc/cc.go +@@ -2052,6 +2052,8 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { + } + if c.sanitize != nil { + flags = c.sanitize.flags(ctx, flags) ++ } else { ++ flags.Local.CFlags = append(flags.Local.CFlags, "-fwrapv") + } + if c.coverage != nil { + flags, deps = c.coverage.flags(ctx, flags, deps) +diff --git a/cc/cc_test.go b/cc/cc_test.go +index 3631f1998..af9498499 100644 +--- a/cc/cc_test.go ++++ b/cc/cc_test.go +@@ -4427,7 +4427,7 @@ func TestIncludeDirectoryOrdering(t *testing.T) { + conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"} + cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"} + +- cflags := []string{"-Werror", "-std=candcpp"} ++ cflags := []string{"-Werror", "-std=candcpp", "-fwrapv"} + cstd := []string{"-std=gnu17", "-std=conly"} + cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"} + +diff --git a/cc/sanitize.go b/cc/sanitize.go +index 31c050018..38eeb12af 100644 +--- a/cc/sanitize.go ++++ b/cc/sanitize.go +@@ -787,8 +787,22 @@ func toDisableUnsignedShiftBaseChange(flags []string) bool { + + func (s *sanitize) flags(ctx ModuleContext, flags Flags) Flags { + if !s.Properties.SanitizerEnabled && !s.Properties.UbsanRuntimeDep { ++ flags.Local.CFlags = append(flags.Local.CFlags, "-fwrapv") + return flags + } ++ ++ wrapv := true ++ for _, san := range s.Properties.Sanitizers { ++ if san == "signed-integer-overflow" || san == "integer" || san == "undefined" { ++ wrapv = false ++ break ++ } ++ } ++ ++ if wrapv { ++ flags.Local.CFlags = append(flags.Local.CFlags, "-fwrapv") ++ } ++ + sanProps := &s.Properties.SanitizeMutated + + if Bool(sanProps.Address) { diff --git a/Patches/LineageOS-21.0/android_build_soong/0002-hm_available.patch b/Patches/LineageOS-21.0/android_build_soong/0002-hm_available.patch new file mode 100644 index 00000000..2d3305f1 --- /dev/null +++ b/Patches/LineageOS-21.0/android_build_soong/0002-hm_available.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Thu, 5 Oct 2023 15:16:24 +0300 +Subject: [PATCH] mark hardened_malloc as bp2build_available + +--- + android/allowlists/allowlists.go | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go +index b9d26f884..34c83e00c 100644 +--- a/android/allowlists/allowlists.go ++++ b/android/allowlists/allowlists.go +@@ -160,6 +160,7 @@ var ( + "external/guava": Bp2BuildDefaultTrueRecursively, + "external/gwp_asan": Bp2BuildDefaultTrueRecursively, + "external/hamcrest": Bp2BuildDefaultTrueRecursively, ++ "external/hardened_malloc": Bp2BuildDefaultTrueRecursively, + "external/icu": Bp2BuildDefaultTrueRecursively, + "external/icu/android_icu4j": Bp2BuildDefaultFalse, // java rules incomplete + "external/icu/icu4j": Bp2BuildDefaultFalse, // java rules incomplete diff --git a/Patches/LineageOS-21.0/android_external_conscrypt/0001-constify_JNINativeMethod.patch b/Patches/LineageOS-21.0/android_external_conscrypt/0001-constify_JNINativeMethod.patch new file mode 100644 index 00000000..64e19cb3 --- /dev/null +++ b/Patches/LineageOS-21.0/android_external_conscrypt/0001-constify_JNINativeMethod.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 18 Nov 2020 14:28:24 -0500 +Subject: [PATCH] constify JNINativeMethod table + +--- + common/src/jni/main/cpp/conscrypt/native_crypto.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc +index 6d831d03..db24fbc3 100644 +--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc ++++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc +@@ -10940,7 +10940,7 @@ static jlong NativeCrypto_SSL_get1_session(JNIEnv* env, jclass, jlong ssl_addres + #define REF_X509_CRL "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLX509CRL;" + #define REF_SSL "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeSsl;" + #define REF_SSL_CTX "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/AbstractSessionContext;" +-static JNINativeMethod sNativeCryptoMethods[] = { ++static const JNINativeMethod sNativeCryptoMethods[] = { + CONSCRYPT_NATIVE_METHOD(clinit, "()V"), + CONSCRYPT_NATIVE_METHOD(CMAC_CTX_new, "()J"), + CONSCRYPT_NATIVE_METHOD(CMAC_CTX_free, "(J)V"), diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0003-SUPL_No_IMSI.patch b/Patches/LineageOS-21.0/android_frameworks_base/0003-SUPL_No_IMSI.patch new file mode 100644 index 00000000..e7c36dd8 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0003-SUPL_No_IMSI.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MSe1969 +Date: Mon, 29 Oct 2018 12:14:17 +0100 +Subject: [PATCH] SUPL: Don't send IMSI / Phone number to SUPL server + +Change-Id: I5ccc4d61e52ac11ef33f44618d0e610089885b87 +--- + .../android/server/location/gnss/GnssLocationProvider.java | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +index 0386ee454278..af7dcc7d917a 100644 +--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java ++++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +@@ -1798,6 +1798,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements + int type = AGPS_SETID_TYPE_NONE; + String setId = null; + ++ /* ++ * We don't want to tell Google our IMSI or phone number to spy on us! ++ * As devices w/o SIM card also have working GPS, providing this data does ++ * not seem to add a lot of value, at least not for the device holder ++ * + int subId = SubscriptionManager.getDefaultDataSubscriptionId(); + if (mGnssConfiguration.isActiveSimEmergencySuplEnabled() && mNIHandler.getInEmergency() + && mNetworkConnectivityHandler.getActiveSubId() >= 0) { +@@ -1818,7 +1823,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements + // This means the framework has the SIM card. + type = AGPS_SETID_TYPE_MSISDN; + } +- } ++ } */ + + mGnssNative.setAgpsSetId(type, (setId == null) ? "" : setId); + } diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0004-Fingerprint_Lockout.patch b/Patches/LineageOS-21.0/android_frameworks_base/0004-Fingerprint_Lockout.patch new file mode 100644 index 00000000..f7ba2902 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0004-Fingerprint_Lockout.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 12 Sep 2017 01:52:11 -0400 +Subject: [PATCH] use permanent fingerprint lockout immediately + +Signed-off-by: anupritaisno1 +--- + .../sensors/fingerprint/hidl/LockoutFrameworkImpl.java | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/LockoutFrameworkImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/LockoutFrameworkImpl.java +index 0730c672acd9..cbd7a8963eb1 100644 +--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/LockoutFrameworkImpl.java ++++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/LockoutFrameworkImpl.java +@@ -43,7 +43,7 @@ public class LockoutFrameworkImpl implements LockoutTracker { + private static final String ACTION_LOCKOUT_RESET = + "com.android.server.biometrics.sensors.fingerprint.ACTION_LOCKOUT_RESET"; + private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED = 5; +- private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT = 20; ++ private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT = 5; + private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30 * 1000; + private static final String KEY_LOCKOUT_RESET_USER = "lockout_reset_user"; + diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0005-User_Logout-a1.patch b/Patches/LineageOS-21.0/android_frameworks_base/0005-User_Logout-a1.patch new file mode 100644 index 00000000..3f0401da --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0005-User_Logout-a1.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Thu, 18 Aug 2022 10:04:46 +0300 +Subject: [PATCH] fix DevicePolicyManager#logoutUser() never succeeding + +To succeed, userId to switch to needs to be set with setLogoutUserIdLocked(), but this is not done +in both callers of this method (both of which are "End session" buttons), making them no-ops. +--- + .../server/devicepolicy/DevicePolicyManagerService.java | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +index cc8da148d272..6a2d88e49c27 100644 +--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java ++++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +@@ -12698,6 +12698,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + Preconditions.checkCallAuthorization(canManageUsers(caller) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS)); + ++ synchronized (getLockObject()) { ++ if (getLogoutUserIdUnchecked() == UserHandle.USER_NULL) { ++ setLogoutUserIdLocked(UserHandle.USER_SYSTEM); ++ } ++ } ++ + int currentUserId = getCurrentForegroundUserId(); + if (VERBOSE_LOG) { + Slogf.v(LOG_TAG, "logout() called by uid %d; current user is %d", caller.getUid(), diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0005-User_Logout.patch b/Patches/LineageOS-21.0/android_frameworks_base/0005-User_Logout.patch new file mode 100644 index 00000000..5a64663d --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0005-User_Logout.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: flawedworld +Date: Fri, 15 Oct 2021 17:07:13 +0100 +Subject: [PATCH] enable secondary user logout support by default + +Ported from 11, 12 moved the isLogoutEnabled boolean to ActiveAdmin.java +--- + .../java/com/android/server/devicepolicy/ActiveAdmin.java | 2 +- + .../server/devicepolicy/DevicePolicyManagerService.java | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +index 17638fcaba68..7e416811c45a 100644 +--- a/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java ++++ b/services/devicepolicy/java/com/android/server/devicepolicy/ActiveAdmin.java +@@ -234,7 +234,7 @@ class ActiveAdmin { + boolean requireAutoTime = false; + boolean forceEphemeralUsers = false; + boolean isNetworkLoggingEnabled = false; +- boolean isLogoutEnabled = false; ++ boolean isLogoutEnabled = true; + + // one notification after enabling + one more after reboots + static final int DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN = 2; +diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +index fb07763f58d6..cc8da148d272 100644 +--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java ++++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +@@ -18919,11 +18919,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + @Override + public boolean isLogoutEnabled() { + if (!mHasFeature) { +- return false; ++ return true; + } + synchronized (getLockObject()) { + ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); +- return (deviceOwner != null) && deviceOwner.isLogoutEnabled; ++ return (deviceOwner == null) || deviceOwner.isLogoutEnabled; + } + } + diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0007-Always_Restict_Serial.patch b/Patches/LineageOS-21.0/android_frameworks_base/0007-Always_Restict_Serial.patch new file mode 100644 index 00000000..42b7db9a --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0007-Always_Restict_Serial.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 6 Sep 2017 21:40:48 -0400 +Subject: [PATCH] always set deprecated Build.SERIAL to UNKNOWN + +Only support fetching the serial number via the new Build.getSerial() +requiring the READ_PHONE_STATE permission. +--- + .../java/com/android/server/am/ActivityManagerService.java | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java +index 89b53aab1539..0d95e615911d 100644 +--- a/services/core/java/com/android/server/am/ActivityManagerService.java ++++ b/services/core/java/com/android/server/am/ActivityManagerService.java +@@ -4707,12 +4707,7 @@ public class ActivityManagerService extends IActivityManager.Stub + + ProfilerInfo profilerInfo = mAppProfiler.setupProfilerInfoLocked(thread, app, instr); + +- // We deprecated Build.SERIAL and it is not accessible to +- // Instant Apps and target APIs higher than O MR1. Since access to the serial +- // is now behind a permission we push down the value. +- final String buildSerial = (!appInfo.isInstantApp() +- && appInfo.targetSdkVersion < Build.VERSION_CODES.P) +- ? sTheRealBuildSerial : Build.UNKNOWN; ++ final String buildSerial = Build.UNKNOWN; + + // Figure out whether the app needs to run in autofill compat mode. + AutofillOptions autofillOptions = null; diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0008-Browser_No_Location.patch b/Patches/LineageOS-21.0/android_frameworks_base/0008-Browser_No_Location.patch new file mode 100644 index 00000000..63a84459 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0008-Browser_No_Location.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Mon, 18 Mar 2019 01:54:30 +0200 +Subject: [PATCH] stop auto-granting location to system browsers + +--- + .../pm/permission/DefaultPermissionGrantPolicy.java | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +index f7f76aaaee16..2c5b6ddc876e 100644 +--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java ++++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +@@ -776,19 +776,6 @@ final class DefaultPermissionGrantPolicy { + Intent.CATEGORY_APP_EMAIL, userId), + userId, CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS); + +- // Browser +- String browserPackage = ArrayUtils.firstOrNull(getKnownPackages( +- KnownPackages.PACKAGE_BROWSER, userId)); +- if (browserPackage == null) { +- browserPackage = getDefaultSystemHandlerActivityPackageForCategory(pm, +- Intent.CATEGORY_APP_BROWSER, userId); +- if (!pm.isSystemPackage(browserPackage)) { +- browserPackage = null; +- } +- } +- grantPermissionsToPackage(pm, browserPackage, userId, false /* ignoreSystemPackage */, +- true /*whitelistRestrictedPermissions*/, FOREGROUND_LOCATION_PERMISSIONS); +- + // Voice interaction + if (voiceInteractPackageNames != null) { + for (String voiceInteractPackageName : voiceInteractPackageNames) { diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0017-constify_JNINativeMethod.patch b/Patches/LineageOS-21.0/android_frameworks_base/0017-constify_JNINativeMethod.patch new file mode 100644 index 00000000..df33b123 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0017-constify_JNINativeMethod.patch @@ -0,0 +1,509 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Mon, 9 Oct 2023 14:21:11 +0300 +Subject: [PATCH] constify JNINativeMethod tables + +fd '.+\.(c|cpp|cc)$' --exec sed -i 's/static JNINativeMethod/static const JNINativeMethod/' +--- + .../jni/com_android_commands_hid_Device.cpp | 2 +- + .../com_android_commands_uinput_Device.cpp | 2 +- + core/jni/LayoutlibLoader.cpp | 2 +- + core/jni/android_app_ActivityThread.cpp | 2 +- + core/jni/android_media_MediaMetricsJNI.cpp | 238 +++++++++++++++++- + core/jni/android_os_HidlMemory.cpp | 2 +- + core/jni/android_os_HwBinder.cpp | 2 +- + core/jni/android_os_HwBlob.cpp | 2 +- + core/jni/android_os_HwParcel.cpp | 2 +- + core/jni/android_os_HwRemoteBinder.cpp | 2 +- + .../android_graphics_DisplayListCanvas.cpp | 2 +- + media/jni/android_media_ImageWriter.cpp | 4 +- + media/jni/android_media_MediaSync.cpp | 2 +- + .../jni/soundpool/android_media_SoundPool.cpp | 2 +- + .../com_android_server_UsbAlsaMidiDevice.cpp | 2 +- + ...rver_companion_virtual_InputController.cpp | 2 +- + .../com_android_server_tv_TvUinputBridge.cpp | 2 +- + ...oid_view_tests_ChoreographerNativeTest.cpp | 2 +- + 18 files changed, 255 insertions(+), 19 deletions(-) + mode change 120000 => 100644 core/jni/android_media_MediaMetricsJNI.cpp + +diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp +index 8b8d361edbd4..60aa5e4267aa 100644 +--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp ++++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp +@@ -368,7 +368,7 @@ static void closeDevice(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { + } + } + +-static JNINativeMethod sMethods[] = { ++static const JNINativeMethod sMethods[] = { + {"nativeOpenDevice", + "(Ljava/lang/String;IIII[B" + "Lcom/android/commands/hid/Device$DeviceCallback;)J", +diff --git a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp +index a78a46504684..5752be8829cb 100644 +--- a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp ++++ b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp +@@ -325,7 +325,7 @@ static jint getEvdevInputPropByLabel(JNIEnv* env, jclass /* clazz */, jstring ra + return InputEventLookup::getLinuxEvdevInputPropByLabel(label.c_str()).value_or(-1); + } + +-static JNINativeMethod sMethods[] = { ++static const JNINativeMethod sMethods[] = { + {"nativeOpenUinputDevice", + "(Ljava/lang/String;IIIIIILjava/lang/String;" + "Lcom/android/commands/uinput/Device$DeviceCallback;)J", +diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp +index 200ddefc3bbc..e7acbdfbddf6 100644 +--- a/core/jni/LayoutlibLoader.cpp ++++ b/core/jni/LayoutlibLoader.cpp +@@ -69,7 +69,7 @@ static void NativeAllocationRegistry_Delegate_nativeApplyFreeFunction(JNIEnv*, j + nativeFreeFunction(nativePtr); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + NATIVE_METHOD(NativeAllocationRegistry_Delegate, nativeApplyFreeFunction, "(JJ)V"), + }; + +diff --git a/core/jni/android_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp +index e25ba76cbbeb..16a8d4656179 100644 +--- a/core/jni/android_app_ActivityThread.cpp ++++ b/core/jni/android_app_ActivityThread.cpp +@@ -33,7 +33,7 @@ static void android_app_ActivityThread_initZygoteChildHeapProfiling(JNIEnv* env, + android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0); + } + +-static JNINativeMethod gActivityThreadMethods[] = { ++static const JNINativeMethod gActivityThreadMethods[] = { + // ------------ Regular JNI ------------------ + { "nPurgePendingResources", "()V", + (void*) android_app_ActivityThread_purgePendingResources }, +diff --git a/core/jni/android_media_MediaMetricsJNI.cpp b/core/jni/android_media_MediaMetricsJNI.cpp +deleted file mode 120000 +index 3204317cab68..000000000000 +--- a/core/jni/android_media_MediaMetricsJNI.cpp ++++ /dev/null +@@ -1 +0,0 @@ +-../../media/jni/android_media_MediaMetricsJNI.cpp +\ No newline at end of file +diff --git a/core/jni/android_media_MediaMetricsJNI.cpp b/core/jni/android_media_MediaMetricsJNI.cpp +new file mode 100644 +index 000000000000..2769dbc430ba +--- /dev/null ++++ b/core/jni/android_media_MediaMetricsJNI.cpp +@@ -0,0 +1,237 @@ ++/* ++ * Copyright 2017, 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. ++ */ ++ ++#define LOG_TAG "MediaMetricsJNI" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "android_media_MediaMetricsJNI.h" ++#include "android_os_Parcel.h" ++#include "android_runtime/AndroidRuntime.h" ++ ++// This source file is compiled and linked into: ++// core/jni/ (libandroid_runtime.so) ++ ++namespace android { ++ ++namespace { ++struct BundleHelper { ++ BundleHelper(JNIEnv* _env, jobject _bundle) ++ : env(_env) ++ , clazzBundle(env->FindClass("android/os/PersistableBundle")) ++ , putIntID(env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V")) ++ , putLongID(env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V")) ++ , putDoubleID(env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V")) ++ , putStringID(env->GetMethodID(clazzBundle, ++ "putString", "(Ljava/lang/String;Ljava/lang/String;)V")) ++ , constructID(env->GetMethodID(clazzBundle, "", "()V")) ++ , bundle(_bundle == nullptr ? env->NewObject(clazzBundle, constructID) : _bundle) ++ { } ++ ++ JNIEnv* const env; ++ const jclass clazzBundle; ++ const jmethodID putIntID; ++ const jmethodID putLongID; ++ const jmethodID putDoubleID; ++ const jmethodID putStringID; ++ const jmethodID constructID; ++ jobject const bundle; ++ ++ // We use templated put to access mediametrics::Item based on data type not type enum. ++ // See std::variant and std::visit. ++ template ++ void put(jstring keyName, const T& value) = delete; ++ ++ template<> ++ void put(jstring keyName, const int32_t& value) { ++ env->CallVoidMethod(bundle, putIntID, keyName, (jint)value); ++ } ++ ++ template<> ++ void put(jstring keyName, const int64_t& value) { ++ env->CallVoidMethod(bundle, putLongID, keyName, (jlong)value); ++ } ++ ++ template<> ++ void put(jstring keyName, const double& value) { ++ env->CallVoidMethod(bundle, putDoubleID, keyName, (jdouble)value); ++ } ++ ++ template<> ++ void put(jstring keyName, const std::string& value) { ++ env->CallVoidMethod(bundle, putStringID, keyName, env->NewStringUTF(value.c_str())); ++ } ++ ++ template<> ++ void put(jstring keyName, const std::pair& value) { ++ ; // rate is currently ignored ++ } ++ ++ template<> ++ void put(jstring keyName, const std::monostate& value) { ++ ; // none is currently ignored ++ } ++ ++ // string char * helpers ++ ++ template<> ++ void put(jstring keyName, const char * const& value) { ++ env->CallVoidMethod(bundle, putStringID, keyName, env->NewStringUTF(value)); ++ } ++ ++ template<> ++ void put(jstring keyName, char * const& value) { ++ env->CallVoidMethod(bundle, putStringID, keyName, env->NewStringUTF(value)); ++ } ++ ++ // We allow both jstring and non-jstring variants. ++ template ++ void put(const char *keyName, const T& value) { ++ put(env->NewStringUTF(keyName), value); ++ } ++}; ++} // namespace ++ ++// place the attributes into a java PersistableBundle object ++jobject MediaMetricsJNI::writeMetricsToBundle( ++ JNIEnv* env, mediametrics::Item *item, jobject bundle) ++{ ++ BundleHelper bh(env, bundle); ++ ++ if (bh.bundle == nullptr) { ++ ALOGE("%s: unable to create Bundle", __func__); ++ return nullptr; ++ } ++ ++ bh.put(mediametrics::BUNDLE_KEY, item->getKey().c_str()); ++ if (item->getPid() != -1) { ++ bh.put(mediametrics::BUNDLE_PID, (int32_t)item->getPid()); ++ } ++ if (item->getTimestamp() > 0) { ++ bh.put(mediametrics::BUNDLE_TIMESTAMP, (int64_t)item->getTimestamp()); ++ } ++ if (static_cast(item->getUid()) != -1) { ++ bh.put(mediametrics::BUNDLE_UID, (int32_t)item->getUid()); ++ } ++ for (const auto &prop : *item) { ++ const char *name = prop.getName(); ++ if (name == nullptr) continue; ++ prop.visit([&] (auto &value) { bh.put(name, value); }); ++ } ++ return bh.bundle; ++} ++ ++// Implementation of MediaMetrics.native_submit_bytebuffer(), ++// Delivers the byte buffer to the mediametrics service. ++static jint android_media_MediaMetrics_submit_bytebuffer( ++ JNIEnv* env, jobject thiz, jobject byteBuffer, jint length) ++{ ++ const jbyte* buffer = ++ reinterpret_cast(env->GetDirectBufferAddress(byteBuffer)); ++ if (buffer == nullptr) { ++ ALOGE("Error retrieving source of audio data to play, can't play"); ++ return (jint)BAD_VALUE; ++ } ++ ++ return (jint)mediametrics::BaseItem::submitBuffer((char *)buffer, length); ++} ++ ++// Helper function to convert a native PersistableBundle to a Java ++// PersistableBundle. ++jobject MediaMetricsJNI::nativeToJavaPersistableBundle(JNIEnv *env, ++ os::PersistableBundle* nativeBundle) { ++ if (env == NULL || nativeBundle == NULL) { ++ ALOGE("Unexpected NULL parmeter"); ++ return NULL; ++ } ++ ++ // Create a Java parcel with the native parcel data. ++ // Then create a new PersistableBundle with that parcel as a parameter. ++ jobject jParcel = android::createJavaParcelObject(env); ++ if (jParcel == NULL) { ++ ALOGE("Failed to create a Java Parcel."); ++ return NULL; ++ } ++ ++ android::Parcel* nativeParcel = android::parcelForJavaObject(env, jParcel); ++ if (nativeParcel == NULL) { ++ ALOGE("Failed to get the native Parcel."); ++ return NULL; ++ } ++ ++ android::status_t result = nativeBundle->writeToParcel(nativeParcel); ++ nativeParcel->setDataPosition(0); ++ if (result != android::OK) { ++ ALOGE("Failed to write nativeBundle to Parcel: %d.", result); ++ return NULL; ++ } ++ ++#define STATIC_INIT_JNI(T, obj, method, globalref, ...) \ ++ static T obj{};\ ++ if (obj == NULL) { \ ++ obj = method(__VA_ARGS__); \ ++ if (obj == NULL) { \ ++ ALOGE("%s can't find " #obj, __func__); \ ++ return NULL; \ ++ } else { \ ++ obj = globalref; \ ++ }\ ++ } \ ++ ++ STATIC_INIT_JNI(jclass, clazzBundle, env->FindClass, ++ static_cast(env->NewGlobalRef(clazzBundle)), ++ "android/os/PersistableBundle"); ++ STATIC_INIT_JNI(jfieldID, bundleCreatorId, env->GetStaticFieldID, ++ bundleCreatorId, ++ clazzBundle, "CREATOR", "Landroid/os/Parcelable$Creator;"); ++ STATIC_INIT_JNI(jobject, bundleCreator, env->GetStaticObjectField, ++ env->NewGlobalRef(bundleCreator), ++ clazzBundle, bundleCreatorId); ++ STATIC_INIT_JNI(jclass, clazzCreator, env->FindClass, ++ static_cast(env->NewGlobalRef(clazzCreator)), ++ "android/os/Parcelable$Creator"); ++ STATIC_INIT_JNI(jmethodID, createFromParcelId, env->GetMethodID, ++ createFromParcelId, ++ clazzCreator, "createFromParcel", "(Landroid/os/Parcel;)Ljava/lang/Object;"); ++ ++ jobject newBundle = env->CallObjectMethod(bundleCreator, createFromParcelId, jParcel); ++ if (newBundle == NULL) { ++ ALOGE("Failed to create a new PersistableBundle " ++ "from the createFromParcel call."); ++ } ++ ++ return newBundle; ++} ++ ++// ---------------------------------------------------------------------------- ++ ++static constexpr JNINativeMethod gMethods[] = { ++ {"native_submit_bytebuffer", "(Ljava/nio/ByteBuffer;I)I", ++ (void *)android_media_MediaMetrics_submit_bytebuffer}, ++}; ++ ++// Registers the native methods, called from core/jni/AndroidRuntime.cpp ++int register_android_media_MediaMetrics(JNIEnv *env) ++{ ++ return AndroidRuntime::registerNativeMethods( ++ env, "android/media/MediaMetrics", gMethods, std::size(gMethods)); ++} ++ ++}; // namespace android +diff --git a/core/jni/android_os_HidlMemory.cpp b/core/jni/android_os_HidlMemory.cpp +index 69e48184c0ad..612fc95776a5 100644 +--- a/core/jni/android_os_HidlMemory.cpp ++++ b/core/jni/android_os_HidlMemory.cpp +@@ -50,7 +50,7 @@ static void nativeFinalize(JNIEnv* env, jobject jobj) { + delete native; + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + {"nativeFinalize", "()V", (void*) nativeFinalize}, + }; + +diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp +index 781895eeeaba..cbec79144826 100644 +--- a/core/jni/android_os_HwBinder.cpp ++++ b/core/jni/android_os_HwBinder.cpp +@@ -352,7 +352,7 @@ static void JHwBinder_report_sysprop_change(JNIEnv * /*env*/, jclass /*clazz*/) + report_sysprop_change(); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "native_init", "()J", (void *)JHwBinder_native_init }, + { "native_setup", "()V", (void *)JHwBinder_native_setup }, + +diff --git a/core/jni/android_os_HwBlob.cpp b/core/jni/android_os_HwBlob.cpp +index e554b44233b5..065937f935fb 100644 +--- a/core/jni/android_os_HwBlob.cpp ++++ b/core/jni/android_os_HwBlob.cpp +@@ -599,7 +599,7 @@ static jlong JHwBlob_native_handle(JNIEnv *env, jobject thiz) { + return handle; + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "native_init", "()J", (void *)JHwBlob_native_init }, + { "native_setup", "(I)V", (void *)JHwBlob_native_setup }, + +diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp +index 0e3c51047b31..edda99533f63 100644 +--- a/core/jni/android_os_HwParcel.cpp ++++ b/core/jni/android_os_HwParcel.cpp +@@ -1066,7 +1066,7 @@ static void JHwParcel_native_writeBuffer( + } + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "native_init", "()J", (void *)JHwParcel_native_init }, + { "native_setup", "(Z)V", (void *)JHwParcel_native_setup }, + +diff --git a/core/jni/android_os_HwRemoteBinder.cpp b/core/jni/android_os_HwRemoteBinder.cpp +index d2d7213e5761..497aa193eb4d 100644 +--- a/core/jni/android_os_HwRemoteBinder.cpp ++++ b/core/jni/android_os_HwRemoteBinder.cpp +@@ -452,7 +452,7 @@ static jint JHwRemoteBinder_hashCode(JNIEnv* env, jobject thiz) { + return static_cast(longHash ^ (longHash >> 32)); // See Long.hashCode() + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "native_init", "()J", (void *)JHwRemoteBinder_native_init }, + + { "native_setup_empty", "()V", +diff --git a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp +index 426644ee6a4e..f886d7dc4e5c 100644 +--- a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp ++++ b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp +@@ -174,7 +174,7 @@ static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAM + + const char* const kClassPathName = "android/graphics/RecordingCanvas"; + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + {"nGetMaximumTextureWidth", "()I", (void*)android_view_DisplayListCanvas_getMaxTextureSize}, + {"nGetMaximumTextureHeight", "()I", + (void*)android_view_DisplayListCanvas_getMaxTextureSize}, +diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp +index f64233fb9c79..a99fcea46911 100644 +--- a/media/jni/android_media_ImageWriter.cpp ++++ b/media/jni/android_media_ImageWriter.cpp +@@ -1114,7 +1114,7 @@ static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz, + + // ---------------------------------------------------------------------------- + +-static JNINativeMethod gImageWriterMethods[] = { ++static const JNINativeMethod gImageWriterMethods[] = { + {"nativeClassInit", "()V", (void*)ImageWriter_classInit }, + {"nativeInit", "(Ljava/lang/Object;Landroid/view/Surface;IIIZIIJ)J", + (void*)ImageWriter_init }, +@@ -1131,7 +1131,7 @@ static JNINativeMethod gImageWriterMethods[] = { + {"cancelImage", "(JLandroid/media/Image;)V", (void*)ImageWriter_cancelImage }, + }; + +-static JNINativeMethod gImageMethods[] = { ++static const JNINativeMethod gImageMethods[] = { + {"nativeCreatePlanes", "(II)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;", + (void*)Image_createSurfacePlanes }, + {"nativeGetWidth", "()I", (void*)Image_getWidth }, +diff --git a/media/jni/android_media_MediaSync.cpp b/media/jni/android_media_MediaSync.cpp +index d1ce30a3e827..d93bda166c44 100644 +--- a/media/jni/android_media_MediaSync.cpp ++++ b/media/jni/android_media_MediaSync.cpp +@@ -514,7 +514,7 @@ static void android_media_MediaSync_native_finalize(JNIEnv *env, jobject thiz) { + android_media_MediaSync_release(env, thiz); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "native_setSurface", + "(Landroid/view/Surface;)V", + (void *)android_media_MediaSync_native_setSurface }, +diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp +index 25040a942061..f62c4340428c 100644 +--- a/media/jni/soundpool/android_media_SoundPool.cpp ++++ b/media/jni/soundpool/android_media_SoundPool.cpp +@@ -560,7 +560,7 @@ android_media_SoundPool_release(JNIEnv *env, jobject thiz) + // ---------------------------------------------------------------------------- + + // Dalvik VM type signatures +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + { "_load", + "(Ljava/io/FileDescriptor;JJI)I", + (void *)android_media_SoundPool_load_FD +diff --git a/services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp b/services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp +index 93938b1ff1bc..47b22c5fd39f 100644 +--- a/services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp ++++ b/services/core/jni/com_android_server_UsbAlsaMidiDevice.cpp +@@ -138,7 +138,7 @@ static void android_server_UsbAlsaMidiDevice_close(JNIEnv *env, jobject thiz, jo + } + } + +-static JNINativeMethod method_table[] = { ++static const JNINativeMethod method_table[] = { + {"nativeOpen", "(IIII)[Ljava/io/FileDescriptor;", + (void *)android_server_UsbAlsaMidiDevice_open}, + {"nativeClose", "([Ljava/io/FileDescriptor;)V", +diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp +index 4cd018b0269e..039258cf983c 100644 +--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp ++++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp +@@ -287,7 +287,7 @@ static bool nativeWriteScrollEvent(JNIEnv* env, jobject thiz, jlong ptr, jfloat + std::chrono::nanoseconds(eventTimeNanos)); + } + +-static JNINativeMethod methods[] = { ++static const JNINativeMethod methods[] = { + {"nativeOpenUinputDpad", "(Ljava/lang/String;IILjava/lang/String;)J", + (void*)nativeOpenUinputDpad}, + {"nativeOpenUinputKeyboard", "(Ljava/lang/String;IILjava/lang/String;)J", +diff --git a/services/core/jni/com_android_server_tv_TvUinputBridge.cpp b/services/core/jni/com_android_server_tv_TvUinputBridge.cpp +index 99deab4fd652..2cb1aaef13fa 100644 +--- a/services/core/jni/com_android_server_tv_TvUinputBridge.cpp ++++ b/services/core/jni/com_android_server_tv_TvUinputBridge.cpp +@@ -534,7 +534,7 @@ static void nativeClear(JNIEnv* env, jclass clazz, jlong ptr) { + * JNI registration + */ + +-static JNINativeMethod gUinputBridgeMethods[] = { ++static const JNINativeMethod gUinputBridgeMethods[] = { + {"nativeOpen", "(Ljava/lang/String;Ljava/lang/String;III)J", (void*)nativeOpen}, + {"nativeGamepadOpen", "(Ljava/lang/String;Ljava/lang/String;)J", (void*)nativeGamepadOpen}, + {"nativeClose", "(J)V", (void*)nativeClose}, +diff --git a/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp b/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp +index 27f4bae9e65a..b5620251d41b 100644 +--- a/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp ++++ b/tests/ChoreographerTests/jni/android_view_tests_ChoreographerNativeTest.cpp +@@ -151,7 +151,7 @@ static void android_view_ChoreographerNativeTest_testPostVsyncCallbackAtFrameRat + endTest(env, clazz); + } + +-static JNINativeMethod gMethods[] = { ++static const JNINativeMethod gMethods[] = { + {"nativeSurfaceControl_getChoreographer", "(Landroid/view/SurfaceControl;)J", + (void*)SurfaceControl_getChoreographer}, + {"nativeTestPostVsyncCallbackAtFrameRate", "(JF)V", diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch new file mode 100644 index 00000000..64a2d088 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-1.patch @@ -0,0 +1,181 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 14 Mar 2015 18:10:20 -0400 +Subject: [PATCH] add exec-based spawning support + +--- + .../com/android/internal/os/ExecInit.java | 115 ++++++++++++++++++ + .../com/android/internal/os/WrapperInit.java | 2 +- + .../android/internal/os/ZygoteConnection.java | 10 +- + 3 files changed, 125 insertions(+), 2 deletions(-) + create mode 100644 core/java/com/android/internal/os/ExecInit.java + +diff --git a/core/java/com/android/internal/os/ExecInit.java b/core/java/com/android/internal/os/ExecInit.java +new file mode 100644 +index 000000000000..2adcab7fdbe6 +--- /dev/null ++++ b/core/java/com/android/internal/os/ExecInit.java +@@ -0,0 +1,115 @@ ++package com.android.internal.os; ++ ++import android.os.Trace; ++import android.system.ErrnoException; ++import android.system.Os; ++import android.util.Slog; ++import android.util.TimingsTraceLog; ++import dalvik.system.VMRuntime; ++ ++/** ++ * Startup class for the process. ++ * @hide ++ */ ++public class ExecInit { ++ /** ++ * Class not instantiable. ++ */ ++ private ExecInit() { ++ } ++ ++ /** ++ * The main function called when starting a runtime application. ++ * ++ * The first argument is the target SDK version for the app. ++ * ++ * The remaining arguments are passed to the runtime. ++ * ++ * @param args The command-line arguments. ++ */ ++ public static void main(String[] args) { ++ // Parse our mandatory argument. ++ int targetSdkVersion = Integer.parseInt(args[0], 10); ++ ++ // Mimic system Zygote preloading. ++ ZygoteInit.preload(new TimingsTraceLog("ExecInitTiming", ++ Trace.TRACE_TAG_DALVIK)); ++ ++ // Launch the application. ++ String[] runtimeArgs = new String[args.length - 1]; ++ System.arraycopy(args, 1, runtimeArgs, 0, runtimeArgs.length); ++ Runnable r = execInit(targetSdkVersion, runtimeArgs); ++ ++ r.run(); ++ } ++ ++ /** ++ * Executes a runtime application with exec-based spawning. ++ * This method never returns. ++ * ++ * @param niceName The nice name for the application, or null if none. ++ * @param targetSdkVersion The target SDK version for the app. ++ * @param args Arguments for {@link RuntimeInit#main}. ++ */ ++ public static void execApplication(String niceName, int targetSdkVersion, ++ String instructionSet, String[] args) { ++ int niceArgs = niceName == null ? 0 : 1; ++ int baseArgs = 5 + niceArgs; ++ String[] argv = new String[baseArgs + args.length]; ++ if (VMRuntime.is64BitInstructionSet(instructionSet)) { ++ argv[0] = "/system/bin/app_process64"; ++ } else { ++ argv[0] = "/system/bin/app_process32"; ++ } ++ argv[1] = "/system/bin"; ++ argv[2] = "--application"; ++ if (niceName != null) { ++ argv[3] = "--nice-name=" + niceName; ++ } ++ argv[3 + niceArgs] = "com.android.internal.os.ExecInit"; ++ argv[4 + niceArgs] = Integer.toString(targetSdkVersion); ++ System.arraycopy(args, 0, argv, baseArgs, args.length); ++ ++ WrapperInit.preserveCapabilities(); ++ try { ++ Os.execv(argv[0], argv); ++ } catch (ErrnoException e) { ++ throw new RuntimeException(e); ++ } ++ } ++ ++ /** ++ * The main function called when an application is started with exec-based spawning. ++ * ++ * When the app starts, the runtime starts {@link RuntimeInit#main} ++ * which calls {@link main} which then calls this method. ++ * So we don't need to call commonInit() here. ++ * ++ * @param targetSdkVersion target SDK version ++ * @param argv arg strings ++ */ ++ private static Runnable execInit(int targetSdkVersion, String[] argv) { ++ if (RuntimeInit.DEBUG) { ++ Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from exec"); ++ } ++ ++ // Check whether the first argument is a "-cp" in argv, and assume the next argument is the ++ // classpath. If found, create a PathClassLoader and use it for applicationInit. ++ ClassLoader classLoader = null; ++ if (argv != null && argv.length > 2 && argv[0].equals("-cp")) { ++ classLoader = ZygoteInit.createPathClassLoader(argv[1], targetSdkVersion); ++ ++ // Install this classloader as the context classloader, too. ++ Thread.currentThread().setContextClassLoader(classLoader); ++ ++ // Remove the classpath from the arguments. ++ String removedArgs[] = new String[argv.length - 2]; ++ System.arraycopy(argv, 2, removedArgs, 0, argv.length - 2); ++ argv = removedArgs; ++ } ++ ++ // Perform the same initialization that would happen after the Zygote forks. ++ Zygote.nativePreApplicationInit(); ++ return RuntimeInit.applicationInit(targetSdkVersion, /*disabledCompatChanges*/ null, argv, classLoader); ++ } ++} +diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java +index 6860759eea8a..a2eef62f80be 100644 +--- a/core/java/com/android/internal/os/WrapperInit.java ++++ b/core/java/com/android/internal/os/WrapperInit.java +@@ -186,7 +186,7 @@ public class WrapperInit { + * This is acceptable here as failure will leave the wrapped app with strictly less + * capabilities, which may make it crash, but not exceed its allowances. + */ +- private static void preserveCapabilities() { ++ public static void preserveCapabilities() { + StructCapUserHeader header = new StructCapUserHeader( + OsConstants._LINUX_CAPABILITY_VERSION_3, 0); + StructCapUserData[] data; +diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java +index cbe070048811..9e78c3a8b16c 100644 +--- a/core/java/com/android/internal/os/ZygoteConnection.java ++++ b/core/java/com/android/internal/os/ZygoteConnection.java +@@ -29,6 +29,7 @@ import android.net.Credentials; + import android.net.LocalSocket; + import android.os.Parcel; + import android.os.Process; ++import android.os.SystemProperties; + import android.os.Trace; + import android.system.ErrnoException; + import android.system.Os; +@@ -247,7 +248,7 @@ class ZygoteConnection { + fdsToClose[1] = zygoteFd.getInt$(); + } + +- if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote ++ if (parsedArgs.mInvokeWith != null || SystemProperties.getBoolean("sys.spawn.exec", false) || parsedArgs.mStartChildZygote + || !multipleOK || peer.getUid() != Process.SYSTEM_UID) { + // Continue using old code for now. TODO: Handle these cases in the other path. + pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, +@@ -535,6 +536,13 @@ class ZygoteConnection { + throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); + } else { + if (!isZygote) { ++ if (SystemProperties.getBoolean("sys.spawn.exec", false)) { ++ ExecInit.execApplication(parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, ++ VMRuntime.getCurrentInstructionSet(), parsedArgs.mRemainingArgs); ++ ++ // Should not get here. ++ throw new IllegalStateException("ExecInit.execApplication unexpectedly returned"); ++ } + return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, + parsedArgs.mDisabledCompatChanges, + parsedArgs.mRemainingArgs, null /* classLoader */); diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-10.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-10.patch new file mode 100644 index 00000000..cd474d7a --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-10.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 11 Sep 2019 06:57:24 -0400 +Subject: [PATCH] disable preloading classloaders for exec spawning + +--- + core/java/com/android/internal/os/ZygoteInit.java | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 55c68981f919..699899e02f85 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -132,9 +132,11 @@ public class ZygoteInit { + preloadClasses(); + bootTimingsTraceLog.traceEnd(); // PreloadClasses + } +- bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders"); +- cacheNonBootClasspathClassLoaders(); +- bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders ++ if (fullPreload) { ++ bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders"); ++ cacheNonBootClasspathClassLoaders(); ++ bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders ++ } + if (fullPreload) { + bootTimingsTraceLog.traceBegin("PreloadResources"); + Resources.preloadResources(); diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-11.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-11.patch new file mode 100644 index 00000000..bcaca8b7 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-11.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 11 Sep 2019 06:58:51 -0400 +Subject: [PATCH] disable preloading HALs for exec spawning + +--- + core/java/com/android/internal/os/ZygoteInit.java | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 699899e02f85..da2f93d4539c 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -142,9 +142,11 @@ public class ZygoteInit { + Resources.preloadResources(); + bootTimingsTraceLog.traceEnd(); // PreloadResources + } +- Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); +- nativePreloadAppProcessHALs(); +- Trace.traceEnd(Trace.TRACE_TAG_DALVIK); ++ if (fullPreload) { ++ Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); ++ nativePreloadAppProcessHALs(); ++ Trace.traceEnd(Trace.TRACE_TAG_DALVIK); ++ } + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver"); + maybePreloadGraphicsDriver(); + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch new file mode 100644 index 00000000..ca4782f4 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-12.patch @@ -0,0 +1,289 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: anupritaisno1 +Date: Sat, 31 Oct 2020 00:26:09 +0200 +Subject: [PATCH] pass through runtime flags for exec spawning and implement + them in the child + +Signed-off-by: anupritaisno1 +--- + .../com/android/internal/os/ExecInit.java | 14 +- + core/java/com/android/internal/os/Zygote.java | 9 + + .../android/internal/os/ZygoteConnection.java | 2 +- + core/jni/com_android_internal_os_Zygote.cpp | 164 ++++++++++-------- + 4 files changed, 107 insertions(+), 82 deletions(-) + +diff --git a/core/java/com/android/internal/os/ExecInit.java b/core/java/com/android/internal/os/ExecInit.java +index 830e5b562a91..749c67abf389 100644 +--- a/core/java/com/android/internal/os/ExecInit.java ++++ b/core/java/com/android/internal/os/ExecInit.java +@@ -31,15 +31,20 @@ public class ExecInit { + // Parse our mandatory argument. + int targetSdkVersion = Integer.parseInt(args[0], 10); + ++ // Parse the runtime_flags. ++ int runtimeFlags = Integer.parseInt(args[1], 10); ++ + // Mimic system Zygote preloading. + ZygoteInit.preload(new TimingsTraceLog("ExecInitTiming", + Trace.TRACE_TAG_DALVIK), false); + + // Launch the application. +- String[] runtimeArgs = new String[args.length - 1]; +- System.arraycopy(args, 1, runtimeArgs, 0, runtimeArgs.length); ++ String[] runtimeArgs = new String[args.length - 2]; ++ System.arraycopy(args, 2, runtimeArgs, 0, runtimeArgs.length); + Runnable r = execInit(targetSdkVersion, runtimeArgs); + ++ Zygote.nativeHandleRuntimeFlags(runtimeFlags); ++ + r.run(); + } + +@@ -52,9 +57,9 @@ public class ExecInit { + * @param args Arguments for {@link RuntimeInit#main}. + */ + public static void execApplication(String niceName, int targetSdkVersion, +- String instructionSet, String[] args) { ++ String instructionSet, int runtimeFlags, String[] args) { + int niceArgs = niceName == null ? 0 : 1; +- int baseArgs = 5 + niceArgs; ++ int baseArgs = 6 + niceArgs; + String[] argv = new String[baseArgs + args.length]; + if (VMRuntime.is64BitInstructionSet(instructionSet)) { + argv[0] = "/system/bin/app_process64"; +@@ -68,6 +73,7 @@ public class ExecInit { + } + argv[3 + niceArgs] = "com.android.internal.os.ExecInit"; + argv[4 + niceArgs] = Integer.toString(targetSdkVersion); ++ argv[5 + niceArgs] = Integer.toString(runtimeFlags); + System.arraycopy(args, 0, argv, baseArgs, args.length); + + WrapperInit.preserveCapabilities(); +diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java +index cab84bb01f70..07691fcec545 100644 +--- a/core/java/com/android/internal/os/Zygote.java ++++ b/core/java/com/android/internal/os/Zygote.java +@@ -1497,4 +1497,13 @@ public final class Zygote { + } + return runtimeFlags; + } ++ ++ /** ++ * Used on GrapheneOS to set up runtime flags ++ * ++ * @param runtimeFlags flags to be passed to the native method ++ * ++ * @hide ++ */ ++ public static native void nativeHandleRuntimeFlags(int runtimeFlags); + } +diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java +index cc936ccefb91..eea7b1e57b37 100644 +--- a/core/java/com/android/internal/os/ZygoteConnection.java ++++ b/core/java/com/android/internal/os/ZygoteConnection.java +@@ -539,7 +539,7 @@ class ZygoteConnection { + if (SystemProperties.getBoolean("sys.spawn.exec", false) && + (parsedArgs.mRuntimeFlags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { + ExecInit.execApplication(parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, +- VMRuntime.getCurrentInstructionSet(), parsedArgs.mRemainingArgs); ++ VMRuntime.getCurrentInstructionSet(), parsedArgs.mRuntimeFlags, parsedArgs.mRemainingArgs); + + // Should not get here. + throw new IllegalStateException("ExecInit.execApplication unexpectedly returned"); +diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp +index 7c5885adb220..9fc92a480e1e 100644 +--- a/core/jni/com_android_internal_os_Zygote.cpp ++++ b/core/jni/com_android_internal_os_Zygote.cpp +@@ -1872,6 +1872,86 @@ static void BindMountStorageDirs(JNIEnv* env, jobjectArray pkg_data_info_list, + } + } + ++static void HandleRuntimeFlags(JNIEnv* env, jint& runtime_flags, const char* process_name, const char* nice_name_ptr) { ++ // Set process properties to enable debugging if required. ++ if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_PTRACE) != 0) { ++ EnableDebugger(); ++ // Don't pass unknown flag to the ART runtime. ++ runtime_flags &= ~RuntimeFlags::DEBUG_ENABLE_PTRACE; ++ } ++ if ((runtime_flags & RuntimeFlags::PROFILE_FROM_SHELL) != 0) { ++ // simpleperf needs the process to be dumpable to profile it. ++ if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { ++ ALOGE("prctl(PR_SET_DUMPABLE) failed: %s", strerror(errno)); ++ RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 1) failed"); ++ } ++ } ++ ++ HeapTaggingLevel heap_tagging_level; ++ switch (runtime_flags & RuntimeFlags::MEMORY_TAG_LEVEL_MASK) { ++ case RuntimeFlags::MEMORY_TAG_LEVEL_TBI: ++ heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI; ++ break; ++ case RuntimeFlags::MEMORY_TAG_LEVEL_ASYNC: ++ heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; ++ break; ++ case RuntimeFlags::MEMORY_TAG_LEVEL_SYNC: ++ heap_tagging_level = M_HEAP_TAGGING_LEVEL_SYNC; ++ break; ++ default: ++ heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; ++ break; ++ } ++ mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level); ++ ++ // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART ++ // runtime. ++ runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK; ++ ++ // Avoid heap zero initialization for applications without MTE. Zero init may ++ // cause app compat problems, use more memory, or reduce performance. While it ++ // would be nice to have them for apps, we will have to wait until they are ++ // proven out, have more efficient hardware, and/or apply them only to new ++ // applications. ++ if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED)) { ++ mallopt(M_BIONIC_ZERO_INIT, 0); ++ } ++ ++ // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART ++ // runtime. ++ runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED; ++ ++ android_mallopt_gwp_asan_options_t gwp_asan_options; ++ const char* kGwpAsanAppRecoverableSysprop = ++ "persist.device_config.memory_safety_native.gwp_asan_recoverable_apps"; ++ // The system server doesn't have its nice name set by the time SpecializeCommon is called. ++ gwp_asan_options.program_name = nice_name_ptr ?: process_name; ++ switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) { ++ default: ++ case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT: ++ gwp_asan_options.desire = GetBoolProperty(kGwpAsanAppRecoverableSysprop, true) ++ ? Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING ++ : Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; ++ android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); ++ break; ++ case RuntimeFlags::GWP_ASAN_LEVEL_NEVER: ++ gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; ++ android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); ++ break; ++ case RuntimeFlags::GWP_ASAN_LEVEL_ALWAYS: ++ gwp_asan_options.desire = Action::TURN_ON_FOR_APP; ++ android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); ++ break; ++ case RuntimeFlags::GWP_ASAN_LEVEL_LOTTERY: ++ gwp_asan_options.desire = Action::TURN_ON_WITH_SAMPLING; ++ android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); ++ break; ++ } ++ // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART ++ // runtime. ++ runtime_flags &= ~RuntimeFlags::GWP_ASAN_LEVEL_MASK; ++} ++ + // Utility routine to specialize a zygote child process. + static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, + jobjectArray rlimits, jlong permitted_capabilities, +@@ -2019,84 +2099,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, + } + } + +- // Set process properties to enable debugging if required. +- if ((runtime_flags & RuntimeFlags::DEBUG_ENABLE_PTRACE) != 0) { +- EnableDebugger(); +- // Don't pass unknown flag to the ART runtime. +- runtime_flags &= ~RuntimeFlags::DEBUG_ENABLE_PTRACE; +- } +- if ((runtime_flags & RuntimeFlags::PROFILE_FROM_SHELL) != 0) { +- // simpleperf needs the process to be dumpable to profile it. +- if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { +- ALOGE("prctl(PR_SET_DUMPABLE) failed: %s", strerror(errno)); +- RuntimeAbort(env, __LINE__, "prctl(PR_SET_DUMPABLE, 1) failed"); +- } +- } +- +- HeapTaggingLevel heap_tagging_level; +- switch (runtime_flags & RuntimeFlags::MEMORY_TAG_LEVEL_MASK) { +- case RuntimeFlags::MEMORY_TAG_LEVEL_TBI: +- heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI; +- break; +- case RuntimeFlags::MEMORY_TAG_LEVEL_ASYNC: +- heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; +- break; +- case RuntimeFlags::MEMORY_TAG_LEVEL_SYNC: +- heap_tagging_level = M_HEAP_TAGGING_LEVEL_SYNC; +- break; +- default: +- heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; +- break; +- } +- mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level); +- +- // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART +- // runtime. +- runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK; +- +- // Avoid heap zero initialization for applications without MTE. Zero init may +- // cause app compat problems, use more memory, or reduce performance. While it +- // would be nice to have them for apps, we will have to wait until they are +- // proven out, have more efficient hardware, and/or apply them only to new +- // applications. +- if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED)) { +- mallopt(M_BIONIC_ZERO_INIT, 0); +- } +- +- // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART +- // runtime. +- runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED; +- + const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr; +- android_mallopt_gwp_asan_options_t gwp_asan_options; +- const char* kGwpAsanAppRecoverableSysprop = +- "persist.device_config.memory_safety_native.gwp_asan_recoverable_apps"; +- // The system server doesn't have its nice name set by the time SpecializeCommon is called. +- gwp_asan_options.program_name = nice_name_ptr ?: process_name; +- switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) { +- default: +- case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT: +- gwp_asan_options.desire = GetBoolProperty(kGwpAsanAppRecoverableSysprop, true) +- ? Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING +- : Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; +- android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); +- break; +- case RuntimeFlags::GWP_ASAN_LEVEL_NEVER: +- gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; +- android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); +- break; +- case RuntimeFlags::GWP_ASAN_LEVEL_ALWAYS: +- gwp_asan_options.desire = Action::TURN_ON_FOR_APP; +- android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); +- break; +- case RuntimeFlags::GWP_ASAN_LEVEL_LOTTERY: +- gwp_asan_options.desire = Action::TURN_ON_WITH_SAMPLING; +- android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); +- break; +- } +- // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART +- // runtime. +- runtime_flags &= ~RuntimeFlags::GWP_ASAN_LEVEL_MASK; ++ ++ HandleRuntimeFlags(env, runtime_flags, process_name, nice_name_ptr); + + SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities, + fail_fn); +@@ -3004,6 +3009,10 @@ static void com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload(JNIEn + gPreloadFdsExtracted = true; + } + ++static void nativeHandleRuntimeFlagsWrapper(JNIEnv* env, jclass, jint runtime_flags) { ++ HandleRuntimeFlags(env, runtime_flags, nullptr, nullptr); ++} ++ + static const JNINativeMethod gMethods[] = { + {"nativeForkAndSpecialize", + "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/" +@@ -3056,6 +3065,7 @@ static const JNINativeMethod gMethods[] = { + (void*)com_android_internal_os_Zygote_nativeMarkOpenedFilesBeforePreload}, + {"nativeAllowFilesOpenedByPreload", "()V", + (void*)com_android_internal_os_Zygote_nativeAllowFilesOpenedByPreload}, ++ {"nativeHandleRuntimeFlags", "(I)V", (void*)nativeHandleRuntimeFlagsWrapper}, + }; + + int register_com_android_internal_os_Zygote(JNIEnv* env) { diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-13.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-13.patch new file mode 100644 index 00000000..fe367633 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-13.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Mon, 8 Aug 2022 18:42:19 +0300 +Subject: [PATCH] exec spawning: don't close the binder connection when the app + crashes + +When an unhandled exception occured, binder connections were closed with +IPCThreadState::stopProcess() before the invocation of java.lang.Thread#dispatchUncaughtException(). +By default, that method tries to report the crash via ActivityManager#handleApplicationCrash(), +which always failed due to the closed binder connection. +This meant that the crash dialog was never shown and additional crash handling was skipped. + +Zygote-based spawning never calls IPCThreadState::stopProcess(). +--- + cmds/app_process/app_main.cpp | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp +index 4e41f2c1ac35..9ce4bef5bb6c 100644 +--- a/cmds/app_process/app_main.cpp ++++ b/cmds/app_process/app_main.cpp +@@ -85,8 +85,10 @@ public: + AndroidRuntime* ar = AndroidRuntime::getRuntime(); + ar->callMain(mClassName, mClass, mArgs); + +- IPCThreadState::self()->stopProcess(); +- hardware::IPCThreadState::self()->stopProcess(); ++ if (mClassName != "com.android.internal.os.ExecInit") { ++ IPCThreadState::self()->stopProcess(); ++ hardware::IPCThreadState::self()->stopProcess(); ++ } + } + + virtual void onZygoteInit() diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-14.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-14.patch new file mode 100644 index 00000000..fbd98630 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-14.patch @@ -0,0 +1,125 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Thu, 30 Mar 2023 17:42:56 +0300 +Subject: [PATCH] exec spawning: support runtime resource overlays + +--- + core/java/android/app/IActivityManager.aidl | 2 ++ + .../android/content/res/AssetManager.java | 33 +++++++++++++++++-- + .../com/android/internal/os/ExecInit.java | 4 +++ + .../server/am/ActivityManagerService.java | 6 ++++ + 4 files changed, 43 insertions(+), 2 deletions(-) + +diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl +index 260e9859c72d..c3fdad0624d4 100644 +--- a/core/java/android/app/IActivityManager.aidl ++++ b/core/java/android/app/IActivityManager.aidl +@@ -950,4 +950,6 @@ interface IActivityManager { + */ + oneway void frozenBinderTransactionDetected(int debugPid, int code, int flags, int err); + int getBindingUidProcessState(int uid, in String callingPackage); ++ ++ String[] getSystemIdmapPaths(); + } +diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java +index 0399995540e7..3885f0fe3dd4 100644 +--- a/core/java/android/content/res/AssetManager.java ++++ b/core/java/android/content/res/AssetManager.java +@@ -26,6 +26,7 @@ import android.annotation.Nullable; + import android.annotation.StringRes; + import android.annotation.StyleRes; + import android.annotation.TestApi; ++import android.app.ActivityManager; + import android.compat.annotation.UnsupportedAppUsage; + import android.content.pm.ActivityInfo; + import android.content.res.Configuration.NativeConfig; +@@ -40,6 +41,7 @@ import android.util.TypedValue; + import com.android.internal.annotations.GuardedBy; + import com.android.internal.annotations.VisibleForTesting; + import com.android.internal.content.om.OverlayConfig; ++import com.android.internal.os.ExecInit; + + import java.io.FileDescriptor; + import java.io.FileNotFoundException; +@@ -235,6 +237,9 @@ public final class AssetManager implements AutoCloseable { + } + } + ++ /** @hide */ ++ public static volatile String[] systemIdmapPaths_; ++ + /** + * This must be called from Zygote so that system assets are shared by all applications. + * @hide +@@ -251,8 +256,32 @@ public final class AssetManager implements AutoCloseable { + final ArrayList apkAssets = new ArrayList<>(); + apkAssets.add(ApkAssets.loadFromPath(frameworkPath, ApkAssets.PROPERTY_SYSTEM)); + +- final String[] systemIdmapPaths = +- OverlayConfig.getZygoteInstance().createImmutableFrameworkIdmapsInZygote(); ++ // createImmutableFrameworkIdmapsInZygote() should be called only in zygote, it fails ++ // in regular processes and is unnecessary there. ++ // When it's called in zygote, overlay state is cached in /data/resource-cache/*@idmap ++ // files. These files are readable by regular app processes. ++ // ++ // When exec-based spawning in used, in-memory cache of assets is lost, and the spawned ++ // process is unable to recreate it, since it's not allowed to create idmaps. ++ // ++ // As a workaround, ask the ActivityManager to return paths of cached idmaps and use ++ // them directly. ActivityManager runs in system_server, which always uses zygote-based ++ // spawning. ++ ++ String[] systemIdmapPaths; ++ if (ExecInit.isExecSpawned) { ++ try { ++ systemIdmapPaths = ActivityManager.getService().getSystemIdmapPaths(); ++ Objects.requireNonNull(systemIdmapPaths); ++ } catch (Throwable t) { ++ Log.e(TAG, "unable to retrieve systemIdmapPaths", t); ++ systemIdmapPaths = new String[0]; ++ } ++ } else { ++ systemIdmapPaths = OverlayConfig.getZygoteInstance().createImmutableFrameworkIdmapsInZygote(); ++ systemIdmapPaths_ = systemIdmapPaths; ++ } ++ + for (String idmapPath : systemIdmapPaths) { + apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, ApkAssets.PROPERTY_SYSTEM)); + } +diff --git a/core/java/com/android/internal/os/ExecInit.java b/core/java/com/android/internal/os/ExecInit.java +index 749c67abf389..39f08b6a0f15 100644 +--- a/core/java/com/android/internal/os/ExecInit.java ++++ b/core/java/com/android/internal/os/ExecInit.java +@@ -84,6 +84,8 @@ public class ExecInit { + } + } + ++ public static boolean isExecSpawned; ++ + /** + * The main function called when an application is started with exec-based spawning. + * +@@ -99,6 +101,8 @@ public class ExecInit { + Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from exec"); + } + ++ isExecSpawned = true; ++ + // Check whether the first argument is a "-cp" in argv, and assume the next argument is the + // classpath. If found, create a PathClassLoader and use it for applicationInit. + ClassLoader classLoader = null; +diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java +index 0d95e615911d..ba6d5a027c9d 100644 +--- a/services/core/java/com/android/server/am/ActivityManagerService.java ++++ b/services/core/java/com/android/server/am/ActivityManagerService.java +@@ -20673,4 +20673,10 @@ public class ActivityManagerService extends IActivityManager.Stub + } + mOomAdjuster.mCachedAppOptimizer.binderError(debugPid, app, code, flags, err); + } ++ ++ @Override ++ public String[] getSystemIdmapPaths() { ++ // see comment in AssetManager#createSystemAssetsInZygoteLocked() ++ return android.content.res.AssetManager.systemIdmapPaths_; ++ } + } diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-15.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-15.patch new file mode 100644 index 00000000..cb83859c --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-15.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Tue, 9 Apr 2024 14:06:27 +0300 +Subject: [PATCH] exec spawning: add workaround for late init of ART + userfaultfd GC + +Chromium browser and its derivatives setup a seccomp syscall filter in their isolated processes, +which blocks creation of new userfaultfds. + +Since 14 QPR2, ART uses a new userfaultfd-based GC. + +When zygote-based process spawning is used, userfaultfd GC is initialized before any of app's code +is executed, i.e. before Chromium's seccomp syscall filter is installed. + +When exec spawning is used, userfaultfd GC initialization is delayed until first garbage collection. +Chromium's seccomp syscall filter is already installed at that point. + +This leads to crashes of isolated Chromium processes (both browser and WebView), with the following +log messages: + E cr_seccomp: ../../sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc:**CRASHING**:seccomp-bpf failure in syscall + E cr_seccomp: nr=0x11a arg1=0x80001 arg2=0xc arg3=0xffffffffffffffff arg4=0xc + +As a workaround, perform early initialization of ART userfaultfd GC in isolated processes by calling +System.gc() before executing app's code. On Pixel 8, this increases startup latency by around 4 to +10 milliseconds. +--- + core/java/com/android/internal/os/ExecInit.java | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/core/java/com/android/internal/os/ExecInit.java b/core/java/com/android/internal/os/ExecInit.java +index 39f08b6a0f15..b4b135cde18f 100644 +--- a/core/java/com/android/internal/os/ExecInit.java ++++ b/core/java/com/android/internal/os/ExecInit.java +@@ -1,5 +1,6 @@ + package com.android.internal.os; + ++import android.os.Process; + import android.os.Trace; + import android.system.ErrnoException; + import android.system.Os; +@@ -120,6 +121,9 @@ public class ExecInit { + + // Perform the same initialization that would happen after the Zygote forks. + Zygote.nativePreApplicationInit(); ++ if (Process.isIsolated()) { ++ System.gc(); ++ } + return RuntimeInit.applicationInit(targetSdkVersion, /*disabledCompatChanges*/ null, argv, classLoader); + } + } diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch new file mode 100644 index 00000000..74c0fb2a --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-2.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 21 May 2019 23:54:20 -0400 +Subject: [PATCH] disable exec spawning when using debugging options + +The debugging options are not yet supported probably, so disable exec +spawning when doing debugging. +--- + core/java/com/android/internal/os/ZygoteConnection.java | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java +index 9e78c3a8b16c..cc936ccefb91 100644 +--- a/core/java/com/android/internal/os/ZygoteConnection.java ++++ b/core/java/com/android/internal/os/ZygoteConnection.java +@@ -536,7 +536,8 @@ class ZygoteConnection { + throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); + } else { + if (!isZygote) { +- if (SystemProperties.getBoolean("sys.spawn.exec", false)) { ++ if (SystemProperties.getBoolean("sys.spawn.exec", false) && ++ (parsedArgs.mRuntimeFlags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { + ExecInit.execApplication(parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, + VMRuntime.getCurrentInstructionSet(), parsedArgs.mRemainingArgs); + diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-3.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-3.patch new file mode 100644 index 00000000..e5c6fa6b --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-3.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 14 May 2019 14:24:21 -0400 +Subject: [PATCH] add parameter for avoiding full preload with exec + +--- + core/java/com/android/internal/os/ExecInit.java | 2 +- + core/java/com/android/internal/os/ZygoteInit.java | 6 +++++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/core/java/com/android/internal/os/ExecInit.java b/core/java/com/android/internal/os/ExecInit.java +index 2adcab7fdbe6..830e5b562a91 100644 +--- a/core/java/com/android/internal/os/ExecInit.java ++++ b/core/java/com/android/internal/os/ExecInit.java +@@ -33,7 +33,7 @@ public class ExecInit { + + // Mimic system Zygote preloading. + ZygoteInit.preload(new TimingsTraceLog("ExecInitTiming", +- Trace.TRACE_TAG_DALVIK)); ++ Trace.TRACE_TAG_DALVIK), false); + + // Launch the application. + String[] runtimeArgs = new String[args.length - 1]; +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 7af196513cae..1675d41580d6 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -122,7 +122,7 @@ public class ZygoteInit { + */ + private static ClassLoader sCachedSystemServerClassLoader = null; + +- static void preload(TimingsTraceLog bootTimingsTraceLog) { ++ static void preload(TimingsTraceLog bootTimingsTraceLog, boolean fullPreload) { + Log.d(TAG, "begin preload"); + bootTimingsTraceLog.traceBegin("BeginPreload"); + beginPreload(); +@@ -154,6 +154,10 @@ public class ZygoteInit { + sPreloadComplete = true; + } + ++ static void preload(TimingsTraceLog bootTimingsTraceLog) { ++ preload(bootTimingsTraceLog, true); ++ } ++ + static void lazyPreload() { + Preconditions.checkState(!sPreloadComplete); + Log.i(TAG, "Lazily preloading resources."); diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-4.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-4.patch new file mode 100644 index 00000000..36b6aae1 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-4.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 11 Sep 2019 06:43:55 -0400 +Subject: [PATCH] pass through fullPreload to libcore + +--- + core/java/com/android/internal/os/ZygoteInit.java | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 1675d41580d6..87d393d97d14 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -125,7 +125,7 @@ public class ZygoteInit { + static void preload(TimingsTraceLog bootTimingsTraceLog, boolean fullPreload) { + Log.d(TAG, "begin preload"); + bootTimingsTraceLog.traceBegin("BeginPreload"); +- beginPreload(); ++ beginPreload(fullPreload); + bootTimingsTraceLog.traceEnd(); // BeginPreload + bootTimingsTraceLog.traceBegin("PreloadClasses"); + preloadClasses(); +@@ -147,7 +147,7 @@ public class ZygoteInit { + // Ask the WebViewFactory to do any initialization that must run in the zygote process, + // for memory sharing purposes. + WebViewFactory.prepareWebViewInZygote(); +- endPreload(); ++ endPreload(fullPreload); + warmUpJcaProviders(); + Log.d(TAG, "end preload"); + +@@ -165,14 +165,14 @@ public class ZygoteInit { + preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK)); + } + +- private static void beginPreload() { ++ private static void beginPreload(boolean fullPreload) { + Log.i(TAG, "Calling ZygoteHooks.beginPreload()"); + +- ZygoteHooks.onBeginPreload(); ++ ZygoteHooks.onBeginPreload(fullPreload); + } + +- private static void endPreload() { +- ZygoteHooks.onEndPreload(); ++ private static void endPreload(boolean fullPreload) { ++ ZygoteHooks.onEndPreload(fullPreload); + + Log.i(TAG, "Called ZygoteHooks.endPreload()"); + } diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-5.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-5.patch new file mode 100644 index 00000000..ad408e28 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-5.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 14 May 2019 14:28:27 -0400 +Subject: [PATCH] disable OpenGL preloading for exec spawning + +--- + core/java/com/android/internal/os/ZygoteInit.java | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 87d393d97d14..f30e17183fca 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -139,9 +139,11 @@ public class ZygoteInit { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); + nativePreloadAppProcessHALs(); + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); +- Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver"); +- maybePreloadGraphicsDriver(); +- Trace.traceEnd(Trace.TRACE_TAG_DALVIK); ++ if (fullPreload) { ++ Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver"); ++ maybePreloadGraphicsDriver(); ++ Trace.traceEnd(Trace.TRACE_TAG_DALVIK); ++ } + preloadSharedLibraries(); + preloadTextResources(); + // Ask the WebViewFactory to do any initialization that must run in the zygote process, diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-6.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-6.patch new file mode 100644 index 00000000..373ed18d --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-6.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 14 May 2019 14:28:52 -0400 +Subject: [PATCH] disable resource preloading for exec spawning + +--- + core/java/com/android/internal/os/ZygoteInit.java | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 87d393d97d14..5cd919d49014 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -133,9 +133,11 @@ public class ZygoteInit { + bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders"); + cacheNonBootClasspathClassLoaders(); + bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders +- bootTimingsTraceLog.traceBegin("PreloadResources"); +- Resources.preloadResources(); +- bootTimingsTraceLog.traceEnd(); // PreloadResources ++ if (fullPreload) { ++ bootTimingsTraceLog.traceBegin("PreloadResources"); ++ Resources.preloadResources(); ++ bootTimingsTraceLog.traceEnd(); // PreloadResources ++ } + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); + nativePreloadAppProcessHALs(); + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-7.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-7.patch new file mode 100644 index 00000000..20396189 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-7.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 14 May 2019 14:30:59 -0400 +Subject: [PATCH] disable class preloading for exec spawning + +--- + core/java/com/android/internal/os/ZygoteInit.java | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 5cd919d49014..21d412a3f9ec 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -127,9 +127,11 @@ public class ZygoteInit { + bootTimingsTraceLog.traceBegin("BeginPreload"); + beginPreload(fullPreload); + bootTimingsTraceLog.traceEnd(); // BeginPreload +- bootTimingsTraceLog.traceBegin("PreloadClasses"); +- preloadClasses(); +- bootTimingsTraceLog.traceEnd(); // PreloadClasses ++ if (fullPreload) { ++ bootTimingsTraceLog.traceBegin("PreloadClasses"); ++ preloadClasses(); ++ bootTimingsTraceLog.traceEnd(); // PreloadClasses ++ } + bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders"); + cacheNonBootClasspathClassLoaders(); + bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-8.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-8.patch new file mode 100644 index 00000000..4e8b7382 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-8.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 14 May 2019 14:31:29 -0400 +Subject: [PATCH] disable WebView reservation for exec spawning + +--- + core/java/com/android/internal/os/ZygoteInit.java | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 21d412a3f9ec..2ced52d06a17 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -148,9 +148,11 @@ public class ZygoteInit { + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + preloadSharedLibraries(); + preloadTextResources(); +- // Ask the WebViewFactory to do any initialization that must run in the zygote process, +- // for memory sharing purposes. +- WebViewFactory.prepareWebViewInZygote(); ++ if (fullPreload) { ++ // Ask the WebViewFactory to do any initialization that must run in the zygote process, ++ // for memory sharing purposes. ++ WebViewFactory.prepareWebViewInZygote(); ++ } + endPreload(fullPreload); + warmUpJcaProviders(); + Log.d(TAG, "end preload"); diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-9.patch b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-9.patch new file mode 100644 index 00000000..e1d7aa67 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0018-Exec_Based_Spawning-9.patch @@ -0,0 +1,57 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Tue, 14 May 2019 14:34:32 -0400 +Subject: [PATCH] disable JCA provider warm up for exec spawning + +--- + .../com/android/internal/os/ZygoteInit.java | 22 ++++++++++--------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java +index 2ced52d06a17..55c68981f919 100644 +--- a/core/java/com/android/internal/os/ZygoteInit.java ++++ b/core/java/com/android/internal/os/ZygoteInit.java +@@ -154,7 +154,7 @@ public class ZygoteInit { + WebViewFactory.prepareWebViewInZygote(); + } + endPreload(fullPreload); +- warmUpJcaProviders(); ++ warmUpJcaProviders(fullPreload); + Log.d(TAG, "end preload"); + + sPreloadComplete = true; +@@ -223,7 +223,7 @@ public class ZygoteInit { + * By doing it here we avoid that each app does it when requesting a service from the provider + * for the first time. + */ +- private static void warmUpJcaProviders() { ++ private static void warmUpJcaProviders(boolean fullPreload) { + long startTime = SystemClock.uptimeMillis(); + Trace.traceBegin( + Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider"); +@@ -233,15 +233,17 @@ public class ZygoteInit { + + (SystemClock.uptimeMillis() - startTime) + "ms."); + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + +- startTime = SystemClock.uptimeMillis(); +- Trace.traceBegin( +- Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers"); +- for (Provider p : Security.getProviders()) { +- p.warmUpServiceProvision(); ++ if (fullPreload) { ++ startTime = SystemClock.uptimeMillis(); ++ Trace.traceBegin( ++ Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers"); ++ for (Provider p : Security.getProviders()) { ++ p.warmUpServiceProvision(); ++ } ++ Log.i(TAG, "Warmed up JCA providers in " ++ + (SystemClock.uptimeMillis() - startTime) + "ms."); ++ Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } +- Log.i(TAG, "Warmed up JCA providers in " +- + (SystemClock.uptimeMillis() - startTime) + "ms."); +- Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } + + private static boolean isExperimentEnabled(String experiment) { diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0020-Location_Indicators.patch b/Patches/LineageOS-21.0/android_frameworks_base/0020-Location_Indicators.patch new file mode 100644 index 00000000..c72d370a --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0020-Location_Indicators.patch @@ -0,0 +1,48 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Danny Lin +Date: Tue, 12 Oct 2021 01:03:59 +0300 +Subject: [PATCH] SystemUI: Use new privacy indicators for location + +Android has had location indicators for a while, but let's use the new +privacy indicator infrastructure for displaying them. This makes them +integrate better with the new camera and microphone indicators. + +Change-Id: Ie457bb2dad17bddbf9dc3a818e3ec586023ce918 +--- + core/java/android/permission/PermissionUsageHelper.java | 2 +- + .../src/com/android/systemui/privacy/PrivacyItemController.kt | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java +index 1f798baf1bd6..20502cdc81c3 100644 +--- a/core/java/android/permission/PermissionUsageHelper.java ++++ b/core/java/android/permission/PermissionUsageHelper.java +@@ -108,7 +108,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis + + private static boolean shouldShowLocationIndicator() { + return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, +- PROPERTY_LOCATION_INDICATORS_ENABLED, false); ++ PROPERTY_LOCATION_INDICATORS_ENABLED, true); + } + + private static long getRecentThreshold(Long now) { +diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +index eb8ef9bf3e50..4b406f76300a 100644 +--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt ++++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +@@ -63,7 +63,7 @@ class PrivacyItemController @Inject constructor( + val micCameraAvailable + get() = privacyConfig.micCameraAvailable + val locationAvailable +- get() = privacyConfig.locationAvailable ++ get() = true + val allIndicatorsAvailable + get() = micCameraAvailable && locationAvailable && privacyConfig.mediaProjectionAvailable + +@@ -274,4 +274,4 @@ class PrivacyItemController @Inject constructor( + listeningCanceller = delegate.executeDelayed({ setListeningState() }, 0L) + } + } +-} +\ No newline at end of file ++} diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0022-Ignore_StatementService_ANR.patch b/Patches/LineageOS-21.0/android_frameworks_base/0022-Ignore_StatementService_ANR.patch new file mode 100644 index 00000000..49cfca1d --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0022-Ignore_StatementService_ANR.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 20 Oct 2021 19:40:42 -0400 +Subject: [PATCH] core/config: [temporary] don't report statementservice + crashes + +There's a known issue in AOSP 12 caused by it creating overly large +intents for the work manager. It's not caused by anything done by end +users and they can't work around it so avoid reporting it to them since +they get a message each time it tries again. +--- + core/res/res/values/config.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml +index 3bc33bac37bc..be714871ad0f 100644 +--- a/core/res/res/values/config.xml ++++ b/core/res/res/values/config.xml +@@ -4211,7 +4211,7 @@ + + +- ++ com.android.statementservice + + diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0024-Burnin_Protection.patch b/Patches/LineageOS-21.0/android_frameworks_base/0024-Burnin_Protection.patch new file mode 100644 index 00000000..098bbf62 --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0024-Burnin_Protection.patch @@ -0,0 +1,317 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Park Ju Hyung +Date: Sun, 15 Jan 2017 03:33:04 +0900 +Subject: [PATCH] SystemUI: add burnIn protection + +Devices with AMOLED display suffer from +status-bar's notification items and nagivation bar's software keys +causing permanent burn-ins when used long-term. + +Moving all items in the area +both horizontally and vertically workarounds this problem. + +jrizzoli: integrate with runtime cmsdk preference + +Linux4: Removed toggle from settings - the burnIn protection is always +enabled if the corresponding AOSP overlay is set to true +Updated for T + +Change-Id: I35b04d1edff86a556adb3ad349569e5d82653f16 +Signed-off-by: Park Ju Hyung +Signed-off-by: Alex Naidis +Signed-off-by: Thecrazyskull +Signed-off-by: Joey Rizzoli +--- + .../SystemUI/res/values/lineage_dimens.xml | 3 + + .../navigationbar/NavigationBarView.java | 26 +++++ + .../statusbar/phone/CentralSurfacesImpl.java | 14 +++ + .../statusbar/phone/PhoneStatusBarView.java | 27 +++++ + .../policy/BurnInProtectionController.java | 105 ++++++++++++++++++ + 5 files changed, 175 insertions(+) + create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/policy/BurnInProtectionController.java + +diff --git a/packages/SystemUI/res/values/lineage_dimens.xml b/packages/SystemUI/res/values/lineage_dimens.xml +index ca6e7db4c5b1..c0acba502cc2 100644 +--- a/packages/SystemUI/res/values/lineage_dimens.xml ++++ b/packages/SystemUI/res/values/lineage_dimens.xml +@@ -24,4 +24,7 @@ + + + 48dp ++ ++ 3dp ++ 1dp + +diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +index aae1aa9a6698..90bcd525b32f 100644 +--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java ++++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java +@@ -159,6 +159,13 @@ public class NavigationBarView extends FrameLayout { + private FloatingRotationButton mFloatingRotationButton; + private RotationButtonController mRotationButtonController; + ++ private int mBasePaddingBottom; ++ private int mBasePaddingLeft; ++ private int mBasePaddingRight; ++ private int mBasePaddingTop; ++ ++ private ViewGroup mNavigationBarContents; ++ + /** + * Helper that is responsible for showing the right toast when a disallowed activity operation + * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in +@@ -889,12 +896,31 @@ public class NavigationBarView extends FrameLayout { + mContextualButtonGroup.setButtonVisibility(R.id.accessibility_button, visible); + } + ++ public void shiftNavigationBarItems(int horizontalShift, int verticalShift) { ++ if (mNavigationBarContents == null) { ++ return; ++ } ++ ++ mNavigationBarContents.setPaddingRelative(mBasePaddingLeft + horizontalShift, ++ mBasePaddingTop + verticalShift, ++ mBasePaddingRight + horizontalShift, ++ mBasePaddingBottom - verticalShift); ++ invalidate(); ++ } ++ + @Override + public void onFinishInflate() { + super.onFinishInflate(); + mNavigationInflaterView = findViewById(R.id.navigation_inflater); + mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers); + ++ ++ mNavigationBarContents = (ViewGroup) findViewById(R.id.nav_buttons); ++ ++ mBasePaddingLeft = mNavigationBarContents.getPaddingStart(); ++ mBasePaddingTop = mNavigationBarContents.getPaddingTop(); ++ mBasePaddingRight = mNavigationBarContents.getPaddingEnd(); ++ mBasePaddingBottom = mNavigationBarContents.getPaddingBottom(); + updateOrientationViews(); + reloadNavIcons(); + } +diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +index 73b95114b005..b943444676f6 100644 +--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java ++++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +@@ -216,6 +216,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll + import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule; + import com.android.systemui.statusbar.policy.BatteryController; + import com.android.systemui.statusbar.policy.BrightnessMirrorController; ++import com.android.systemui.statusbar.policy.BurnInProtectionController; + import com.android.systemui.statusbar.policy.ConfigurationController; + import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; + import com.android.systemui.statusbar.policy.DeviceProvisionedController; +@@ -379,6 +380,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { + private BiometricUnlockController mBiometricUnlockController; + private final LightBarController mLightBarController; + private final AutoHideController mAutoHideController; ++ private BurnInProtectionController mBurnInProtectionController; + + private final Point mCurrentDisplaySize = new Point(); + +@@ -1223,6 +1225,12 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { + mShadeSurface.updateExpansionAndVisibility(); + setBouncerShowingForStatusBarComponents(mBouncerShowing); + checkBarModes(); ++ ++ if (mContext.getResources().getBoolean( ++ com.android.internal.R.bool.config_enableBurnInProtection)) { ++ mBurnInProtectionController = new BurnInProtectionController(mContext, ++ this, mStatusBarView); ++ } + }); + mStatusBarInitializer.initializeStatusBar(); + +@@ -2494,6 +2502,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { + + updateNotificationPanelTouchState(); + getNotificationShadeWindowViewController().cancelCurrentTouch(); ++ if (mBurnInProtectionController != null) { ++ mBurnInProtectionController.stopShiftTimer(true); ++ } + if (mLaunchCameraOnFinishedGoingToSleep) { + mLaunchCameraOnFinishedGoingToSleep = false; + +@@ -2659,6 +2670,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { + } + } + updateScrimController(); ++ if (mBurnInProtectionController != null) { ++ mBurnInProtectionController.startShiftTimer(true); ++ } + } + }; + +diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +index 1207388b4389..3015dfa7768f 100644 +--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java ++++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone; + + import android.annotation.Nullable; + import android.content.Context; ++import android.content.res.Resources; + import android.content.res.Configuration; + import android.graphics.Insets; + import android.graphics.Rect; +@@ -65,6 +66,13 @@ public class PhoneStatusBarView extends FrameLayout implements Callbacks { + private final CommandQueue mCommandQueue; + private final StatusBarContentInsetsProvider mContentInsetsProvider; + ++ private int mBasePaddingBottom; ++ private int mBasePaddingLeft; ++ private int mBasePaddingRight; ++ private int mBasePaddingTop; ++ ++ private ViewGroup mStatusBarContents; ++ + private DarkReceiver mBattery; + private ClockController mClockController; + private int mRotationOrientation = -1; +@@ -143,6 +151,18 @@ public class PhoneStatusBarView extends FrameLayout implements Callbacks { + StatusBarUserChipViewBinder.bind(container, viewModel); + } + ++ public void shiftStatusBarItems(int horizontalShift, int verticalShift) { ++ if (mStatusBarContents == null) { ++ return; ++ } ++ ++ mStatusBarContents.setPaddingRelative(mBasePaddingLeft + horizontalShift, ++ mBasePaddingTop + verticalShift, ++ mBasePaddingRight + horizontalShift, ++ mBasePaddingBottom - verticalShift); ++ invalidate(); ++ } ++ + @Override + public void onFinishInflate() { + super.onFinishInflate(); +@@ -150,6 +170,13 @@ public class PhoneStatusBarView extends FrameLayout implements Callbacks { + mClockController = new ClockController(getContext(), this); + mCutoutSpace = findViewById(R.id.cutout_space_view); + ++ mStatusBarContents = (ViewGroup) findViewById(R.id.status_bar_contents); ++ ++ mBasePaddingLeft = mStatusBarContents.getPaddingStart(); ++ mBasePaddingTop = mStatusBarContents.getPaddingTop(); ++ mBasePaddingRight = mStatusBarContents.getPaddingEnd(); ++ mBasePaddingBottom = mStatusBarContents.getPaddingBottom(); ++ + updateResources(); + } + +diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BurnInProtectionController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BurnInProtectionController.java +new file mode 100644 +index 000000000000..864d86ffd6a3 +--- /dev/null ++++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BurnInProtectionController.java +@@ -0,0 +1,105 @@ ++/* ++ * Copyright 2017 Paranoid Android ++ * Copyright 2020 The LineageOS 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.systemui.statusbar.policy; ++ ++import android.content.Context; ++import android.content.res.Resources; ++import android.os.Handler; ++import android.os.Looper; ++import android.util.Log; ++ ++import com.android.systemui.R; ++import com.android.systemui.navigationbar.NavigationBarView; ++import com.android.systemui.statusbar.phone.PhoneStatusBarView; ++import com.android.systemui.statusbar.phone.CentralSurfacesImpl; ++ ++public class BurnInProtectionController { ++ private static final String TAG = "BurnInProtectionController"; ++ private static final boolean DEBUG = false; ++ private static final long INTERVAL = 60000; // Milliseconds ++ ++ private int mHorizontalShift = 0; ++ private int mVerticalShift = 0; ++ private int mHorizontalDirection = 1; ++ private int mVerticalDirection = 1; ++ private int mNavigationBarHorizontalMaxShift; ++ private int mNavigationBarVerticalMaxShift; ++ private int mHorizontalMaxShift; ++ private int mVerticalMaxShift; ++ private long mShiftInterval; ++ ++ private final Handler mHandler = new Handler(); ++ private final Runnable mRunnable = () -> { ++ shiftItems(); ++ mHandler.postDelayed(this.mRunnable, INTERVAL); ++ }; ++ ++ private PhoneStatusBarView mPhoneStatusBarView; ++ private CentralSurfacesImpl mStatusBar; ++ ++ private Context mContext; ++ ++ public BurnInProtectionController(Context context, CentralSurfacesImpl statusBar, ++ PhoneStatusBarView phoneStatusBarView) { ++ mContext = context; ++ ++ mPhoneStatusBarView = phoneStatusBarView; ++ mStatusBar = statusBar; ++ ++ mHorizontalMaxShift = mContext.getResources() ++ .getDimensionPixelSize(R.dimen.burnin_protection_horizontal_shift); ++ // total of ((vertical_max_shift - 1) * 2) pixels can be moved ++ mVerticalMaxShift = mContext.getResources() ++ .getDimensionPixelSize(R.dimen.burnin_protection_vertical_shift) - 1; ++ } ++ ++ public void startShiftTimer(boolean enabled) { ++ if (!enabled) return; ++ mHandler.removeCallbacks(mRunnable); ++ mHandler.postDelayed(mRunnable, INTERVAL); ++ if (DEBUG) Log.d(TAG, "Started shift timer"); ++ } ++ ++ public void stopShiftTimer(boolean enabled) { ++ if (!enabled) return; ++ mHandler.removeCallbacks(mRunnable); ++ if (DEBUG) Log.d(TAG, "Canceled shift timer"); ++ } ++ ++ private void shiftItems() { ++ mHorizontalShift += mHorizontalDirection; ++ if ((mHorizontalShift >= mHorizontalMaxShift) || ++ (mHorizontalShift <= -mHorizontalMaxShift)) { ++ mHorizontalDirection *= -1; ++ } ++ ++ mVerticalShift += mVerticalDirection; ++ if ((mVerticalShift >= mVerticalMaxShift) || ++ (mVerticalShift <= -mVerticalMaxShift)) { ++ mVerticalDirection *= -1; ++ } ++ ++ mPhoneStatusBarView.shiftStatusBarItems(mHorizontalShift, mVerticalShift); ++ NavigationBarView navigationBarView = mStatusBar.getNavigationBarView(); ++ ++ if (navigationBarView != null) { ++ navigationBarView.shiftNavigationBarItems(mHorizontalShift, mVerticalShift); ++ } ++ if (DEBUG) Log.d(TAG, "Shifting items\u2026"); ++ } ++} diff --git a/Patches/LineageOS-21.0/android_frameworks_base/0026-Crash_Details.patch b/Patches/LineageOS-21.0/android_frameworks_base/0026-Crash_Details.patch new file mode 100644 index 00000000..f526f42c --- /dev/null +++ b/Patches/LineageOS-21.0/android_frameworks_base/0026-Crash_Details.patch @@ -0,0 +1,194 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Dmitry Muhomor +Date: Mon, 8 Aug 2022 19:03:37 +0300 +Subject: [PATCH] add an option to show the details of an application error to + the user + +Adds a "Show details" item to crash and ANR (app not responding) dialogs that takes the user to a +SystemUI activity which shows the error details and allows to copy them to the clipboard or to +export them via the standard sharing UI. +--- + .../android/app/ApplicationErrorReport.java | 29 +++++++++++++++++-- + core/res/res/layout/app_anr_dialog.xml | 4 +-- + core/res/res/layout/app_error_dialog.xml | 4 +-- + core/res/res/values/strings.xml | 2 ++ + core/res/res/values/symbols.xml | 3 ++ + .../java/com/android/server/am/AppErrors.java | 1 + + 6 files changed, 37 insertions(+), 6 deletions(-) + +diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java +index 9cea5e8ef4cf..a8f51104d0fa 100644 +--- a/core/java/android/app/ApplicationErrorReport.java ++++ b/core/java/android/app/ApplicationErrorReport.java +@@ -25,6 +25,8 @@ import android.content.pm.ResolveInfo; + import android.os.Binder; + import android.os.Parcel; + import android.os.Parcelable; ++import android.os.Process; ++import android.os.SystemClock; + import android.os.SystemProperties; + import android.provider.Settings; + import android.util.Printer; +@@ -98,6 +100,9 @@ public class ApplicationErrorReport implements Parcelable { + */ + public String packageName; + ++ /** @hide */ ++ public long packageVersion; ++ + /** + * Package name of the application which installed the application this + * report pertains to. +@@ -162,13 +167,19 @@ public class ApplicationErrorReport implements Parcelable { + String packageName, int appFlags) { + // check if error reporting is enabled in secure settings + int enabled = Settings.Global.getInt(context.getContentResolver(), +- Settings.Global.SEND_ACTION_APP_ERROR, 0); ++ Settings.Global.SEND_ACTION_APP_ERROR, 1); + if (enabled == 0) { + return null; + } + + PackageManager pm = context.getPackageManager(); + ++ ComponentName logViewerApp = getErrorReportReceiver(pm, packageName, ++ android.ext.LogViewerApp.getPackageName()); ++ if (logViewerApp != null) { ++ return logViewerApp; ++ } ++ + // look for receiver in the installer package + String candidate = null; + ComponentName result = null; +@@ -233,6 +244,7 @@ public class ApplicationErrorReport implements Parcelable { + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(type); + dest.writeString(packageName); ++ dest.writeLong(packageVersion); + dest.writeString(installerPackageName); + dest.writeString(processName); + dest.writeLong(time); +@@ -260,6 +272,7 @@ public class ApplicationErrorReport implements Parcelable { + public void readFromParcel(Parcel in) { + type = in.readInt(); + packageName = in.readString(); ++ packageVersion = in.readLong(); + installerPackageName = in.readString(); + processName = in.readString(); + time = in.readLong(); +@@ -345,6 +358,11 @@ public class ApplicationErrorReport implements Parcelable { + */ + public String crashTag; + ++ /** @hide */ ++ public long processUptimeMs; ++ /** @hide */ ++ public long processStartupLatencyMs; ++ + /** + * Create an uninitialized instance of CrashInfo. + */ +@@ -398,6 +416,9 @@ public class ApplicationErrorReport implements Parcelable { + } + + exceptionMessage = sanitizeString(exceptionMessage); ++ ++ processUptimeMs = SystemClock.elapsedRealtime() - Process.getStartElapsedRealtime(); ++ processStartupLatencyMs = Process.getStartElapsedRealtime() - Process.getStartRequestedElapsedRealtime(); + } + + /** {@hide} */ +@@ -439,6 +460,8 @@ public class ApplicationErrorReport implements Parcelable { + throwLineNumber = in.readInt(); + stackTrace = in.readString(); + crashTag = in.readString(); ++ processUptimeMs = in.readLong(); ++ processStartupLatencyMs = in.readLong(); + } + + /** +@@ -455,6 +478,8 @@ public class ApplicationErrorReport implements Parcelable { + dest.writeInt(throwLineNumber); + dest.writeString(stackTrace); + dest.writeString(crashTag); ++ dest.writeLong(processUptimeMs); ++ dest.writeLong(processStartupLatencyMs); + int total = dest.dataPosition()-start; + if (Binder.CHECK_PARCEL_SIZE && total > 20*1024) { + Slog.d("Error", "ERR: exHandler=" + exceptionHandlerClassName); +@@ -704,7 +729,7 @@ public class ApplicationErrorReport implements Parcelable { + */ + public void dump(Printer pw, String prefix) { + pw.println(prefix + "type: " + type); +- pw.println(prefix + "packageName: " + packageName); ++ pw.println(prefix + "packageName: " + packageName + ":" + packageVersion); + pw.println(prefix + "installerPackageName: " + installerPackageName); + pw.println(prefix + "processName: " + processName); + pw.println(prefix + "time: " + time); +diff --git a/core/res/res/layout/app_anr_dialog.xml b/core/res/res/layout/app_anr_dialog.xml +index 5ad0f4c0f6cc..ad3a2d2991de 100644 +--- a/core/res/res/layout/app_anr_dialog.xml ++++ b/core/res/res/layout/app_anr_dialog.xml +@@ -41,8 +41,8 @@ + android:id="@+id/aerr_report" + android:layout_width="match_parent" + android:layout_height="wrap_content" +- android:text="@string/aerr_report" +- android:drawableStart="@drawable/ic_feedback" ++ android:text="@string/aerr_show_details" ++ android:drawableStart="@drawable/ic_info_outline_24" + style="@style/aerr_list_item" /> + + +diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml +index c3b149a1e295..a47b82018377 100644 +--- a/core/res/res/layout/app_error_dialog.xml ++++ b/core/res/res/layout/app_error_dialog.xml +@@ -52,8 +52,8 @@ + android:id="@+id/aerr_report" + android:layout_width="match_parent" + android:layout_height="wrap_content" +- android:text="@string/aerr_report" +- android:drawableStart="@drawable/ic_feedback" ++ android:text="@string/aerr_show_details" ++ android:drawableStart="@drawable/ic_info_outline_24" + style="@style/aerr_list_item" /> + +