Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does SQLite leak memory with the SQLCipher extension?

I'm using SQLCipher to store an encrypted SQLite database. However, when I use sqlite3_key to encrypt the database, I start getting a memory leak. Observe the following sample:

#include <sqlite3.h>    

int main()
{
    sqlite3 * connection;
    sqlite3_open_v2(":memory:", &connection, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
    sqlite3_key(connection, "passphrase", 10);
    sqlite3_close(connection);
}

This sample produces a memory leak. If I remove the call to sqlite3_key, the memory leak disappears.

I've narrowed down some possible culprits:

  • Although the sample uses an in-memory database (hence ":memory:"), I see the same result when using file-based databases.
  • All of the return codes from the sqlite3_* calls are SQLITE_OK, meaning there aren't any errors.
  • The buffer length of 10 for "passphrase" is not the problem.

However, no matter how many connections I create or how many different encryption keys I use, the memory leak is always about 8 kilobytes. This leads me to suspect that this is not actually a memory leak, but just some constant global memory in SQLite/SQLCipher that doesn't get freed manually.

Has anyone experienced this before? Is there a way to get rid of the leak? Even if this is not an official memory leak, it's hard to detect real memory leaks with this present.

I'm using a SQLCipher library for Windows.

like image 1000
Elliot Cameron Avatar asked Nov 04 '22 19:11

Elliot Cameron


1 Answers

I've looked into this a bit further, and these reported leaks are a result of memory allocated by OpenSSL. Since SQLCipher doesn't know when the app is strictly done using it, EVP_cleanup() is not called, and the memory is reported by valgrind as a leak. We're working towards a simple fix that will try to identify when the OpenSSL structures are no longer in use by SQLCipher with some simple reference counting, so EVP_cleanup() can be called automatically.

As a quick workaround for this before the next release of SQLCipher, you could call EVP_cleanup() manually in the program before exiting.

like image 118
Stephen Lombardo Avatar answered Nov 08 '22 10:11

Stephen Lombardo