Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attempt to write a readonly database, crashes on android 5.0v devices while using SqlCipher #161

Closed
praveenb opened this issue May 2, 2015 · 70 comments

Comments

@praveenb
Copy link

praveenb commented May 2, 2015

Im getting following log on app crash, on android 5.0v devices

Caused by: net.sqlcipher.database.SQLiteException: attempt to write a readonly database
at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2096)
at net.sqlcipher.database.SQLiteDatabase.(SQLiteDatabase.java:1962)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:881)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:913)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:132)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:99)
at PackageName.DBHelperCipher.(DBHelperCipher.java:93)
at PackageName.ProcessDBCipherInitTask.doInBackground(ProcessDBCipherInitTask.java:20)
at PackageName.ProcessDBCipherInitTask.doInBackground(ProcessDBCipherInitTask.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)

I've submitted a question on StackOverflow, http://stackoverflow.com/q/29988933/341443.
Can you please help on this.

Thank you.

@developernotes
Copy link
Member

Hello @praveenb

Are you able to replicate the crash on your 5.0 device when running the SQLCipher for Android test suite?

@praveenb
Copy link
Author

praveenb commented May 5, 2015

@developernotes Thank you so much for your kind reply,
I run the test suite on Android 5.0 device, Though I see a crash at some other test condition, I do not see a crash resulting error log given above. i.e I'm not able to replicate above crash.

Not sure where im doing mistake in my code. I think i need to investigate further in test suite to handle the issue in my project.

But, I just like to ask,.. you have any other suggestions or guidelines for me on this.

Thank you.

@developernotes
Copy link
Member

Hello @praveenb

Do you have a specific test case that is failing consistently in the test suite?

With regard to your specific scenario though, does the database file exist right before you initialize the DBHelperCipher instance?

@praveenb
Copy link
Author

praveenb commented May 8, 2015

@developernotes,

there is no database file exist before initialize the class...
Just for clarification, I published app to Play Store, I see app crashes, When I do a fresh install from play store, on a android 5.0v device.

I debugged the android-database-sqlcipher project, by giving external path, as shown below
public EventDataSQLHelper(Context context, String name, CursorFactory factory, int version) {
super(context, DB_PATH+DATABASE_NAME, null, DATABASE_VERSION);
}
**here DB_PATH constant refers to external path.

And I see the issue is occurring only when created db file on external storage,
see the issue occurring at this line
setLocale(Locale.getDefault()); in SQLiteDatabase file

Please let me any idea on this.

Thankyou

@developernotes
Copy link
Member

Hello @praveenb

I am wondering if there is an issue within the internals of getWritableDatabase(). As an experiment, could you try invoking SQLiteDatabase.openOrCreateDatabase(…); before you initialize your EventDataSQLHelper only when the database file does not exist before hand? Could you let us know your results? Thanks!

@praveenb
Copy link
Author

Im getting the same error, invoking SQLiteDatabase.openOrCreateDatabase(…); method

Thanks

@developernotes
Copy link
Member

Hello @praveenb

If you can prepare a test within the test suite, I would be glad to take a look at it on a Lollipop device.

@praveenb
Copy link
Author

Hi @developernotes ,

Please see this link https://github.com/praveenb/sqlcipher-android-tests, I added test class to test suite. Please see committed code changes.

Hi Nick, You are able to see issue on your side. or You see any issue in committed changes. Please reply on this.

FYI, I see this issue on Lenovo A7000, Lollipop device. Please help on this.

Thank you.

@chetan1011
Copy link

Hi @developernotes ,

I am getting the same error,error code 8: attempt to write a read only database

When I am write(Insert) record in database at this time I am getting this error in my lolipop device.

please help me ...

FYI, I see this issue on Lenovo A7000-a, Lollipop device. Please help on this.

@developernotes
Copy link
Member

Hello @chetan1011

Can you verify whether the database file exists before you attempt to write to it?

@praveenb
Copy link
Author

Hi @developernotes ,

You are able to look at the test suit changes that i made at this link https://github.com/praveenb/sqlcipher-android-tests.

Please let me know if you need any other details

Thank you.

@chetan1011
Copy link

Hello @developernotes ,

The database file was store in sdcard(External_storage)...
and i take permission in android manifest "android.permission.WRITE_EXTERNAL_STORAGE"

@developernotes
Copy link
Member

Hello @chetan1011

Can you verify whether the database file exists on the SD card prior to any attempts to interact with it via the SQLCipher API? Thanks!

@BenPope
Copy link

BenPope commented May 28, 2015

I'm having a similar problem on Android 5.0.2 with native (c++) sqlcipher 3.3.0.

ls -al /storage/emulated/0/Android/data/com.app.name/files/data.db
-rw-rw---- u0_a165  sdcard_r    38912 2015-05-28 21:31 data.db

