Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8565fedc authored by Kalesh Singh's avatar Kalesh Singh
Browse files

PackageManager: 16K: Extract native libs that are not zipaligned correctly



If 16kB app compat is enabled; fallback to extracting native libraries
which are not zipaligned correctly (16kb alignment) but are zipaligned
correctly for 4kB devices (has 4kb alignement).

This is expected to be the case for apps that have not updated to support
16kB page size and use extractNativeLibs=false.

If app compat is enabled on 16kb devices, allow the installation of such
4kb-zipaligned apps.

Bug: 339709616
Test: Install apps not 16kb zip-aligned from playstore (chic-fil-a, ...)
Change-Id: I30a1bc50bc9dea40baf37e7af296e2a4d8e857db
Signed-off-by: default avatarKalesh Singh <kaleshsingh@google.com>
parent 8585f409
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "NativeLibraryHelper"
//#define LOG_NDEBUG 0

#include <android-base/properties.h>
#include <androidfw/ApkParsing.h>
#include <androidfw/ZipFileRO.h>
#include <androidfw/ZipUtils.h>
@@ -263,6 +264,7 @@ static install_status_t copyFileIfChanged(JNIEnv* env, void* arg, ZipFileRO* zip
    jstring* javaNativeLibPath = (jstring*)args[0];
    jboolean extractNativeLibs = *(jboolean*)args[1];
    jboolean debuggable = *(jboolean*)args[2];
    jboolean app_compat_16kb = *(jboolean*)args[3];
    install_status_t ret = INSTALL_SUCCEEDED;

    ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
@@ -294,6 +296,16 @@ static install_status_t copyFileIfChanged(JNIEnv* env, void* arg, ZipFileRO* zip
        }

        if (offset % kPageSize != 0) {
            // If the library is zip-aligned correctly for 4kb devices and app compat is
            // enabled, on 16kb devices fallback to extraction
            if (offset % 0x1000 == 0 && app_compat_16kb) {
                ALOGI("16kB AppCompat: Library '%s' is not PAGE(%zu)-aligned - falling back to "
                      "extraction from apk\n",
                      fileName, kPageSize);
                return extractNativeLibFromApk(zipFile, zipEntry, fileName, nativeLibPath.c_str(),
                                               when, uncompLen, crc);
            }

            ALOGE("Library '%s' is not PAGE(%zu)-aligned - will not be able to open it directly "
                  "from apk.\n",
                  fileName, kPageSize);
@@ -508,12 +520,24 @@ static int findSupportedAbi(JNIEnv* env, jlong apkHandle, jobjectArray supported
    return status;
}

static inline bool app_compat_16kb_enabled() {
    static const size_t kPageSize = getpagesize();

    // App compat is only applicable on 16kb-page-size devices.
    if (kPageSize != 0x4000) {
        return false;
    }

    return android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false);
}

static jint
com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
        jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
        jboolean extractNativeLibs, jboolean debuggable)
{
    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &debuggable };
    jboolean app_compat_16kb = app_compat_16kb_enabled();
    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &debuggable, &app_compat_16kb };
    return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable,
            copyFileIfChanged, reinterpret_cast<void*>(args));
}