SQLite User Forum

An assertion failure still needs to be handled
Login

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]

Hello developers,

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]

Supplement:

Here is the bisecting information of history commits for your reference:

[12980] e15f47064b good
[06490] f5c395834c good
[03245] c465d0eb47 good
[01622] 6b93627b5d bad
[02433] ab458a319f bad
[02839] 48ba5e5a22 bad
[03042] 9dc0d34586 good
[02940] ba27012d43 good
[02889] 4dbd398d64 bad
[02914] 16fef3db06 bad
[02927] 8bd75bf636 bad
[02933] 6aef58b629 bad
[02936] 0adb273f7e bad
[02938] 2c8af35206 good
[02937] 8f4a3750b7 bad

latest good : [02938] 2c8af35206

bad introduce : [02937] 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.