An assertion failure still needs to be handled
(1.1) By Wang Ke (krking) on 2022-01-16 01:55:11 edited from 1.0 [source]
I noticed a problem mentioned here.
It's about an assertion failure in vdbe.c. Through fuzzing for the latest development version with debug enabled, we found it seems that the problem hasn't been totally fixed.
For this testcase:
CREATE TABLE a(a1 PRIMARY KEY,a2); INSERT INTO a VALUES(1,5); CREATE TABLE b(b1 UNIQUE,b2); SELECT * FROM a LEFT JOIN b ON b2=NULL AND b2=5 WHERE (b1,substr(b.b1,1,1))==(SELECT 1024,'b');
It still causes:
sqlite3VdbeExec: Assertion `memIsValid(&aMem[pOp->p1])' failed.
(2.1) By Wang Ke (krking) on 2022-01-21 09:55:03 edited from 2.0 in reply to 1.1 [link] [source]
Here is the bisecting information of history commits for your reference:
 e15f47064b good  f5c395834c good  c465d0eb47 good  6b93627b5d bad  ab458a319f bad  48ba5e5a22 bad  9dc0d34586 good  ba27012d43 good  4dbd398d64 bad  16fef3db06 bad  8bd75bf636 bad  6aef58b629 bad  0adb273f7e bad  2c8af35206 good  8f4a3750b7 bad
latest good :  2c8af35206
bad introduce :  8f4a3750b7
It seems a little weird, since this commit didn't make any changes to the code, and I wonder if there's something wrong with my bisecting tool...
(3) By Richard Hipp (drh) on 2022-01-21 13:14:52 in reply to 2.1 [link] [source]
Thanks for bumping this. Somehow we missed it.
The following script does a better job of capturing the essence of the malfunction:
CREATE TABLE a(a1); INSERT INTO a VALUES(1); CREATE TABLE b(b1,b2,b3); INSERT INTO b(b1,b2,b3) VALUES(NULL,123,456); SELECT * FROM a LEFT JOIN b ON b1=NULL WHERE (b2,b3)==(SELECT 123, 456);
Using this script, I didn't have any trouble bisecting to check-in ddb5f0558c445699 from 2016-09-07, which makes logical sense. That was the check-in that added support for row-value comparisons.
(4) By Richard Hipp (drh) on 2022-01-21 13:29:57 in reply to 3 [link] [source]
I should add, for the benefit of people who worry about these things, that this is not a memory error. In other words, it is not a potential vulnerability. The assertion fault indicates that one of the byte-code registers was read before it was initialized by the byte-code itself. But because all the byte-code registers are initialized to NULL prior to starting up the byte-code engine, no harm comes of this use of an uninitialized byte-code register. The problem is with a byte-code register, not a CPU register. No CPU registers or memory are read while uninitialized, nor are there NULL pointer dereferences or array overruns or anything like that. This is a fault in the byte code only. The worst possible outcome is an incorrect answer (though with this particular malfunction, it appears that even the answer is correct).
So, in other words, rewriting in Rust/Go/Swift or some other memory-safe language would not have helped here.
Since the assert() that fails is only coded when you compile with SQLITE_DEBUG and hence does not appear in release builds, and because the correct answer is obtained without the assert(), this is not a pressing issue. The problem needs to be fixed, and I am very grateful to Wang Ke for bringing it to my attention. But it is not an emergency.
(5) By Richard Hipp (drh) on 2022-01-21 16:42:08 in reply to 1.1 [link] [source]
See check-in 4db5217a28ce767f for the fix.