I get an exception "attempt to write a readonly database".

It's weird. The app manages to write the database on startup.

It also fails miserably if I try to put it into EXCLUSIVE locking mode, could it somehow be trying to lock the file more than once?

@chetan1011
Copy link

Hello @developernotes ,

@developernotes Thank you so much for your kind reply,

Yes sir, i check database file is exist or not in sdcard...at that time database is exist in sdcard..

I mean database file is exist in sdcard...

still Im getting the same error, android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode.

This error got in only 5.0 (lolipop)version in android.

Please let me know if you need any other details

Thank you.

@brodybits
Copy link
Contributor

FYI the same problem (crash with net.sqlcipher.database.SQLiteException: attempt to write a readonly database) is also discussed in: https://discuss.zetetic.net/t/sqlcipher-on-android-5-0-x64-emulator-crash/286

still Im getting the same error, android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode.

@chetan1011 looks like it may be the same problem as #139.

@brodybits
Copy link
Contributor

According to the documentation in http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html, and also in the Javadoc, it is possible that SQLiteDatabase.openDatabase (and SQLiteDatabase.openOrCreateDatabase()) can throw a SQLiteException if it cannot open the database for some reason. It should be the responsibility of the application to catch and handle this error. I wonder if we should add throws SQLException to the declaration of these functions to avoid these crashes?

@chetan1011
Copy link

Hello brodybits,
Thank you so much for your kind reply,

I am use following code:
database = SQLiteDatabase.openOrCreateDatabase(db_path, "******",
null);
SQLiteStatement insertStmt = database.compileStatement(insertQuery);
recordId = insertStmt.executeInsert();

then i got "attempt to write a read only database"

if you hve any solution then please give me your solution ya any sample...

please help me dude...

@brodybits
Copy link
Contributor

@chetan1011 can you post the log to show where your application is failing?

@chetan1011
Copy link

HI @brodybits ,
bellow I post my log where i failing application..

05-29 17:55:20.391: W/System.err(4598): net.sqlcipher.database.SQLiteException: error code 8: attempt to write a readonly database
05-29 17:55:20.391: W/System.err(4598): at net.sqlcipher.database.SQLiteStatement.native_execute(Native Method)
05-29 17:55:20.391: W/System.err(4598): at net.sqlcipher.database.SQLiteStatement.executeInsert(SQLiteStatement.java:84)
05-29 17:55:20.391: W/System.err(4598): at com.esense.topscorer.scratchcard.QueryCreator.insertRecords(QueryCreator.java:94)
05-29 17:55:20.391: W/System.err(4598): at com.esense.topscorer.scratchcard.InsertImpl.runQuery(InsertImpl.java:18)
05-29 17:55:20.391: W/System.err(4598): at com.esense.topscorer.scratchcard.BaseAsyncDBOperation.doInBackground(BaseAsyncDBOperation.java:56)
05-29 17:55:20.391: W/System.err(4598): at com.esense.topscorer.scratchcard.BaseAsyncDBOperation.doInBackground(BaseAsyncDBOperation.java:1)
05-29 17:55:20.391: W/System.err(4598): at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-29 17:55:20.391: W/System.err(4598): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-29 17:55:20.391: W/System.err(4598): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-29 17:55:20.391: W/System.err(4598): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-29 17:55:20.391: W/System.err(4598): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-29 17:55:20.391: W/System.err(4598): at java.lang.Thread.run(Thread.java:818)

please help me..

@brodybits
Copy link
Contributor

@chetan1011, for some reason your case is different from the OP. In your case, openOrCreateDatabase() succeeds but insertStmt.executeInsert() is failing. Can you log and post the string value of db_path?

@chetan1011
Copy link

@brodybits dbpath is valid...

it's database file and it's exist in sdcard...

this code is working fine in all other version but.... it's just not working in 5.0 android version...

@brodybits
Copy link
Contributor

Just issued PR #174 with fixes to show where SQLiteDatabase.dbopen is actually failing. If you are having problems, please try again with these changes and report your results.

@developernotes
Copy link
Member

@chetan1011 you may want to hold off on #174 right now, there is still some work going on there.

brodybits pushed a commit to brodybits/android-database-sqlcipher that referenced this issue May 29, 2015
…n messages

Use throw_sqlite3_exception_errcode() if sqlite3_open_v2() fails
Needed to help diagnose exceptions in sqlcipher#139 & sqlcipher#161
Some credit to https://github.com/android/platform_frameworks_base/blob/master/core/jni/android_database_SQLiteConnection.cpp
@brodybits
Copy link
Contributor

Just reworked the changes in PR #175 to show where SQLiteDatabase.dbopen() is actually failing, waiting for review.

@developernotes
Copy link
Member

Hello @eyeled

Thank you for your feedback, we look forward to hearing your results on device.

