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

[BUG] Rebuild causes inconsistent state if password changed #1933

Open
Zeke133 opened this issue Feb 3, 2021 · 0 comments
Open

[BUG] Rebuild causes inconsistent state if password changed #1933

Zeke133 opened this issue Feb 3, 2021 · 0 comments
Labels

Comments

@Zeke133
Copy link

Zeke133 commented Feb 3, 2021

Version
LiteDB 5.0.10
Windows 10
UWP

Describe the bug
DB rebuild procedure with password change brings DB files to an inconsistent state.
Data-file is disposed of and recreated with a new password during DB rebuild.
Log-file stays to be encrypted with an old password not looking at the fact that the old password already replaced in settings and isn't stored anywhere.
The problem is basically solved after LiteDatabase.Dispose() called. Data is checked-out from log-file to data-file and log-file is removed if it's empty. This usually prevents log-file to stay encrypted with the old passwords on subsequent DB start.
The problem appears if DB used in the UWP application. There is no exact point of application termination so not possible to call Dispose() manually. So it is disposed of later after the application closed with boilerplate code from the destructor called with GC.

Here is a scenario to trigger the problem:

  • User changed the password in the application and closed it.
  • LiteDatabase.Dispose() is not called exactly after the application was closed. It will be called later on object destruction.
  • User runs the application again and tries to manipulate some data or change the password again.
  • "Invalid exception" will be thrown with AES stream trying to read log-file data encrypted with old password.

The same situation should happen in any other kind of application that was unexpectedly terminated or killed after the password change procedure.

Code to Reproduce
I've created a dummy UWP application to show the reproduction of this problem. Please look at this GitHub repo.

private async Task RebuildStorageAsync(string newPassword)
{
    LiteDB.Engine.RebuildOptions rebuildOptions = new LiteDB.Engine.RebuildOptions
    {
        Password = newPassword
    };
    await Task.Run(() => Database.Rebuild(rebuildOptions)).ConfigureAwait(false);
}

Expected behavior
Log-file should be re-created with a new password during rebuild procedure the same way as data-file does. It will prevent an inconsistent state to appear. DB state will not depend on time and necessity of Dispose() call.

Screenshots/Stacktrace

   at LiteDB.Engine.AesStream..ctor(String password, Stream stream)
   at LiteDB.Engine.FileStreamFactory.GetStream(Boolean canWrite, Boolean sequencial)
   at LiteDB.Engine.StreamPool.<>c__DisplayClass3_0.<.ctor>b__0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.CreateValue()
   at LiteDB.Engine.DiskService.SetLength(Int64 length, FileOrigin origin)
   at LiteDB.Engine.WalIndexService.Clear()
   at LiteDB.Engine.LiteEngine.RebuildContent(IFileReader reader)
   at LiteDB.Engine.LiteEngine.Rebuild(RebuildOptions options)
   at LiteDB.LiteDatabase.Rebuild(RebuildOptions options)

Additional context
I propose a fix for this issue in pull-request #1934.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant