Calling sqlite_key () function returns slowly.
After the linux system is powered on, calling sqlite3_open function and calling sqlite_key function, it is found that calling sqlite_key returns very slowly, and the reason is that the value of/proc/sys/kernel/random/entropy _ avail has not reached 128. In this case, how can I make sqlite_key return quickly?
Could you please provide more detailed information about your environment?
- Which Linux distribution are you using?
- Which version of wxSQLite3 are you using?
- Which version of wxWidgets are you using?
- Which compiler version are you using?
- Which cipher scheme of wxSQLite3 are you using?
After the linux system is powered on, calling sqlite3_open function and calling sqlite_key function, it is found that calling sqlite_key returns very slowly, and the reason is that the value of/proc/sys/kernel/random/entropy _ avail has not reached 128.
Hm, usually the number of available entropy bytes is only low in a very early stage of system initialization. It is not very typical for wxWidgets-based applications to be called that early during system start. At least up to now you are the first reporting such a problem. Could you please describe the nature of your application?
In this case, how can I make sqlite_key return quickly?
First, it would be necessary to know, which method to retrieve entropy is used. Could you provide a call stack, so that it becomes clear which implementation within function entropy() is used? The code of function entropy() looks like this:
static size_t entropy(void* buf, size_t n)
{
#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
if (SecRandomCopyBytes(kSecRandomDefault, n, (uint8_t*) buf) == 0)
return n;
#elif defined(__linux__) && defined(SYS_getrandom)
if (syscall(SYS_getrandom, buf, n, 0) == n)
return n;
#elif defined(__linux__) && defined(SYS_getentropy)
if (syscall(SYS_getentropy, buf, n) == 0)
return n;
#endif
return read_urandom(buf, n);
For Linux systems there are 3 possibilities:
syscall(SYS_getrandom,...)syscall(SYS_getentropy,...)read_urandom(buf, n)
Which one is it in your case?
Actually, only 44 bytes of entropy are asked for in the underlying code of wxSQLite3. So, it is unclear why your system blocks until /proc/sys/kernel/random/entropy_avail has reached 128 - at least this variable is not queried by wxSQLite3 itself..
Closing, because no further details were provided. IMHO there nothing wrong with wxSQLite3 here.
Sorry, I replied earlier, but maybe because of network problems, I didn't update the content of the reply to github. The following is my last reply. Calling the sqlite_key () function returns a slow thank-you reply. I found that the entropy function came to the branch of # elifdefined (Linux)&& defined (sys _ getrandom) by using printf to print logs. Then it got stuck here for 2 minutes.
The kernel version is 4.19. gcc version:9.4.0 Database version: 3.47.1 I don't know the rest of the versions. I changed syscall(SYS_getrandom,bufmn,0) to read_urandom(buf,n). There is no problem after such modification.
At present, I have also encountered a problem. When calling the sqlite_key function during system startup, this log display occasionally appears. Setting key failed,Encryption is not supported by the VFS 。 The probability of this log appearing is very low.
Sorry, I replied earlier, but maybe because of network problems, I didn't update the content of the reply to github.
Well, as you could check for yourself, your reply wasn't visible on GitHub.
The following is my last reply. Calling the sqlite_key () function returns a slow thank-you reply.
What do you mean by "thank-you" reply. sqlite3_key() returns SQLITE_OK(= 0) in case of success.
I found that the entropy function came to the branch of # elifdefined (Linux)&& defined (sys _ getrandom) by using printf to print logs. Then it got stuck here for 2 minutes.
As far as I know getrandom blocks, if not enough entropy is available. But this should usually only happen, if you call it very early during system startup. I don't have the slightest idea, why this takes 2 minutes.
The kernel version is 4.19.
This is really a very old kernel version. The LTS release reached its end of life (EOL) in December 2024. There seems to be a SLTS release, which gets support until January 2029. However, this old kernel version could well be the cause of the problems you experience.
gcc version:9.4.0
The C compiler version is less important, although it is also quite dated.
Database version: 3.47.1
There was never a release of wxSQLite3 combined with SQLite 3.47.1. Therefore I suspect that you actually use SQLite3 Multiple Ciphers 1.9.1.
In principle, you can continue to use that version. However, both SQLite and SQLite3 Multiple Ciphers received important updates in the meantime.
I don't know the rest of the versions.
I understand that regarding wxSQLite3 and wxWidgets, because most likely you are not using them at all. However, you should be able to tell, which Linux distribution you are using.
I changed syscall(SYS_getrandom,bufmn,0) to read_urandom(buf,n). There is no problem after such modification.
As said above, I suspect that the problem may be related to the dated kernel version of your system.
At present, I have also encountered a problem. When calling the sqlite_key function during system startup, this log display occasionally appears. Setting key failed,Encryption is not supported by the VFS 。 The probability of this log appearing is very low.
Without knowing what exactly your application is doing, it is nearly impossible to guess what is going on. However, another user detected end of February a race condition in a multi-threaded environment. The issue was fixed in SQLite3 Multiple Ciphers 2.1.0.
Maybe upgrading to the latest version (2.1.3) solves this issue.
The kernel version is 4.19. [...]
As said above, I suspect that the problem may be related to the dated kernel version of your system.
In the meantime I did some research. AFAICT it is definitely a kernel issue. For kernel versions below 5.6 the getrandom method blocks, until the CRNG is fully initialized - and that can take quite a while. For kernel versions 5.6 and above getrandom does block only until enough random data is available, not until CRNG is fully initialized. However, this means that the random data retrieved are potentially cryptographically insecure (by the way, the same holds true for reading /dev/urandom).
In theory, it would be possible to detect the kernel version at runtime and to call getrandom only, if the kernel version is 5.6 or higher. However, you are the first and only user reporting this issue. Therefore, you are free to implement such a check on your own, if you really have to stick with kernel version 4.19, but I don't intend to add such a check in the official source base of SQLite3 Multiple Ciphers.
Conclusion: use one of the following approaches:
- Live with the application blocking until CRNG is fully initialized
- Upgrade your system to a kernel version 5.6 or higher
- Remove the code for calling
getrandomand useread_urandominstead - Add a check for the kernel version and call
read_urandomif the version is below 5.6
The kernel version is 4.19. [...]
As said above, I suspect that the problem may be related to the dated kernel version of your system.
In the meantime I did some research. AFAICT it is definitely a kernel issue. For kernel versions below 5.6 the
getrandommethod blocks, until the CRNG is fully initialized - and that can take quite a while. For kernel versions 5.6 and abovegetrandomdoes block only until enough random data is available, not until CRNG is fully initialized. However, this means that the random data retrieved are potentially cryptographically insecure (by the way, the same holds true for reading/dev/urandom).In theory, it would be possible to detect the kernel version at runtime and to call
getrandomonly, if the kernel version is 5.6 or higher. However, you are the first and only user reporting this issue. Therefore, you are free to implement such a check on your own, if you really have to stick with kernel version 4.19, but I don't intend to add such a check in the official source base of SQLite3 Multiple Ciphers.Conclusion: use one of the following approaches:
- Live with the application blocking until CRNG is fully initialized
- Upgrade your system to a kernel version 5.6 or higher
- Remove the code for calling
getrandomand useread_urandominstead- Add a check for the kernel version and call
read_urandomif the version is below 5.6
==>The kernel version can't be updated for the time being. I'll adopt read_urandom for the time being.
At present, I have also encountered a problem. When calling the sqlite_key function during system startup, this log display occasionally appears. Setting key failed,Encryption is not supported by the VFS 。 The probability of this log appearing is very low.
Without knowing what exactly your application is doing, it is nearly impossible to guess what is going on. However, another user detected end of February a race condition in a multi-threaded environment. The issue was fixed in SQLite3 Multiple Ciphers 2.1.0.
Maybe upgrading to the latest version (2.1.3) solves this issue.
==》I guess it may also be caused by multithreading. I will use the latest code to confirm.