yapstudios / YapDatabase

YapDB is a collection/key/value store with a plugin architecture. It's built atop sqlite, for Swift & objective-c developers.
Other
3.35k stars 365 forks source link

YapDatabase went corrupt across app launch #452

Open sameeragrawal opened 6 years ago

sameeragrawal commented 6 years ago

We are using YapDatabase v2.9.1 in our iOS app. Two of our app installations (both on iOS 11.3) reported YapDatabase going corrupt, and used the default CorruptAction (Rename) and created new database file.

The previous app session's log has: YapDatabase: Error in sqlite_close: 5 unable to close due to unfinalized statements or unfinished backups

This happened to both the databases that we use in the app, for both the installations.

Please help us understand, in what circumstances this is likely to happen, and how to really recover the database in this case.

sameeragrawal commented 6 years ago

Further update

Seeing the following behavior consistently, in this scenario:

Environment: iPhone running iOS 11.3

chrisballinger commented 6 years ago

Huh. You're using NSFileProtectionCompleteUntilFirstUserAuthentication? https://developer.apple.com/documentation/foundation/nsfileprotectioncompleteuntilfirstuserauthentication https://developer.apple.com/documentation/foundation/nsfileprotectioncompleteuntilfirstuserauthentication

On Thu, May 3, 2018 at 12:54 PM, sameeragrawal notifications@github.com wrote:

Further update

Seeing the following behavior consistently, in this scenario:

  • Phone has passcode set up
  • launch the app
  • without killing the app, reboot the phone. Do not enter the passcode yet
  • App wakes up in background, due to silent Push notification received
  • in the boot path (didfinishlaunchingwithoptions), DB open is failing. However, YapDatabase is able to rename the underlying DB file

Environment: iPhone running iOS 11.3

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/yapstudios/YapDatabase/issues/452#issuecomment-386416637, or mute the thread https://github.com/notifications/unsubscribe-auth/AAfqH-ujL8Bqibvje9dWO_gFMKahIv4_ks5tu2CMgaJpZM4TNr48 .

sameeragrawal commented 6 years ago

Do you mean on the database file? No, we do not set any attributes on the database file created by YapDatabase or underlying SQLite.

robbiehanson commented 6 years ago
  • without killing the app, reboot the phone. Do not enter the passcode yet
  • App wakes up in background, due to silent Push notification received

Are you using encryption? SQLCipher?

And if so, will the encryption key routine require access to the keychain? Which it won't have yet (I don't think)...

fmessina commented 6 years ago
  • without killing the app, reboot the phone. Do not enter the passcode yet
  • App wakes up in background, due to silent Push notification received

Our app was suffering the same problem. We are using SQLCipher to encrypt the DB and the material used to decrypt it is stored in the keychain with the property kSecAttrAccessible = kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly

Our solution was to use YapDatabaseCorruptAction_Fail as corruptAction and simply exit the app if the app is launched and a database is not created properly.

It a bit brutal but it works really well. Otherwise you need to change the accessibility of the keys stored in the keychain to something like kSecAttrAccessibleAlwaysThisDeviceOnly

robbiehanson commented 6 years ago

Thank you @fmessina , that's valuable information for the community.

sameeragrawal commented 6 years ago

We are not using SQLCipher either. However, this:

Our solution was to use YapDatabaseCorruptAction_Fail as corruptAction and simply exit the app if the app is launched and a database is not created properly.

is what we too implemented to protect the data in this situation.