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

Commit a86bb7e4 authored by Michael Hoisie's avatar Michael Hoisie
Browse files

Make sqlite JNI available for host Mac and Windows in libandroid_runtime

This involves switching CursorWindow to use MappedFile for mmap-related
operations. The main advantage of FileMap is that it is supported on all
host platforms, including Windows. This change is a no-op in terms of
functionality.

This is a roll-forward of aosp/3000218. However, that CL was rolled back
due to a spurious test failure (testPocCVE_2023_21276). That test has
been updated to avoid unrelated false positives in ag/34986562.

Test: Roboelctric SQLiteDatabaseTest
Test: libandroidfw_tests
Flag: EXEMPT small refactor
Bug: 317884162
Bug: 437248474
Change-Id: I150fd216971cf486beda7c187945a758ebe5589c
parent 1cf0749b
Loading
Loading
Loading
Loading
+7 −13
Original line number Diff line number Diff line
@@ -74,6 +74,12 @@ cc_library_shared_for_libandroid_runtime {
    srcs: [
        "android_animation_PropertyValuesHolder.cpp",
        "android_content_res_ApkAssets.cpp",
        "android_database_CursorWindow.cpp",
        "android_database_SQLiteCommon.cpp",
        "android_database_SQLiteConnection.cpp",
        "android_database_SQLiteGlobal.cpp",
        "android_database_SQLiteDebug.cpp",
        "android_database_SQLiteRawStatement.cpp",
        "android_media_ImageReader.cpp",
        "android_media_PublicFormatUtils.cpp",
        "android_media_Utils.cpp",
@@ -148,12 +154,6 @@ cc_library_shared_for_libandroid_runtime {
                "android_opengl_GLES31.cpp",
                "android_opengl_GLES31Ext.cpp",
                "android_opengl_GLES32.cpp",
                "android_database_CursorWindow.cpp",
                "android_database_SQLiteCommon.cpp",
                "android_database_SQLiteConnection.cpp",
                "android_database_SQLiteGlobal.cpp",
                "android_database_SQLiteDebug.cpp",
                "android_database_SQLiteRawStatement.cpp",
                "android_graphics_GraphicBuffer.cpp",
                "android_graphics_SurfaceTexture.cpp",
                "android_view_CompositionSamplingListener.cpp",
@@ -444,6 +444,7 @@ cc_library_shared_for_libandroid_runtime {
                "libnativehelper_jvm",
                "libpiex",
                "libpng",
                "libsqlite",
                "libtiff_directory",
                "libui-types",
                "libutils",
@@ -467,12 +468,6 @@ cc_library_shared_for_libandroid_runtime {
        },
        host_linux: {
            srcs: [
                "android_database_CursorWindow.cpp",
                "android_database_SQLiteCommon.cpp",
                "android_database_SQLiteConnection.cpp",
                "android_database_SQLiteGlobal.cpp",
                "android_database_SQLiteDebug.cpp",
                "android_database_SQLiteRawStatement.cpp",
                "android_hardware_input_InputApplicationHandle.cpp",
                "android_os_MessageQueue.cpp",
                "android_os_Parcel.cpp",
@@ -487,7 +482,6 @@ cc_library_shared_for_libandroid_runtime {
            ],
            static_libs: [
                "libbinderthreadstateutils",
                "libsqlite",
                "libgui_window_info_static",
                "libbinder",
                "libbinder_ndk",
+47 −64
Original line number Diff line number Diff line
@@ -38,8 +38,10 @@
#define LOG_NDEBUG 1

#include <androidfw/CursorWindow.h>
#ifdef __linux__
#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#endif
#include "android_database_SQLiteCommon.h"

#include "core_jni_helpers.h"
@@ -111,6 +113,15 @@ fail:
    return 0;
}

static void nativeDispose(JNIEnv* env, jclass clazz, jlong windowPtr) {
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
    if (window) {
        LOG_WINDOW("Closing window %p", window);
        delete window;
    }
}

#ifdef __linux__
static jlong nativeCreateFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
    Parcel* parcel = parcelForJavaObject(env, parcelObj);

@@ -129,19 +140,6 @@ static jlong nativeCreateFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj
    return reinterpret_cast<jlong>(window);
}

static void nativeDispose(JNIEnv* env, jclass clazz, jlong windowPtr) {
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
    if (window) {
        LOG_WINDOW("Closing window %p", window);
        delete window;
    }
}

static jstring nativeGetName(JNIEnv* env, jclass clazz, jlong windowPtr) {
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
    return env->NewStringUTF(window->name().c_str());
}

static void nativeWriteToParcel(JNIEnv * env, jclass clazz, jlong windowPtr,
        jobject parcelObj) {
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
@@ -154,6 +152,12 @@ static void nativeWriteToParcel(JNIEnv * env, jclass clazz, jlong windowPtr,
        jniThrowRuntimeException(env, msg.c_str());
    }
}
#endif

static jstring nativeGetName(JNIEnv* env, jclass clazz, jlong windowPtr) {
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
    return env->NewStringUTF(window->name().c_str());
}

static void nativeClear(CRITICAL_JNI_PARAMS_COMMA jlong windowPtr) {
    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
@@ -517,57 +521,36 @@ static jboolean nativePutNull(CRITICAL_JNI_PARAMS_COMMA jlong windowPtr, jint ro
    return true;
}

static const JNINativeMethod sMethods[] =
{
static const JNINativeMethod sMethods[] = {
        /* name, signature, funcPtr */
    { "nativeCreate", "(Ljava/lang/String;I)J",
            (void*)nativeCreate },
    { "nativeCreateFromParcel", "(Landroid/os/Parcel;)J",
            (void*)nativeCreateFromParcel },
    { "nativeDispose", "(J)V",
            (void*)nativeDispose },
    { "nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
            (void*)nativeWriteToParcel },

    { "nativeGetName", "(J)Ljava/lang/String;",
            (void*)nativeGetName },
    { "nativeGetBlob", "(JII)[B",
            (void*)nativeGetBlob },
    { "nativeGetString", "(JII)Ljava/lang/String;",
            (void*)nativeGetString },
        {"nativeCreate", "(Ljava/lang/String;I)J", (void*)nativeCreate},
        {"nativeDispose", "(J)V", (void*)nativeDispose},
#ifdef __linux__
        {"nativeCreateFromParcel", "(Landroid/os/Parcel;)J", (void*)nativeCreateFromParcel},
        {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel},
#endif
        {"nativeGetName", "(J)Ljava/lang/String;", (void*)nativeGetName},
        {"nativeGetBlob", "(JII)[B", (void*)nativeGetBlob},
        {"nativeGetString", "(JII)Ljava/lang/String;", (void*)nativeGetString},
        {"nativeCopyStringToBuffer", "(JIILandroid/database/CharArrayBuffer;)V",
         (void*)nativeCopyStringToBuffer},
    { "nativePutBlob", "(J[BII)Z",
            (void*)nativePutBlob },
    { "nativePutString", "(JLjava/lang/String;II)Z",
            (void*)nativePutString },
        {"nativePutBlob", "(J[BII)Z", (void*)nativePutBlob},
        {"nativePutString", "(JLjava/lang/String;II)Z", (void*)nativePutString},

        // ------- @FastNative below here ----------------------
    { "nativeAllocRow", "(J)Z",
            (void*)nativeAllocRow },
    { "nativeGetLong", "(JII)J",
            (void*)nativeGetLong },
    { "nativeGetDouble", "(JII)D",
            (void*)nativeGetDouble },

        {"nativeAllocRow", "(J)Z", (void*)nativeAllocRow},
        {"nativeGetLong", "(JII)J", (void*)nativeGetLong},
        {"nativeGetDouble", "(JII)D", (void*)nativeGetDouble},

        // ------- @CriticalNative below here ------------------
    { "nativeClear", "(J)V",
            (void*)nativeClear },
    { "nativeGetNumRows", "(J)I",
            (void*)nativeGetNumRows },
    { "nativeFreeLastRow", "(J)V",
            (void*)nativeFreeLastRow },
    { "nativeGetType", "(JII)I",
            (void*)nativeGetType },
    { "nativeSetNumColumns", "(JI)Z",
            (void*)nativeSetNumColumns },
    { "nativePutLong", "(JJII)Z",
            (void*)nativePutLong },
    { "nativePutDouble", "(JDII)Z",
            (void*)nativePutDouble },
    { "nativePutNull", "(JII)Z",
            (void*)nativePutNull },
        {"nativeClear", "(J)V", (void*)nativeClear},
        {"nativeGetNumRows", "(J)I", (void*)nativeGetNumRows},
        {"nativeFreeLastRow", "(J)V", (void*)nativeFreeLastRow},
        {"nativeGetType", "(JII)I", (void*)nativeGetType},
        {"nativeSetNumColumns", "(JI)Z", (void*)nativeSetNumColumns},
        {"nativePutLong", "(JJII)Z", (void*)nativePutLong},
        {"nativePutDouble", "(JDII)Z", (void*)nativePutDouble},
        {"nativePutNull", "(JII)Z", (void*)nativePutNull},
};

int register_android_database_CursorWindow(JNIEnv* env)
+0 −2
Original line number Diff line number Diff line
@@ -120,7 +120,6 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
        {"android.content.res.AssetManager", REG_JNI(register_android_content_AssetManager)},
        {"android.content.res.StringBlock", REG_JNI(register_android_content_StringBlock)},
        {"android.content.res.XmlBlock", REG_JNI(register_android_content_XmlBlock)},
#ifdef __linux__
        {"android.database.CursorWindow", REG_JNI(register_android_database_CursorWindow)},
        {"android.database.sqlite.SQLiteConnection",
         REG_JNI(register_android_database_SQLiteConnection)},
@@ -128,7 +127,6 @@ static const std::unordered_map<std::string, RegJNIRec> gRegJNIMap = {
        {"android.database.sqlite.SQLiteDebug", REG_JNI(register_android_database_SQLiteDebug)},
        {"android.database.sqlite.SQLiteRawStatement",
         REG_JNI(register_android_database_SQLiteRawStatement)},
#endif
        {"android.media.ImageReader", REG_JNI(register_android_media_ImageReader)},
        {"android.media.PublicFormatUtils", REG_JNI(register_android_media_PublicFormatUtils)},
#ifdef __linux__
+3 −7
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ cc_library {
        "BigBufferStream.cpp",
        "ChunkIterator.cpp",
        "ConfigDescription.cpp",
        "CursorWindow.cpp",
        "FileStream.cpp",
        "Idmap.cpp",
        "LoadedArsc.cpp",
@@ -114,7 +115,6 @@ cc_library {
            srcs: [
                "BackupData.cpp",
                "BackupHelpers.cpp",
                "CursorWindow.cpp",
            ],
            shared_libs: [
                "libbase",
@@ -148,11 +148,6 @@ cc_library {
                "libz",
            ],
        },
        host_linux: {
            srcs: [
                "CursorWindow.cpp",
            ],
        },
        windows: {
            enabled: true,
        },
@@ -221,6 +216,7 @@ cc_test {
        "tests/Config_test.cpp",
        "tests/ConfigDescription_test.cpp",
        "tests/ConfigLocale_test.cpp",
        "tests/CursorWindow_test.cpp",
        "tests/DynamicRefTable_test.cpp",
        "tests/FileStream_test.cpp",
        "tests/Idmap_test.cpp",
@@ -245,7 +241,6 @@ cc_test {
            srcs: [
                "tests/BackupData_test.cpp",
                "tests/BackupHelpers_test.cpp",
                "tests/CursorWindow_test.cpp",
                "tests/ObbFile_test.cpp",
                "tests/PosixUtils_test.cpp",
            ],
@@ -257,6 +252,7 @@ cc_test {
        },
        host: {
            static_libs: common_test_libs + [
                "libbinder",
                "liblog",
                "libz",
            ],
+15 −9
Original line number Diff line number Diff line
@@ -18,11 +18,12 @@

#include <androidfw/CursorWindow.h>

#include <sys/mman.h>

#include "android-base/logging.h"
#include "android-base/mapped_file.h"
#include "cutils/ashmem.h"

using android::base::MappedFile;

namespace android {

/**
@@ -39,7 +40,7 @@ CursorWindow::CursorWindow() {

CursorWindow::~CursorWindow() {
    if (mAshmemFd >= 0) {
        ::munmap(mData, mSize);
        mMappedFile.reset();
        ::close(mAshmemFd);
    } else {
        free(mData);
@@ -75,6 +76,7 @@ fail_silent:
status_t CursorWindow::maybeInflate() {
    int ashmemFd = 0;
    void* newData = nullptr;
    std::unique_ptr<MappedFile> newMappedFile = nullptr;

    // Bail early when we can't expand any further
    if (mReadOnly || mSize == mInflatedSize) {
@@ -95,11 +97,12 @@ status_t CursorWindow::maybeInflate() {
        goto fail_silent;
    }

    newData = ::mmap(nullptr, mInflatedSize, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
    if (newData == MAP_FAILED) {
    newMappedFile = MappedFile::FromFd(ashmemFd, 0, mInflatedSize, PROT_READ | PROT_WRITE);
    if (newMappedFile == nullptr) {
        PLOG(ERROR) << "Failed mmap";
        goto fail_silent;
    }
    newData = newMappedFile->data();

    if (ashmem_set_prot_region(ashmemFd, PROT_READ) < 0) {
        PLOG(ERROR) << "Failed ashmem_set_prot_region";
@@ -117,6 +120,7 @@ status_t CursorWindow::maybeInflate() {

        free(mData);
        mAshmemFd = ashmemFd;
        mMappedFile = std::move(newMappedFile);
        mData = newData;
        mSize = mInflatedSize;
        mSlotsOffset = newSlotsOffset;
@@ -130,11 +134,12 @@ status_t CursorWindow::maybeInflate() {
fail:
    LOG(ERROR) << "Failed maybeInflate";
fail_silent:
    ::munmap(newData, mInflatedSize);
    newMappedFile.reset();
    ::close(ashmemFd);
    return UNKNOWN_ERROR;
}

#ifdef __linux__
status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outWindow) {
    *outWindow = nullptr;

@@ -166,13 +171,13 @@ status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outWindow
            PLOG(ERROR) << "Failed F_DUPFD_CLOEXEC";
            goto fail_silent;
        }

        window->mData = ::mmap(nullptr, window->mSize, PROT_READ, MAP_SHARED, tempFd, 0);
        if (window->mData == MAP_FAILED) {
        window->mMappedFile = MappedFile::FromFd(tempFd, 0, window->mSize, PROT_READ);
        if (window->mMappedFile == nullptr) {
            ::close(tempFd);
            PLOG(ERROR) << "Failed mmap";
            goto fail_silent;
        }
        window->mData = window->mMappedFile->data();

        window->mAshmemFd = tempFd;

@@ -239,6 +244,7 @@ fail:
fail_silent:
    return UNKNOWN_ERROR;
}
#endif

status_t CursorWindow::clear() {
    if (mReadOnly) {
Loading