@atultiwari
Copy link

Hi,
As mentioned in discussion forum, my app is crashing (at least in 2 known mobiles - Mi 4i and Lenovo Phab Plus) soon after it tries to access the database.
After some research and with the help of @developernotes reply in the discussion forum, I was finally able to get the App Crashing Error from Mi 4i mobile -
It said -

net.sqlcipher.database.SQLiteException: attempt to write a readonly database: DELETE failed setting locale

The Mi 4i device runs Android 5.0.2
After learning this.. I tried to reciprocate the same in x86_64 emulators of version 5.0.1 and 5.1.1.
Luckily no error is thrown in 5.1.1 and app works absolutely fine for me.

Unfortunately in Android 5.0.1 x86_64 emulator following error is displayed -

05-11 19:36:46.931 2995-2995/? D/QuestionBankDBHelper: Count Query = SELECT COUNT(*) as count FROM qbank
05-11 19:36:46.935 2995-2995/? I/Database: sqlite returned: error code = 28, msg = file renamed while open: /storage/sdcard/Download/mydata.db
05-11 19:36:47.071 2995-2995/? I/Database: sqlite returned: error code = 1032, msg = statement aborts at 3: [PRAGMA user_version = 1]
05-11 19:36:47.071 2995-2995/? E/Database: Failure 8 (attempt to write a readonly database) on 0xecf5f208 when executing 'PRAGMA user_version = 1'
05-11 19:36:47.072 2995-2995/? I/Database: sqlite returned: error code = 28, msg = file renamed while open: /storage/sdcard/Download/mydata.db

The same database is working fine in 4.2.2, 5.1.1, 6.0.1 etc.

This error appears to be slightly different than what is thrown in Mi 4i phone. But, one thing is sure.. there is some bug that is interfering with SQLCipher to work in Android 5.0.x

How I tested -
I have sqlcipher encrypted database, which is stored in External Storage. The errors are thrown, when being trying to access this database.

@kibergus
Copy link

kibergus commented May 18, 2016

Hi! We've encountered the same bug too. atultiwari, thank you very much for finding emulator in which the problem can be easily reproduced. That helped a lot. The error is actually in android headers. For android 19 they have:

android-ndk-r10d/platforms/android-19/arch-x86/usr/include/sys/types.h:typedef __kernel_ino_t       ino_t;
android-ndk-r10d/platforms/android-19/arch-x86/usr/include/asm/posix_types_32.h:typedef unsigned long __kernel_ino_t;

but

struct stat {
...
    unsigned long long  st_ino;
};

So ino_t is 4 bytes and stat.st_ino is 8 bytes wide. Sqlite trims inode number to 4 bytes when stores it and then compares with 8 byte wide inode number in fileHasMoved.

It seems, that in android 21 headers have been fixed:

android-ndk-r10d/platforms/android-21/arch-x86/usr/include/sys/types.h:typedef __kernel_ino_t __ino_t;
android-ndk-r10d/platforms/android-21/arch-x86/usr/include/sys/types.h:typedef __ino_t ino_t;
android-ndk-r10d/platforms/android-21/arch-x86/usr/include/asm-generic/posix_types.h:typedef __kernel_ulong_t __kernel_ino_t;
android-ndk-r10d/platforms/android-21/arch-x86/usr/include/asm/posix_types_x32.h:typedef unsigned long long __kernel_ulong_t;

So currently I see two solutions: good one is to use headers for android 21. But if that's inappropriate, then the problem can be solved by a hack in sqlite by explicitly converting stat.st_ino to (ino_t) in sqlite source.

@brodybits
Copy link
Contributor

+1 for using the android-21 headers

@atultiwari
Copy link

atultiwari commented May 18, 2016

@kibergus thank you for finding out the root cause of this issue. Being a medico, it is hard to understand it completely, but I did understand some basics about it.
I am curious, if somehow, I can make SQLCipher work with Android 5.0 (as suggested by you - using the android 21 headers), or will I have to wait for developers of SQLCipher to release some kind of patch?
Thanks.

@YuriZheng
Copy link

I get this issue on my phone, Android 5.0, I see @kibergus's answer, but i don't know how to deal with it,For using the android-21 headers ? How to do it?

@developernotes
Copy link
Member

Hi @atultiwari, @YuriZheng,

We will look into making the adjustment to the NDK API 21 within the android-n-preview soon.

@developernotes
Copy link
Member

Hi @atultiwari, @YuriZheng,

We have made some changes in the android-n-preview branch which include adjusting the target platform used within the Android NDK. Please feel free to try the android-n-preview to see if it addresses the issue you are seeing. Thanks!

@atultiwari
Copy link

atultiwari commented May 23, 2016

