Crash of SQLCipher 3.5.1 with armeabi .so file

SQLCipher 3.5.1 works great in Nexus 6 (Android N Preview version), thank you for your team’s effort. But it always crashes in other phones when I try to use armeabi - not armeabi-v7a.

I didn’t use aar file because my android app is based on Eclipse. I found that your example project runs with jar + so files, so I used them.
https://github.com/sqlcipher/sqlcipher-android-tests

All .so files in my app are based on armeabi, so I made armeabi folder only (with libsqlcipher.so file, indeed) and it crashes here : SQLiteDatabase.loadLibs(this); But when I use armeabi-v7a .so file, there is no problem at all. Can you tell me what I did wrong? All the other .so files are based on armeabi, so I don’t want to change them all.

I used Samsung Galaxy S6 Edge(SM-G925S : android v5.1.1) and Samsung Galaxy J(SC-02F : android v4.4.2) for test. Here is the crash log.

06-29 15:34:51.360: I/InjectionManager(696): Inside getClassLibPath + mLibMap{0=, 1=}
06-29 15:34:51.360: I/InjectionManager(696): Inside getClassLibPath caller 
06-29 15:34:51.370: D/InjectionManager(696): InjectionManager
06-29 15:34:51.370: D/InjectionManager(696): fillFeatureStoreMap com.example.sqltest
06-29 15:34:51.370: I/InjectionManager(696): Constructor com.example.sqltest, Feature store :{}
06-29 15:34:51.370: I/InjectionManager(696): featureStore :{}
06-29 15:34:51.380: D/SecWifiDisplayUtil(696): Metadata value : SecSettings2
06-29 15:34:51.390: D/PhoneWindow(696): *FMB* installDecor mIsFloating : false
06-29 15:34:51.390: D/PhoneWindow(696): *FMB* installDecor flags : -2139029248
06-29 15:34:51.400: W/linker(696): libsqlcipher.so: unused DT entry: type 0x6ffffffe arg 0x1f440
06-29 15:34:51.400: W/linker(696): libsqlcipher.so: unused DT entry: type 0x6fffffff arg 0x3
06-29 15:34:51.400: E/art(696): dlopen("/data/app/com.example.sqltest-2/lib/arm/libsqlcipher.so", RTLD_LAZY) failed: dlopen failed: unknown reloc type 160 @ 0xef643a80 (6332)
06-29 15:34:51.410: D/AndroidRuntime(696): Shutting down VM
06-29 15:34:51.410: E/AndroidRuntime(696): FATAL EXCEPTION: main
06-29 15:34:51.410: E/AndroidRuntime(696): Process: com.example.sqltest, PID: 696
06-29 15:34:51.410: E/AndroidRuntime(696): java.lang.UnsatisfiedLinkError: dlopen failed: unknown reloc type 160 @ 0xef643a80 (6332)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at java.lang.Runtime.loadLibrary(Runtime.java:371)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at java.lang.System.loadLibrary(System.java:988)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at net.sqlcipher.database.SQLiteDatabase.loadLibs(SQLiteDatabase.java:177)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at net.sqlcipher.database.SQLiteDatabase.loadLibs(SQLiteDatabase.java:170)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at com.example.sqltest.MainActivity.onCreate(MainActivity.java:16)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.Activity.performCreate(Activity.java:6500)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1120)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3072)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3218)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.ActivityThread.access$1000(ActivityThread.java:198)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1676)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.os.Handler.dispatchMessage(Handler.java:102)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.os.Looper.loop(Looper.java:145)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at android.app.ActivityThread.main(ActivityThread.java:6837)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at java.lang.reflect.Method.invoke(Native Method)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at java.lang.reflect.Method.invoke(Method.java:372)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
06-29 15:34:51.410: E/AndroidRuntime(696): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

Thank you in advance.

Hi @Wontae_Kim

Can you please provide a screenshot showing how you have your native libraries structured? The native armeabi library should work within the armeabi-v7a folder, however there is no reason to do that because we include support for both armeabi, armeabi-v7a, and x86, so you should be able to include the respective native libraries within their different folders.

It has no problem with both folders, armeabi and armeabi-v7a.

But if I remove armeabi-v7a folder to use armeabi and run, app crashes. Here is the MD5 hash for more information.

MD5(armeabi/libsqlcipher.so)= 981ee6bec6f37ea451455b038a3b2f1e
MD5(armeabi-v7a/libsqlcipher.so)= 1d05bb24aecc4361794b0507b99206f0
MD5(sqlcipher.jar)= 60ec1f3db92c432eef477eece6c089d3

Hi @Wontae_Kim

Why are you removing the armeabi-v7a folder? All folders can be present when the application is compiled and packaged.

Hi, @developernotes

It is because I have four other .so files and they’re for armeabi platform. Without removing the armeabi-v7a folder I have to request each library developers or teams to build library files for armeabi-v7a platform. The process will be much simpler if I can use sqlcipher for armeabi platform, so I removed armeabi-v7a folder and tried to use armeabi libraries. :sweat: Also size of apk matters.

Hi @Wontae_Kim

That is very strange, I was just able to reproduce that with the SQLCipher for Android test suite when only the armeabi native platform is included by itself. We will look into this issue further. Thanks!

Hello @Wontae_Kim

I believe I’ve isolated the issue. Are you using the community edition, or the commercial edition of SQLCipher?

Hi @developernotes

Thank you for your testing! I used jar file and .so files found from here : https://github.com/sqlcipher/sqlcipher-android-tests

Hi @Wontae_Kim

Would you try the latest binaries I have pushed to the SQLCipher for Android test suite? I would like to know if it addresses the issue you are seeing? Thanks!

Hello, @developernotes

Initialization fail has disappeared with new .so and jar files. But when I try to open a DB with password, an exception occurs :

E/DB      (18545): file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
E/DB      (18545): net.sqlcipher.database.SQLiteException: file is encrypted or is not a database: , while compiling: select count(*) from sqlite_master;
E/DB      (18545): 	at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:83)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:49)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1762)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1727)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2344)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1091)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1032)
E/DB      (18545): 	at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1008)

I found some different codes of my app than your test app. So I changed my codes for opening DB file from :

SQLiteDatabase db = SQLiteDatabase.openDatabase(path, secKey, null,
            SQLiteDatabase.OPEN_READWRITE
                    | SQLiteDatabase.CREATE_IF_NECESSARY
                    | SQLiteDatabase.NO_LOCALIZED_COLLATORS, null);

to

SQLiteDatabase db = SQLiteDatabase.openDatabase(path, secKey, null,
        SQLiteDatabase.OPEN_READWRITE
                | SQLiteDatabase.CREATE_IF_NECESSARY
                | SQLiteDatabase.NO_LOCALIZED_COLLATORS, new SQLiteDatabaseHook() {
            @Override
            public void preKey(SQLiteDatabase database) {}

            @Override
            public void postKey(SQLiteDatabase database) {
                database.rawExecSQL("PRAGMA cipher = 'aes-128-cbc'");
            }
        });

and it’s working. :slight_smile: If an issue occurred I’ll let you know the situation. Thank you.

And one more thing : your test app didn’t go well without armeabi-v7 folder. At first launch all test cases are passed, but when I quit the app and re-launch, Cipher Migrate Test has failed.

I attached two log files of each cases.

Samsung Galaxy J(SC-02F : android v4.4.2) is used for test.

Hello @Wontae_Kim

Thank you for your feedback and test verification. We will look into the test to make sure resources are properly cleaned up to allow for repeatable runs.