summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-12-02 06:55:18 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-12-02 06:55:18 +0000
commit7f6716912c43be9707a5f8ddc1033408d65b95c6 (patch)
tree7cf84e5fce02f80c52d0acc1eb2c1713152d2585
parent366a90d065873c89aca456471fe527f01f058578 (diff)
parent7e2a46ab9b8c31bd51eccd2f5ba296a27aff9133 (diff)
downloadart-android13-mainline-extservices-release.tar.gz
Snap for 9361261 from 7e2a46ab9b8c31bd51eccd2f5ba296a27aff9133 to mainline-extservices-releaseaml_ext_331814220aml_ext_331412000android13-mainline-extservices-release
Change-Id: I5c4b5e1b061b1b967289d82f68395ee24428c9cf
-rw-r--r--libnativeloader/library_namespaces.cpp24
-rw-r--r--libnativeloader/test/Android.bp13
-rw-r--r--libnativeloader/test/loadlibrarytest_data_app_manifest.xml1
-rw-r--r--libnativeloader/test/loadlibrarytest_product_app_manifest.xml1
-rw-r--r--libnativeloader/test/loadlibrarytest_system_app_manifest.xml1
-rw-r--r--libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml1
-rw-r--r--libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml1
-rw-r--r--libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml1
-rw-r--r--libnativeloader/test/src/android/test/app/DataAppTest.java15
-rw-r--r--libnativeloader/test/src/android/test/app/ProductAppTest.java15
-rw-r--r--libnativeloader/test/src/android/test/app/SystemAppTest.java11
-rw-r--r--libnativeloader/test/src/android/test/app/VendorAppTest.java15
-rw-r--r--libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java16
-rw-r--r--libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java21
-rw-r--r--runtime/exec_utils.cc8
-rw-r--r--runtime/exec_utils_test.cc10
16 files changed, 38 insertions, 116 deletions
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index f3c93a0ecc..bcc19aaa41 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -85,18 +85,15 @@ constexpr const char* kVendorLibPath = "/vendor/" LIB;
// below, because they can't be two separate directories - either one has to be
// a symlink to the other.
constexpr const char* kProductLibPath = "/product/" LIB ":/system/product/" LIB;
-constexpr const char* kSystemLibPath = "/system/" LIB ":/system_ext/" LIB;
const std::regex kVendorDexPathRegex("(^|:)(/system)?/vendor/");
const std::regex kProductDexPathRegex("(^|:)(/system)?/product/");
-const std::regex kSystemDexPathRegex("(^|:)/system(_ext)?/"); // MUST be tested last.
-// Define origin partition of APK
+// Define origin of APK if it is from vendor partition or product partition
using ApkOrigin = enum {
APK_ORIGIN_DEFAULT = 0,
APK_ORIGIN_VENDOR = 1, // Includes both /vendor and /system/vendor
APK_ORIGIN_PRODUCT = 2, // Includes both /product and /system/product
- APK_ORIGIN_SYSTEM = 3, // Includes both /system and /system_ext but not /system/{vendor,product}
};
jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) {
@@ -119,9 +116,6 @@ ApkOrigin GetApkOriginFromDexPath(const std::string& dex_path) {
apk_origin = APK_ORIGIN_PRODUCT;
}
- if (apk_origin == APK_ORIGIN_DEFAULT && std::regex_search(dex_path, kSystemDexPathRegex)) {
- apk_origin = APK_ORIGIN_SYSTEM;
- }
return apk_origin;
}
@@ -243,18 +237,7 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t
const char* apk_origin_msg = "other apk"; // Only for debug logging.
if (!is_shared) {
- if (apk_origin == APK_ORIGIN_SYSTEM) {
- // System apps commonly get shared namespaces and hence don't need this.
- // In practice it's necessary for shared system libraries (i.e. JARs
- // rather than actual APKs) that are loaded by ordinary apps which don't
- // get shared namespaces.
- apk_origin_msg = "system apk";
-
- // Give access to all libraries in the system and system_ext partitions
- // (they can freely access each other's private APIs).
- library_path = library_path + ":" + kSystemLibPath;
- permitted_path = permitted_path + ":" + kSystemLibPath;
- } else if (apk_origin == APK_ORIGIN_VENDOR) {
+ if (apk_origin == APK_ORIGIN_VENDOR) {
unbundled_app_origin = APK_ORIGIN_VENDOR;
apk_origin_msg = "unbundled vendor apk";
@@ -308,7 +291,8 @@ Result<NativeLoaderNamespace*> LibraryNamespaces::Create(JNIEnv* env, uint32_t t
// they are to other apps, including those in system, system_ext, and
// product partitions. The reason is that when GSI is used, the system
// partition may get replaced, and then vendor apps may fail. It's fine for
- // product apps, because that partition isn't mounted in GSI tests.
+ // product (and system_ext) apps, because those partitions aren't mounted in
+ // GSI tests.
auto libs =
filter_public_libraries(target_sdk_version, uses_libraries, extended_public_libraries());
if (!libs.empty()) {
diff --git a/libnativeloader/test/Android.bp b/libnativeloader/test/Android.bp
index 1d3a07a5f3..b43a02ce4a 100644
--- a/libnativeloader/test/Android.bp
+++ b/libnativeloader/test/Android.bp
@@ -55,13 +55,6 @@ java_library {
srcs: ["src/android/test/systemsharedlib/SystemSharedLib.java"],
}
-// Test fixture that represents a shared library in /system_ext/framework.
-java_library {
- name: "libnativeloader_system_ext_shared_lib",
- installable: true,
- srcs: ["src/android/test/systemextsharedlib/SystemExtSharedLib.java"],
-}
-
java_defaults {
name: "loadlibrarytest_app_defaults",
defaults: ["art_module_source_build_java_defaults"],
@@ -70,10 +63,7 @@ java_defaults {
"androidx.test.rules",
"loadlibrarytest_test_utils",
],
- libs: [
- "libnativeloader_system_shared_lib",
- "libnativeloader_system_ext_shared_lib",
- ],
+ libs: ["libnativeloader_system_shared_lib"],
}
android_test_helper_app {
@@ -135,7 +125,6 @@ java_test_host {
data: [
":library_container_app",
":libnativeloader_system_shared_lib",
- ":libnativeloader_system_ext_shared_lib",
":loadlibrarytest_system_priv_app",
":loadlibrarytest_system_app",
":loadlibrarytest_system_ext_app",
diff --git a/libnativeloader/test/loadlibrarytest_data_app_manifest.xml b/libnativeloader/test/loadlibrarytest_data_app_manifest.xml
index 2af0af417e..9b663e6d94 100644
--- a/libnativeloader/test/loadlibrarytest_data_app_manifest.xml
+++ b/libnativeloader/test/loadlibrarytest_data_app_manifest.xml
@@ -21,7 +21,6 @@
android:targetPackage="android.test.app.data" />
<application>
<uses-library android:name="android.test.systemsharedlib" />
- <uses-library android:name="android.test.systemextsharedlib" />
<uses-native-library android:required="false" android:name="libfoo.oem1.so" />
<uses-native-library android:required="false" android:name="libbar.oem1.so" />
<uses-native-library android:required="false" android:name="libfoo.oem2.so" />
diff --git a/libnativeloader/test/loadlibrarytest_product_app_manifest.xml b/libnativeloader/test/loadlibrarytest_product_app_manifest.xml
index 614f33ffc9..c1d997aa70 100644
--- a/libnativeloader/test/loadlibrarytest_product_app_manifest.xml
+++ b/libnativeloader/test/loadlibrarytest_product_app_manifest.xml
@@ -21,7 +21,6 @@
android:targetPackage="android.test.app.product" />
<application>
<uses-library android:name="android.test.systemsharedlib" />
- <uses-library android:name="android.test.systemextsharedlib" />
<uses-native-library android:required="false" android:name="libfoo.oem1.so" />
<uses-native-library android:required="false" android:name="libbar.oem1.so" />
<uses-native-library android:required="false" android:name="libfoo.oem2.so" />
diff --git a/libnativeloader/test/loadlibrarytest_system_app_manifest.xml b/libnativeloader/test/loadlibrarytest_system_app_manifest.xml
index 5711f651cf..5c6af09031 100644
--- a/libnativeloader/test/loadlibrarytest_system_app_manifest.xml
+++ b/libnativeloader/test/loadlibrarytest_system_app_manifest.xml
@@ -21,7 +21,6 @@
android:targetPackage="android.test.app.system" />
<application>
<uses-library android:name="android.test.systemsharedlib" />
- <uses-library android:name="android.test.systemextsharedlib" />
<!-- System apps get a shared classloader namespace, so they don't need
uses-native-library entries for anything in /system. -->
<uses-native-library android:required="false" android:name="libfoo.product1.so" />
diff --git a/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml b/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml
index 8aa3fa9f1f..961f9ba389 100644
--- a/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml
+++ b/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml
@@ -21,7 +21,6 @@
android:targetPackage="android.test.app.system_ext" />
<application>
<uses-library android:name="android.test.systemsharedlib" />
- <uses-library android:name="android.test.systemextsharedlib" />
<!-- System apps get a shared classloader namespace, so they don't need
uses-native-library entries for anything in /system. -->
<uses-native-library android:required="false" android:name="libfoo.product1.so" />
diff --git a/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml b/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml
index 126453c86f..f4bf3c094b 100644
--- a/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml
+++ b/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml
@@ -21,7 +21,6 @@
android:targetPackage="android.test.app.system_priv" />
<application>
<uses-library android:name="android.test.systemsharedlib" />
- <uses-library android:name="android.test.systemextsharedlib" />
<!-- System apps get a shared classloader namespace, so they don't need
uses-native-library entries for anything in /system. -->
<uses-native-library android:required="false" android:name="libfoo.product1.so" />
diff --git a/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml b/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml
index a2a9f648f4..1a8cbcc2a8 100644
--- a/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml
+++ b/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml
@@ -21,7 +21,6 @@
android:targetPackage="android.test.app.vendor" />
<application>
<uses-library android:name="android.test.systemsharedlib" />
- <uses-library android:name="android.test.systemextsharedlib" />
<uses-native-library android:required="false" android:name="libfoo.oem1.so" />
<uses-native-library android:required="false" android:name="libbar.oem1.so" />
<uses-native-library android:required="false" android:name="libfoo.oem2.so" />
diff --git a/libnativeloader/test/src/android/test/app/DataAppTest.java b/libnativeloader/test/src/android/test/app/DataAppTest.java
index 767a7b19ff..db97e8ddc0 100644
--- a/libnativeloader/test/src/android/test/app/DataAppTest.java
+++ b/libnativeloader/test/src/android/test/app/DataAppTest.java
@@ -17,7 +17,6 @@
package android.test.app;
import android.test.lib.TestUtils;
-import android.test.systemextsharedlib.SystemExtSharedLib;
import android.test.systemsharedlib.SystemSharedLib;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -41,24 +40,16 @@ public class DataAppTest {
@Test
public void testLoadPrivateLibraries() {
TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_private1"));
- TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("systemext_private1"));
TestUtils.assertLibraryNotFound(() -> System.loadLibrary("product_private1"));
TestUtils.assertLibraryNotFound(() -> System.loadLibrary("vendor_private1"));
}
@Test
public void testLoadPrivateLibrariesViaSystemSharedLib() {
- SystemSharedLib.loadLibrary("system_private2");
- SystemSharedLib.loadLibrary("systemext_private2");
+ // TODO(b/237577392): Fix this use case.
+ TestUtils.assertLinkerNamespaceError(() -> SystemSharedLib.loadLibrary("system_private2"));
+
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
}
-
- @Test
- public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
- SystemExtSharedLib.loadLibrary("system_private3");
- SystemExtSharedLib.loadLibrary("systemext_private3");
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
- }
}
diff --git a/libnativeloader/test/src/android/test/app/ProductAppTest.java b/libnativeloader/test/src/android/test/app/ProductAppTest.java
index 1f36798515..a9b8697067 100644
--- a/libnativeloader/test/src/android/test/app/ProductAppTest.java
+++ b/libnativeloader/test/src/android/test/app/ProductAppTest.java
@@ -17,7 +17,6 @@
package android.test.app;
import android.test.lib.TestUtils;
-import android.test.systemextsharedlib.SystemExtSharedLib;
import android.test.systemsharedlib.SystemSharedLib;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -41,24 +40,16 @@ public class ProductAppTest {
@Test
public void testLoadPrivateLibraries() {
TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_private1"));
- TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("systemext_private1"));
System.loadLibrary("product_private1");
TestUtils.assertLibraryNotFound(() -> System.loadLibrary("vendor_private1"));
}
@Test
public void testLoadPrivateLibrariesViaSystemSharedLib() {
- SystemSharedLib.loadLibrary("system_private2");
- SystemSharedLib.loadLibrary("systemext_private2");
+ // TODO(b/237577392): Fix this use case.
+ TestUtils.assertLinkerNamespaceError(() -> SystemSharedLib.loadLibrary("system_private2"));
+
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
}
-
- @Test
- public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
- SystemExtSharedLib.loadLibrary("system_private3");
- SystemExtSharedLib.loadLibrary("systemext_private3");
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
- }
}
diff --git a/libnativeloader/test/src/android/test/app/SystemAppTest.java b/libnativeloader/test/src/android/test/app/SystemAppTest.java
index 197a40cf0e..664447824c 100644
--- a/libnativeloader/test/src/android/test/app/SystemAppTest.java
+++ b/libnativeloader/test/src/android/test/app/SystemAppTest.java
@@ -17,7 +17,6 @@
package android.test.app;
import android.test.lib.TestUtils;
-import android.test.systemextsharedlib.SystemExtSharedLib;
import android.test.systemsharedlib.SystemSharedLib;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -41,7 +40,6 @@ public class SystemAppTest {
@Test
public void testLoadPrivateLibraries() {
System.loadLibrary("system_private1");
- System.loadLibrary("systemext_private1");
TestUtils.assertLibraryNotFound(() -> System.loadLibrary("product_private1"));
TestUtils.assertLibraryNotFound(() -> System.loadLibrary("vendor_private1"));
}
@@ -49,16 +47,7 @@ public class SystemAppTest {
@Test
public void testLoadPrivateLibrariesViaSystemSharedLib() {
SystemSharedLib.loadLibrary("system_private2");
- SystemSharedLib.loadLibrary("systemext_private2");
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
}
-
- @Test
- public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
- SystemExtSharedLib.loadLibrary("system_private3");
- SystemExtSharedLib.loadLibrary("systemext_private3");
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
- }
}
diff --git a/libnativeloader/test/src/android/test/app/VendorAppTest.java b/libnativeloader/test/src/android/test/app/VendorAppTest.java
index c9ce8db57a..5187ac8c20 100644
--- a/libnativeloader/test/src/android/test/app/VendorAppTest.java
+++ b/libnativeloader/test/src/android/test/app/VendorAppTest.java
@@ -17,7 +17,6 @@
package android.test.app;
import android.test.lib.TestUtils;
-import android.test.systemextsharedlib.SystemExtSharedLib;
import android.test.systemsharedlib.SystemSharedLib;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -40,7 +39,6 @@ public class VendorAppTest {
@Test
public void testLoadPrivateLibraries() {
TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_private1"));
- TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("systemext_private1"));
TestUtils.assertLibraryNotFound(() -> System.loadLibrary("product_private1"));
// TODO(mast): The vendor app fails to load a private vendor library because it gets
// classified as untrusted_app in SELinux, which doesn't have access to vendor_file. Even an
@@ -51,17 +49,10 @@ public class VendorAppTest {
@Test
public void testLoadPrivateLibrariesViaSystemSharedLib() {
- SystemSharedLib.loadLibrary("system_private2");
- SystemSharedLib.loadLibrary("systemext_private2");
+ // TODO(b/237577392): Fix this use case.
+ TestUtils.assertLinkerNamespaceError(() -> SystemSharedLib.loadLibrary("system_private2"));
+
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
}
-
- @Test
- public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
- SystemExtSharedLib.loadLibrary("system_private3");
- SystemExtSharedLib.loadLibrary("systemext_private3");
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
- TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
- }
}
diff --git a/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java b/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java
index c9290377ee..c908a492e2 100644
--- a/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java
+++ b/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java
@@ -69,10 +69,7 @@ public class LibnativeloaderTest extends BaseHostJUnit4Test {
ctx.pushExtendedPublicProductLibs(libApk);
ctx.pushPrivateLibs(libApk);
}
- ctx.pushSystemSharedLib("/system/framework", "android.test.systemsharedlib",
- "libnativeloader_system_shared_lib.jar");
- ctx.pushSystemSharedLib("/system_ext/framework", "android.test.systemextsharedlib",
- "libnativeloader_system_ext_shared_lib.jar");
+ ctx.pushSystemSharedLib();
// "Install" apps in various partitions through plain adb push followed by a soft reboot. We
// need them in these locations to test library loading restrictions, so for all except
@@ -233,18 +230,17 @@ public class LibnativeloaderTest extends BaseHostJUnit4Test {
void pushPrivateLibs(ZipFile libApk) throws Exception {
// Push the libraries once for each test. Since we cannot unload them, we need a fresh
// never-before-loaded library in each loadLibrary call.
- for (int i = 1; i <= 3; ++i) {
+ for (int i = 1; i <= 2; ++i) {
pushNativeTestLib(libApk, "/system/${LIB}/libsystem_private" + i + ".so");
- pushNativeTestLib(libApk, "/system_ext/${LIB}/libsystemext_private" + i + ".so");
pushNativeTestLib(libApk, "/product/${LIB}/libproduct_private" + i + ".so");
pushNativeTestLib(libApk, "/vendor/${LIB}/libvendor_private" + i + ".so");
}
}
- void pushSystemSharedLib(String packageDir, String packageName, String buildJarName)
- throws Exception {
- String path = packageDir + "/" + packageName + ".jar";
- pushFile(buildJarName, path);
+ void pushSystemSharedLib() throws Exception {
+ String packageName = "android.test.systemsharedlib";
+ String path = "/system/framework/" + packageName + ".jar";
+ pushFile("libnativeloader_system_shared_lib.jar", path);
pushString("<permissions>\n"
+ "<library name=\"" + packageName + "\" file=\"" + path + "\" />\n"
+ "</permissions>\n",
diff --git a/libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java b/libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java
deleted file mode 100644
index 1240e12e55..0000000000
--- a/libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.systemextsharedlib;
-
-public final class SystemExtSharedLib {
- public static void loadLibrary(String name) { System.loadLibrary(name); }
-}
diff --git a/runtime/exec_utils.cc b/runtime/exec_utils.cc
index dd389f8c97..58ee5ce01e 100644
--- a/runtime/exec_utils.cc
+++ b/runtime/exec_utils.cc
@@ -16,9 +16,11 @@
#include "exec_utils.h"
+#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sysexits.h>
#include <unistd.h>
#include <ctime>
@@ -89,6 +91,12 @@ pid_t ExecWithoutWait(const std::vector<std::string>& arg_vector, std::string* e
} else {
execve(program, &args[0], envp);
}
+ if (errno == EACCES) {
+ // This usually happens when a non-Zygote process invokes dex2oat to generate an in-memory
+ // boot image, which is WAI.
+ PLOG(DEBUG) << "Failed to execute (" << ToCommandLine(arg_vector) << ")";
+ _exit(EX_NOPERM);
+ }
// This should be regarded as a crash rather than a normal return.
PLOG(FATAL) << "Failed to execute (" << ToCommandLine(arg_vector) << ")";
UNREACHABLE();
diff --git a/runtime/exec_utils_test.cc b/runtime/exec_utils_test.cc
index e89180b572..a435e3c8fe 100644
--- a/runtime/exec_utils_test.cc
+++ b/runtime/exec_utils_test.cc
@@ -17,6 +17,7 @@
#include "exec_utils.h"
#include <sys/utsname.h>
+#include <sysexits.h>
#include <csignal>
#include <cstring>
@@ -127,6 +128,15 @@ TEST_P(ExecUtilsTest, ExecError) {
EXPECT_FALSE(error_msg.empty());
}
+TEST_P(ExecUtilsTest, ExecPermissionDenied) {
+ std::vector<std::string> command;
+ command.push_back("/dev/null");
+ std::string error_msg;
+ ExecResult result = exec_utils_->ExecAndReturnResult(command, /*timeout_sec=*/-1, &error_msg);
+ EXPECT_EQ(result.status, ExecResult::kExited);
+ EXPECT_EQ(result.exit_code, EX_NOPERM);
+}
+
TEST_P(ExecUtilsTest, EnvSnapshotAdditionsAreNotVisible) {
static constexpr const char* kModifiedVariable = "EXEC_SHOULD_NOT_EXPORT_THIS";
static constexpr int kOverwrite = 1;