diff options
author | 2024-02-19 19:41:36 +0000 | |
---|---|---|
committer | 2024-02-21 21:09:36 +0000 | |
commit | 16b9c0b1ab17b5770f8cefc1d5a1414c911a7a57 (patch) | |
tree | 02ac68c713ba511c5e6843e1f24f72de7e5f2fdc | |
parent | d00d24530a29b684bec9a895c1da491a6390395f (diff) |
Fix test failures on sargo.
https://r.android.com/2962585 added new tests, but some of them fail on
S on sargo since the product partition comes from R and doesn't have
its own linker namespace.
Also switch version checks to use com.android.modules.utils.build.SdkLevel
to correctly handle pre-release codenames.
Test: libnativeloader_e2e_tests on AOSP with temporary code to verify
that TestUtils.productAppsAreShared() returns false
Test: libnativeloader_e2e_tests on sargo in heavy presubmit
Test: libnativeloader_e2e_tests on Cuttlefish S image in heavy presubmit
Bug: 325619263
Bug: 237577392
Change-Id: I7cc7d0a6288b10b5f70c6c674f88287b2489be75
4 files changed, 102 insertions, 60 deletions
diff --git a/libnativeloader/test/Android.bp b/libnativeloader/test/Android.bp index 268e93ab3f..6166725af7 100644 --- a/libnativeloader/test/Android.bp +++ b/libnativeloader/test/Android.bp @@ -102,11 +102,12 @@ java_library { java_library { name: "loadlibrarytest_testlib", - sdk_version: "31", + sdk_version: "system_31", static_libs: [ "androidx.test.ext.junit", "androidx.test.ext.truth", "androidx.test.rules", + "modules-utils-build_system", ], libs: [ "libnativeloader_system_shared_lib", diff --git a/libnativeloader/test/src/android/test/app/ProductAppTest.java b/libnativeloader/test/src/android/test/app/ProductAppTest.java index bfa648b013..4cf379c9c6 100644 --- a/libnativeloader/test/src/android/test/app/ProductAppTest.java +++ b/libnativeloader/test/src/android/test/app/ProductAppTest.java @@ -16,8 +16,6 @@ package android.test.app; -import android.os.Build; -import android.os.SystemProperties; import android.test.lib.AppTestCommon; import android.test.lib.TestUtils; import android.test.productsharedlib.ProductSharedLib; @@ -36,13 +34,6 @@ public class ProductAppTest extends AppTestCommon { return AppLocation.PRODUCT; } - // True if apps in product partitions get shared library namespaces, so we - // cannot test that libs in system and system_ext get blocked. - private static boolean productAppsAreShared() { - return Build.VERSION.SDK_INT <= 34 && // UPSIDE_DOWN_CAKE - SystemProperties.get("ro.product.vndk.version").isEmpty(); - } - @Test public void testPrivateLibsExist() { TestUtils.testPrivateLibsExist("/product", "product_private"); @@ -53,7 +44,7 @@ public class ProductAppTest extends AppTestCommon { System.loadLibrary("system_extpub.oem1"); System.loadLibrary("system_extpub.oem2"); System.loadLibrary("system_extpub1.oem1"); - if (!productAppsAreShared()) { + if (!TestUtils.productAppsAreShared()) { TestUtils.assertLibraryInaccessible( // Missing <uses-native-library>. () -> System.loadLibrary("system_extpub_nouses.oem2")); } @@ -63,7 +54,7 @@ public class ProductAppTest extends AppTestCommon { @Test public void testLoadPrivateLibraries() { - if (!productAppsAreShared()) { + if (!TestUtils.productAppsAreShared()) { TestUtils.assertLibraryInaccessible(() -> System.loadLibrary("system_private1")); TestUtils.assertLibraryInaccessible(() -> System.loadLibrary("systemext_private1")); } @@ -81,13 +72,14 @@ public class ProductAppTest extends AppTestCommon { @Test public void testLoadPrivateLibrariesViaSystemSharedLib() { - // TODO(b/237577392): Loading a private native system library via a shared system library - // ought to work. - TestUtils.assertLibraryInaccessible(() -> SystemSharedLib.loadLibrary("system_private2")); - TestUtils.assertLibraryInaccessible( - () -> SystemSharedLib.loadLibrary("systemext_private2")); + if (!TestUtils.productAppsAreShared()) { + // TODO(b/237577392): Loading a private native system library via a shared system + // library ought to work. + TestUtils.assertLibraryInaccessible( + () -> SystemSharedLib.loadLibrary("system_private2")); + TestUtils.assertLibraryInaccessible( + () -> SystemSharedLib.loadLibrary("systemext_private2")); - if (!productAppsAreShared()) { TestUtils.assertLibraryInaccessible( () -> SystemSharedLib.loadLibrary("product_private2")); } @@ -97,14 +89,14 @@ public class ProductAppTest extends AppTestCommon { @Test public void testLoadPrivateLibrariesViaSystemExtSharedLib() { - // TODO(b/237577392): Loading a private native system library via a shared system library - // ought to work. - TestUtils.assertLibraryInaccessible( - () -> SystemExtSharedLib.loadLibrary("system_private3")); - TestUtils.assertLibraryInaccessible( - () -> SystemExtSharedLib.loadLibrary("systemext_private3")); + if (!TestUtils.productAppsAreShared()) { + // TODO(b/237577392): Loading a private native system library via a shared system + // library ought to work. + TestUtils.assertLibraryInaccessible( + () -> SystemExtSharedLib.loadLibrary("system_private3")); + TestUtils.assertLibraryInaccessible( + () -> SystemExtSharedLib.loadLibrary("systemext_private3")); - if (!productAppsAreShared()) { TestUtils.assertLibraryInaccessible( () -> SystemExtSharedLib.loadLibrary("product_private3")); } @@ -115,7 +107,7 @@ public class ProductAppTest extends AppTestCommon { @Test public void testLoadPrivateLibrariesViaProductSharedLib() { - if (!productAppsAreShared()) { + if (!TestUtils.productAppsAreShared()) { TestUtils.assertLibraryInaccessible( () -> ProductSharedLib.loadLibrary("system_private4")); TestUtils.assertLibraryInaccessible( @@ -130,7 +122,7 @@ public class ProductAppTest extends AppTestCommon { @Test public void testLoadPrivateLibrariesViaVendorSharedLib() { - if (!productAppsAreShared()) { + if (!TestUtils.productAppsAreShared()) { TestUtils.assertLibraryInaccessible( () -> VendorSharedLib.loadLibrary("system_private5")); TestUtils.assertLibraryInaccessible( @@ -155,7 +147,7 @@ public class ProductAppTest extends AppTestCommon { @Test public void testLoadPrivateLibrariesWithAbsolutePaths() { - if (!productAppsAreShared()) { + if (!TestUtils.productAppsAreShared()) { TestUtils.assertLibraryInaccessible( () -> System.load(TestUtils.libPath("/system", "system_private6"))); TestUtils.assertLibraryInaccessible( diff --git a/libnativeloader/test/src/android/test/lib/AppTestCommon.java b/libnativeloader/test/src/android/test/lib/AppTestCommon.java index 36ef3dc77a..51f4655839 100644 --- a/libnativeloader/test/src/android/test/lib/AppTestCommon.java +++ b/libnativeloader/test/src/android/test/lib/AppTestCommon.java @@ -32,31 +32,50 @@ public abstract class AppTestCommon { public abstract AppLocation getAppLocation(); - // Loading private libs using absolute paths through shared libs should only - // depend on the location of the shared lib, so these tests are shared for - // all apps, regardless of location. - - // There's an exception for system apps. For them LibraryNamespaces::Create - // gets called with is_shared=true. That means they don't set up separate - // "unbundled" namespaces for the shared libs in product and vendor, so - // ProductSharedLib and VendorSharedLib can still load private system libs - // through their classloader namespaces, but not the private libs in the - // same partition as themselves. - private boolean isSharedSystemApp() { - return getAppLocation() == AppLocation.SYSTEM; + // Loading private libs using absolute paths through shared libs should + // normally only depend on the location of the shared lib, so these tests + // are shared for all apps, regardless of location. + + // Returns true when system private native libs are accessible directly from + // the app classloader namespace. + private boolean systemPrivateLibsAccessibleFromAppNamespace() { + // Currently it only works from system apps. It also works from product + // apps on old versions where they were treated like system apps. + // TODO(b/237577392): Fix this to work from system shared libs. + return getAppLocation() == AppLocation.SYSTEM + || (getAppLocation() == AppLocation.PRODUCT && TestUtils.productAppsAreShared()); + } + + // Detect exception when product private libs are accessible directly from + // the app classloader namespace even when they shouldn't be. + private boolean productPrivateLibsAccessibleFromAppNamespace() { + // In old versions where product apps were treated like system apps, the + // product private libs were included in the system namespace, so + // they're accessible both from system and product apps. + // TODO(b/237577392): Fix this to work from product shared libs. + return (getAppLocation() == AppLocation.SYSTEM || getAppLocation() == AppLocation.PRODUCT) + && TestUtils.productAppsAreShared(); + } + + // Detect exception where we don't switch from a shared system namespace to + // a product or vendor "unbundled" namespace when calling into + // ProductSharedLib and VendorSharedLib. That means they still can load + // private system libs but not private libs in their own partition. + // TODO(mast): Stop propagating the shared property (isBundledApp in + // LoadedApk.java) down to public and vendor shared java libs? + private boolean noSwitchToVendorOrProductNamespace() { + // System apps get shared namespaces, and also product apps on old + // versions where they were treated like system apps. + return getAppLocation() == AppLocation.SYSTEM + || (getAppLocation() == AppLocation.PRODUCT && TestUtils.productAppsAreShared()); } @Test public void testLoadPrivateLibrariesViaSystemSharedLibWithAbsolutePaths() { - if (getAppLocation() == AppLocation.SYSTEM) { + if (systemPrivateLibsAccessibleFromAppNamespace()) { SystemSharedLib.load(TestUtils.libPath("/system", "system_private7")); SystemSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private7")); } else { - // Cannot load private system libs because there is no provision in - // LibraryNamespaces::Create to create an "unbundled system apk" for - // shared system libs based on their location. Hence SystemSharedLib - // gets a classloader namespace as an "other apk", with the same - // library_path as the app. TestUtils.assertLibraryInaccessible(() -> { SystemSharedLib.load(TestUtils.libPath("/system", "system_private7")); }); @@ -65,8 +84,13 @@ public abstract class AppTestCommon { }); } - TestUtils.assertLibraryInaccessible( - () -> { SystemSharedLib.load(TestUtils.libPath("/product", "product_private7")); }); + if (productPrivateLibsAccessibleFromAppNamespace()) { + SystemSharedLib.load(TestUtils.libPath("/product", "product_private7")); + } else { + TestUtils.assertLibraryInaccessible(() -> { + SystemSharedLib.load(TestUtils.libPath("/product", "product_private7")); + }); + } TestUtils.assertLibraryInaccessible( () -> { SystemSharedLib.load(TestUtils.libPath("/vendor", "vendor_private7")); }); @@ -74,11 +98,10 @@ public abstract class AppTestCommon { @Test public void testLoadPrivateLibrariesViaSystemExtSharedLibWithAbsolutePaths() { - if (getAppLocation() == AppLocation.SYSTEM) { + if (systemPrivateLibsAccessibleFromAppNamespace()) { SystemExtSharedLib.load(TestUtils.libPath("/system", "system_private8")); SystemExtSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private8")); } else { - // See comment in the corresponding test for SystemSharedLib above. TestUtils.assertLibraryInaccessible(() -> { SystemExtSharedLib.load(TestUtils.libPath("/system", "system_private8")); }); @@ -87,9 +110,13 @@ public abstract class AppTestCommon { }); } - TestUtils.assertLibraryInaccessible(() -> { + if (productPrivateLibsAccessibleFromAppNamespace()) { SystemExtSharedLib.load(TestUtils.libPath("/product", "product_private8")); - }); + } else { + TestUtils.assertLibraryInaccessible(() -> { + SystemExtSharedLib.load(TestUtils.libPath("/product", "product_private8")); + }); + } TestUtils.assertLibraryInaccessible(() -> { SystemExtSharedLib.load(TestUtils.libPath("/vendor", "vendor_private8")); @@ -98,7 +125,7 @@ public abstract class AppTestCommon { @Test public void testLoadPrivateLibrariesViaProductSharedLibWithAbsolutePaths() { - if (isSharedSystemApp()) { + if (systemPrivateLibsAccessibleFromAppNamespace() || noSwitchToVendorOrProductNamespace()) { ProductSharedLib.load(TestUtils.libPath("/system", "system_private9")); ProductSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private9")); } else { @@ -110,7 +137,17 @@ public abstract class AppTestCommon { }); } - if (!isSharedSystemApp()) { + boolean loadPrivateProductLib; + if (TestUtils.productAppsAreShared()) { + // The library is accessible if the app is in either system or + // product, because both are loaded as system apps and private product + // libs are available for both. + loadPrivateProductLib = getAppLocation() == AppLocation.SYSTEM + || getAppLocation() == AppLocation.PRODUCT; + } else { + loadPrivateProductLib = !noSwitchToVendorOrProductNamespace(); + } + if (loadPrivateProductLib) { ProductSharedLib.load(TestUtils.libPath("/product", "product_private9")); } else { TestUtils.assertLibraryInaccessible(() -> { @@ -124,7 +161,7 @@ public abstract class AppTestCommon { @Test public void testLoadPrivateLibrariesViaVendorSharedLibWithAbsolutePaths() { - if (isSharedSystemApp()) { + if (systemPrivateLibsAccessibleFromAppNamespace() || noSwitchToVendorOrProductNamespace()) { VendorSharedLib.load(TestUtils.libPath("/system", "system_private10")); VendorSharedLib.load(TestUtils.libPath("/system_ext", "systemext_private10")); } else { @@ -136,11 +173,15 @@ public abstract class AppTestCommon { }); } - TestUtils.assertLibraryInaccessible(() -> { + if (productPrivateLibsAccessibleFromAppNamespace()) { VendorSharedLib.load(TestUtils.libPath("/product", "product_private10")); - }); + } else { + TestUtils.assertLibraryInaccessible(() -> { + VendorSharedLib.load(TestUtils.libPath("/product", "product_private10")); + }); + } - if (!isSharedSystemApp()) { + if (!noSwitchToVendorOrProductNamespace()) { VendorSharedLib.load(TestUtils.libPath("/vendor", "vendor_private10")); } else { TestUtils.assertLibraryInaccessible(() -> { diff --git a/libnativeloader/test/src/android/test/lib/TestUtils.java b/libnativeloader/test/src/android/test/lib/TestUtils.java index 6d2a9db0f3..5f5cd911e8 100644 --- a/libnativeloader/test/src/android/test/lib/TestUtils.java +++ b/libnativeloader/test/src/android/test/lib/TestUtils.java @@ -21,10 +21,12 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertThrows; -import android.os.Build; +import android.os.SystemProperties; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.modules.utils.build.SdkLevel; + import org.junit.function.ThrowingRunnable; import java.io.File; @@ -44,7 +46,13 @@ public final class TestUtils { // True if we have to skip testing public libraries in the product // partition, which got supported in T. public static boolean skipPublicProductLibTests() { - return Build.VERSION.SDK_INT < 33; // TIRAMISU + return !SdkLevel.isAtLeastT(); + } + + // True if apps in product partitions get shared library namespaces, so we + // cannot test that libs in system and system_ext get blocked. + public static boolean productAppsAreShared() { + return !SdkLevel.isAtLeastU() && SystemProperties.get("ro.product.vndk.version").isEmpty(); } // Test that private libs are present, as a safeguard so that the dlopen |