Handle allocation failures in cipher registration and parameter table cloning - #277
LucaCappelletti94 wants to merge 1 commit into
Conversation
|
IMHO it would have been much better to start with reporting an issue instead of submitting this PR. That would have allowed to discuss what is actually an issue and what not, and how to solve it. I agree that there are (mainly theoretical) memory allocation issues, and checks should be introduced to guard against such events.
I prefer to keep separate allocations. It makes the code more readable, and reduces the risk of miscalculating the memory requirements in case of changes.
This link doesn't point to anything useful, but I think I understand what you mean.
Function
If the first allocation fails, the second will typically fail as well, and the second one is checked. However, I agree that both should be checked to be on the safe side.
You are right again. However, if the system is that short of memory, you are unlikely to be able to work with SQLite anyway. No excuse, but unlikely to cause crashes in real world applications. Nevertheless, the issue will be addressed, of course. |
|
A-Ok on issue first, and yes these issues only matter to very memory constrained settings (I am hitting them in a fuzzer where I am using a custom allocator designed to misbehave and find these things). These are arguably NOT urgent errors, just stuff I have collected as I am increasing the tests in the two I suppose in real life one could hit them in very constrained embedded systems, and even there it is pushing it. Sorry for the (functionally) dead link, I meant to link the relevant lines but I must have ended up copying the wrong thing at some point and I ended up not seeing it at the time. |
Of course, it is important to catch even unlikely issues. Therefore thank you for reporting your findings.
Sure. And as said I will address them. |
|
Commit 95b6a40 addresses the issues you detected. Thanks again for reporting. I applied fixes somewhat differently than you did in your PR, and added a few extra measures to make your The |
|
Thanks! I appreciate it! |
Description
This PR handles allocation failures during
sqlite3_initializeandsqlite3_openwithout NULL-pointer writes or SQL callbacks referencing freed cipher parameters. Failed initialization releases its partially registered ciphers so initialization can be retried. Cloned parameter tables share one allocation, owned by the connection and released throughsqlite3_free.Problem Statement
On main at
7a7f16a,sqlite3mcRegisterCipherpasses an unchecked allocation tostrcpy, andsqlite3mcCloneCodecParameterTablechecks only one of its two allocations before writing through both. A single failed allocation can crash initialization or connection opening.mcRegisterCodecExtensionsalso ignoressqlite3_set_clientdata's return value. That function invokes its supplied destructor on allocation failure, leaving SQL callbacks bound to freed parameters if registration continues. A failed initialization can also leaveglobalCipherCountinconsistent with the tables, causing a retry to returnSQLITE_OKwith an unusable cipher configuration.SQLite documents graceful allocation failure handling, allocation fault injection, and client-data destruction on allocation failure.
Verification
The included allocation-failure test fails each allocation in turn. Calls must return
SQLITE_OKorSQLITE_NOMEM, retried initialization must reproduce the clean-start cipher tables, and successfully opened connections must retain their cipher configuration. Run it withCompiled against the baseline sources with
-fsanitize=address,undefined, the test reportsThe configured build passes 40 initialization and 214 connection-opening failure points. The direct sanitizer build passes 40 and 34 respectively, with no AddressSanitizer, UndefinedBehaviorSanitizer, or leak reports. Allocation counts depend on enabled features.
Type of Change
Problem / Motivation
A required allocation failure should return
SQLITE_NOMEMwithout terminating the process or publishing incomplete cipher state. The regression test exercises this contract and initialization retries in the Unix CI job.Checklist