@developernotes thank you for your reply. I will try it in the evening and get back to you. It's 2 a.m. here, feeling very sleepy.
But, on a quick look. I am unable to figure out how to use android-n-preview? I mean previously I was using aar in Android studio, like -
compile 'net.zetetic:android-database-sqlcipher:3.4.0@aar'

But it seems, for android-n-preview I might have to compile sqlcipher myself, about which I have no idea.

@developernotes
Copy link
Member

Hello @atultiwari,

Yes, the android-n-preview branch is distributed in source only format. If you are interested in a zip build please feel free to email us at support@zetetic.net with your Discuss account.

@YuriZheng
Copy link

Hello @developernotes :
I download the source and build it myself. But it has this issue, I'm a java developer, so i'm poor of c and c++. If you solved this probrem, please let me know! I'm very worried. Thank you very much !!!

@umesh289
Copy link

@developernotes I too am facing this issue only on 5.0 devices.

05-24 15:46:30.494: I/Database(11744): sqlite returned: error code = 28, msg = file renamed while open: /storage/sdcard0/dummy1/db
05-24 15:46:30.503: I/Database(11744): sqlite returned: error code = 1032, msg = statement aborts at 8: [CREATE TABLE IF NOT EXISTS dummy_table1
.....
05-24 15:46:30.503: E/Database(11744): Failure 8 (attempt to write a readonly database) on 0xabb15250 when executing 'CREATE TABLE IF NOT EXISTS dummy_table2(rowid integer default -1, did integer

@developernotes
Copy link
Member

Hello @YuriZheng

If you are interested in our android-n-preview branch, we have instructions available here for accessing it.

@heutschibogdan
Copy link

Hi @developernotes ,

I am facing this problem using the latest version 3.5.4 on a sony device with android 5.0. net.sqlcipher.database.SQLiteException: error code 8: attempt to write a readonly database. Do you have any suggestions what I could try?

@developernotes
Copy link
Member

Hi @heutschibogdan

Are you able to create a small reproducible test case within the SQLCipher for Android test suite? If so, we would be happy to look into that further. Thanks!

@heutschibogdan
Copy link

Hi @developernotes

I've added a test case for this. It seems the problem is not really related to the sony device, as I've reproduced it on multiple android versions which have x86_64 system image. It seems there is a problem when using an external storage in this cases.

@gautamshrm3
Copy link

Hi Team,

We are facing the below issue may be the similar as previous

net.sqlcipher.database.SQLiteException: error code 8: attempt to write a readonly database

This issue we have only got in MI devices.

Please us ASAP.

@umesh0492
Copy link

umesh0492 commented Mar 15, 2017

Hi Team,

We are facing the below issue may be the similar as previous

net.sqlcipher.database.SQLiteException: error code 8: attempt to write a readonly database

Happens when app having multiple processes.

@sjlombardo
Copy link
Member

@umesh0492 are you saying that the application works if there is only a single process, but fails when there are multiple processes, even if the database location is the same?

@ArikYa
Copy link

ArikYa commented Sep 15, 2017

I'm having the same issue, also seems to be related to multi-processes application. Any update on this?

@developernotes
Copy link
Member

Hi @ArikYa

What version of SQLCipher for Android are you currently using?

@ArikYa
Copy link

ArikYa commented Sep 15, 2017

I use it through Requery, which uses 3.5.4

@developernotes
Copy link
Member

Hello @ArikYa

Please try the latest version of SQLCipher for Android, which is 3.5.7 and let us know your results. Thanks!

@dotw
Copy link

dotw commented Nov 20, 2017

Hello guys, I'm facing the same issue. I'm using the latest version 3.5.7 now.

11-20 17:48:54.719 12073-12218/com.hzqi.sango W/System.err: net.sqlcipher.database.SQLiteException: error code 8: attempt to write a readonly database
11-20 17:48:54.719 12073-12218/com.hzqi.sango W/System.err:     at net.sqlcipher.database.SQLiteStatement.native_execute(Native Method)
11-20 17:48:54.719 12073-12218/com.hzqi.sango W/System.err:     at net.sqlcipher.database.SQLiteStatement.execute(SQLiteStatement.java:58)
11-20 17:48:54.719 12073-12218/com.hzqi.sango W/System.err:     at net.sqlcipher.database.SQLiteDatabase.execSQL(SQLiteDatabase.java:2319)

@dotw
Copy link

dotw commented Nov 21, 2017

Struggling several hours then I found the issue is the database path.
I changed the path from
context.getApplicationInfo().dataDir + "/databases/" + DATABASE_NAME
to
context.getDatabasePath(DATABASE_NAME).getPath()
then, the exception is gone.

@developernotes
Copy link
Member

Hi @dotw

We are glad to hear you were able to resolve the issue. Thanks!

@sqlcipher sqlcipher locked and limited conversation to collaborators Nov 21, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests