Two issues: - Binding a UTF-16 string of size 0x80000000U results in a integer overflow in sqlite3VdbeMemSetStr() - Binding a UTF-8 string of size 0x7fffffff in SQLITE_TRANSIENT mode results in a integer overflow in sqlite3VdbeMemSetStr() 1) Build sqlite3 (3.35.5 here), on 64 bit, with CFLAGS="-DSQLITE_MAX_LENGTH=2147483647 -ftrapv -g" ./configure 2) Build the following test program: #include <assert.h> #include <sqlite3.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { sqlite3* db = NULL; sqlite3_stmt* stmt = NULL; char* bigtext; int rc; rc = sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_READWRITE, NULL); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE t(c)", NULL, NULL, NULL); assert(rc == SQLITE_OK); rc = sqlite3_prepare_v2(db, "INSERT INTO t VALUES (?)", -1, &stmt, NULL); assert(rc == SQLITE_OK); bigtext = malloc( 0x80000000U + 2 ); assert(bigtext); memset(bigtext, 1, 0x80000000U ); bigtext[0x80000000U + 0] = 0; bigtext[0x80000000U + 1] = 0; rc = sqlite3_bind_text16(stmt, 1, bigtext, -1, SQLITE_STATIC); assert(rc == SQLITE_OK); return 0; } 3) LD_LIBRARY_PATH=$PWD/.libs gdb ./test (gdb) r Program received signal SIGABRT, Aborted. __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 50 ../sysdeps/unix/sysv/linux/raise.c: Aucun fichier ou dossier de ce type. (gdb) bt #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 #1 0x00007ffff7c4c859 in __GI_abort () at abort.c:79 #2 0x00007ffff7e539da in __addvsi3.cold () from /home/even/sqlite-autoconf-3350500/.libs/libsqlite3.so.0 #3 0x00007ffff7e8c905 in sqlite3VdbeMemSetStr (pMem=0x555555567350, z=0x7fff77aac010 '\001' <repeats 200 times>..., n=-1, enc=2 '\002', xDel=0x0) at sqlite3.c:77568 #4 0x00007ffff7e96e14 in bindText (pStmt=0x555555566b08, i=1, zData=0x7fff77aac010, nData=-1, xDel=0x0, encoding=2 '\002') at sqlite3.c:85016 #5 0x00007ffff7e97295 in sqlite3_bind_text16 (pStmt=0x555555566b08, i=1, zData=0x7fff77aac010, nData=-1, xDel=0x0) at sqlite3.c:85145 #6 0x00005555555553b9 in main () (gdb) up #1 0x00007ffff7c4c859 in __GI_abort () at abort.c:79 79 abort.c: Aucun fichier ou dossier de ce type. (gdb) #2 0x00007ffff7e539da in __addvsi3.cold () from /home/even/sqlite-autoconf-3350500/.libs/libsqlite3.so.0 (gdb) #3 0x00007ffff7e8c905 in sqlite3VdbeMemSetStr (pMem=0x555555567350, z=0x7fff77aac010 '\001' <repeats 200 times>..., n=-1, enc=2 '\002', xDel=0x0) at sqlite3.c:77568 77568 for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} (gdb) print nByte $1 = 2147483646 Proposed fix: u32 nByteU; for(nByteU=0; nByteU<=(u32)iLimit && (z[nByteU] | z[nByteU+1]); nByteU+=2){} nByte = (int)MIN((u32)iLimit, nByteU); 4) Build the test program: #include <assert.h> #include <sqlite3.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { sqlite3* db = NULL; sqlite3_stmt* stmt = NULL; char* bigtext; int rc; rc = sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_READWRITE, NULL); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE t(c)", NULL, NULL, NULL); assert(rc == SQLITE_OK); rc = sqlite3_prepare_v2(db, "INSERT INTO t VALUES (?)", -1, &stmt, NULL); assert(rc == SQLITE_OK); bigtext = malloc( 0x7FFFFFFFU + 1 ); assert(bigtext); memset(bigtext, 1, 0x7FFFFFFFU ); bigtext[0x7FFFFFFFU] = 0; rc = sqlite3_bind_text(stmt, 1, bigtext, -1, SQLITE_TRANSIENT); assert(rc == SQLITE_OK); return 0; } 5) LD_LIBRARY_PATH=$PWD/.libs gdb ./test (gdb) r Program received signal SIGSEGV, Segmentation fault. __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:503 503 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: Aucun fichier ou dossier de ce type. (gdb) bt #0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:503 #1 0x00007ffff7e8c9d9 in sqlite3VdbeMemSetStr (pMem=0x555555567350, z=0x7fff77aac010 '\001' <repeats 200 times>..., n=-1, enc=1 '\001', xDel=0xffffffffffffffff) at sqlite3.c:77591 #2 0x00007ffff7e96e14 in bindText (pStmt=0x555555566b08, i=1, zData=0x7fff77aac010, nData=-1, xDel=0xffffffffffffffff, encoding=1 '\001') at sqlite3.c:85016 #3 0x00007ffff7e971d1 in sqlite3_bind_text (pStmt=0x555555566b08, i=1, zData=0x7fff77aac010 '\001' <repeats 200 times>..., nData=-1, xDel=0xffffffffffffffff) at sqlite3.c:85119 #4 0x00005555555553a9 in main () (gdb) up #1 0x00007ffff7e8c9d9 in sqlite3VdbeMemSetStr (pMem=0x555555567350, z=0x7fff77aac010 '\001' <repeats 200 times>..., n=-1, enc=1 '\001', xDel=0xffffffffffffffff) at sqlite3.c:77591 77591 memcpy(pMem->z, z, nAlloc); (gdb) print nAlloc $1 = 2147483648 (gdb) print pMem->n $4 = 0 The issue is that the (int)MAX(nAlloc,32) at line 77588 evaluates to 0. And the probably root cause if the "if( nByte>iLimit ){" check at line 77582 that should be "if( nAlloc>(u32)iLimit ){"