Skip to content
New issue

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

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

Already on GitHub? # to your account

[BUG] AesStream Invalid Password exception for corrupted log/data file #2343

Open
anurakt27 opened this issue Jul 18, 2023 · 1 comment
Open
Labels

Comments

@anurakt27
Copy link

anurakt27 commented Jul 18, 2023

Version
LiteDB version - v5.0.16
OS - Windows 11 (22H2 OS Build 22621.1992)
.NET version - .NET 6, .NET 462

Describe the bug
While creating a new data/log file, AesStream can potentially create a corrupted "hidden" page. Following is the corruption pattern in hidden page:

  • Byte 0 : 1
  • Byte 1-16: salt
  • Bytes 17-8191: 0

The occurrence of this corruption is very rare, however, the data/log file becomes irrecoverable and always throws "Invalid Password" exception.

Code to Reproduce
Simple code to create a new database with a collection called "User" and perform Insert operation.

using (var db = new LiteDatabase(new ConnectionString("FileName=test.litedb;Password=Test1234!;Connection=shared")))
{
      var collection = db.GetCollection<User>();
      collection.Insert(new User { Name = "TestUser" });
}

Reproduction of this issue requires dev to add a breakpoint to AesStream ctor and terminate the program as soon as breakpoint is hit for the first time.

Breakdown of issue that happens while AesStream creates new "hidden" page, and application terminates abruptly:

  1. Write bytes[0] as 1 - This is done to indicate that the stream is encrypted
  2. Write bytes[1..16] with Salt
  3. Fill bytes[17-8191] with 0 - This is done to add padding the stream to make the length equivalent to PAGE_SIZE
  4. Set position to 32 for writing encrypted 1s to the stream.
  5. Setting position of stream causes it to write to disk. This behavior was confirmed using Process Monitor tool.
  6. Terminate the program at this point.
  7. File of size 8KB is created, where bytes[17..8191] are empty.

Expected behavior

  1. Should not fill bytes[17-8191] with 0 to make it a multiple of PAGE_SIZE. The code seems to be capable of handling scenarios where length of stream is less than PAGE_SIZE.
  2. Should be able to recover itself from corrupted state.

Screenshots/Stacktrace
Stack Trace of Invalid Password Exception:

Unhandled exception. LiteDB.LiteException: Invalid password
   at LiteDB.Engine.AesStream..ctor(String password, Stream stream) in C:\stash\LiteDB\LiteDB\Engine\Disk\Streams\AesStream.cs:line 129
   at LiteDB.Engine.FileStreamFactory.GetStream(Boolean canWrite, Boolean sequencial) in C:\stash\LiteDB\LiteDB\Engine\Disk\StreamFactory\FileStreamFactory.cs:line 56
   at LiteDB.Engine.StreamPool.<>c__DisplayClass3_0.<.ctor>b__0() in C:\stash\LiteDB\LiteDB\Engine\Disk\StreamFactory\StreamPool.cs:line 29
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at LiteDB.Engine.StreamPool.get_Writer() in C:\stash\LiteDB\LiteDB\Engine\Disk\StreamFactory\StreamPool.cs:line 35
   at LiteDB.Engine.DiskService..ctor(EngineSettings settings, Int32[] memorySegmentSizes) in C:\stash\LiteDB\LiteDB\Engine\Disk\DiskService.cs:line 53
   at LiteDB.Engine.LiteEngine..ctor(EngineSettings settings) in C:\stash\LiteDB\LiteDB\Engine\LiteEngine.cs:line 70
   at LiteDB.SharedEngine.OpenDatabase() in C:\stash\LiteDB\LiteDB\Client\Shared\SharedEngine.cs:line 63
   at LiteDB.SharedEngine.Insert(String collection, IEnumerable`1 docs, BsonAutoId autoId) in C:\stash\LiteDB\LiteDB\Client\Shared\SharedEngine.cs:line 214
   at LiteDB.LiteCollection`1.Insert(T entity) in C:\stash\LiteDB\LiteDB\Client\Database\Collections\Insert.cs:line 20
   at Test.Program.Main(String[] args) in C:\stash\LiteDB\Test\Program.cs:line 13

test.litedb file after performing the reproduction steps (all bytes are empty after the 17th byte):
image

@anurakt27
Copy link
Author

PR #2344 contains the fix

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

No branches or pull requests

1 participant