summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author John Wu <topjohnwu@google.com> 2022-09-14 16:20:32 +0000
committer John Wu <topjohnwu@google.com> 2022-09-14 20:57:17 +0000
commit03ac3eb0fc36be97f301ac60e85e1bb7ca52fa12 (patch)
treecc00296dfcbf529cc2c9025efdd958be5e79f693
parent81b3f56cab037577dfa1c53024145a4385df5ca1 (diff)
Enforce files loaded in DexFile to be read-only
Executables dynamically downloaded can be unexpectedly manipulated, causing code injection. For apps targeting U+, we'd like to introduce an enforcement in the platform to make sure files are marked as read-only. Test: m Bug: 218865702 Change-Id: Id635fbc79fc9a345781081b71f02a580267be655
-rw-r--r--runtime/native/dalvik_system_DexFile.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index d714206241..306198f311 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -57,6 +57,9 @@
namespace art {
+// Should be the same as dalvik.system.DexFile.ENFORCE_READ_ONLY_JAVA_DCL
+static constexpr uint64_t kEnforceReadOnlyJavaDcl = 218865702;
+
using android::base::StringPrintf;
static bool ConvertJavaArrayToDexFiles(
@@ -316,6 +319,32 @@ static jobject DexFile_openDexFileNative(JNIEnv* env,
return nullptr;
}
+#ifdef __ANDROID__
+ const int uid = getuid();
+ // The following UIDs are exempted:
+ // * Root (0): root processes always have write access to files.
+ // * System (1000): /data/app/**.apk are owned by AID_SYSTEM;
+ // loading installed APKs in system_server is allowed.
+ // * Shell (2000): directly calling dalvikvm/app_process in ADB shell
+ // to run JARs with CLI is allowed.
+ if (uid != 0 && uid != 1000 && uid != 2000) {
+ Runtime* const runtime = Runtime::Current();
+ CompatFramework& compatFramework = runtime->GetCompatFramework();
+ if (compatFramework.IsChangeEnabled(kEnforceReadOnlyJavaDcl)) {
+ if (access(sourceName.c_str(), W_OK) == 0) {
+ LOG(ERROR) << "Attempt to load writable dex file: " << sourceName.c_str();
+ ScopedLocalRef<jclass> se(env, env->FindClass("java/lang/SecurityException"));
+ std::string message(
+ StringPrintf("Writable dex file '%s' is not allowed.", sourceName.c_str()));
+ env->ThrowNew(se.get(), message.c_str());
+ return nullptr;
+ }
+ }
+ }
+#else
+ (void) kEnforceReadOnlyJavaDcl;
+#endif
+
std::vector<std::string> error_msgs;
const OatFile* oat_file = nullptr;
std::vector<std::unique_ptr<const DexFile>> dex_files =