SQLite Forum

Segmentation-Fault with prepared statement
Login

Segmentation-Fault with prepared statement

(1.1) By Jens (jens1205) on 2020-12-21 20:52:01 edited from 1.0 [link] [source]

Pi-Hole is using sqlite3, especially in its FTL component (see https://github.com/pi-hole/FTL).

I can reproduce a segmentation fault in pihole ftl, which looks like it's comming from sqlite 3. For details of the bug is submitted to pihole-ftl, please see https://github.com/pi-hole/FTL/issues/987.

The pihole-ftl developer thinks this is a bug of sqlite3.

Backtrace from gdb:

#0  unlink_chunk (p=p@entry=0xffff7c0629d0, av=0xffff7c000020) at malloc.c:1459
#1  0x0000ffff957fe5d8 in _int_malloc (av=av@entry=0xffff7c000020, bytes=bytes@entry=264) at malloc.c:4041
#2  0x0000ffff957ff69c in __GI___libc_malloc (bytes=bytes@entry=264) at malloc.c:3066
#3  0x0000aaaab8f1e1cc in sqlite3MemMalloc (nByte=256) at /root/project/src/database/sqlite3.c:23508
#4  0x0000aaaab8efef10 in dbMallocRawFinish (db=0xffff7c025d48, n=<optimized out>) at /root/project/src/database/sqlite3.c:27680
#5  0x0000aaaab8f0663c in exprDup (db=0xffff7c025d48, p=0xffff7c058608, dupFlags=1, pzBuffer=0x0)
    at /root/project/src/database/sqlite3.c:99950
#6  0x0000aaaab8f05b58 in sqlite3ExprDup (flags=1, p=<optimized out>, db=0xffff7c025d48)
    at /root/project/src/database/sqlite3.c:100113
#7  sqlite3SrcListDup (db=db@entry=0xffff7c025d48, p=0xffff937f2128, flags=-1192298888, flags@entry=1)
    at /root/project/src/database/sqlite3.c:34665
#8  0x0000aaaab8f05eec in sqlite3SelectDup (db=db@entry=0xffff7c025d48, pDup=pDup@entry=0xffff7c04b458, flags=flags@entry=1)
    at /root/project/src/database/sqlite3.c:100242
#9  0x0000aaaab8f77f40 in sqlite3CreateView (pBegin=0xffff937f1750, noErr=<optimized out>, isTemp=<optimized out>,
    pSelect=0xffff7c04b458, pCNames=0x0, pName2=0xffff937f17c8, pName1=0xffff937f17b0, pParse=0xffff937f2128)
    at /root/project/src/database/sqlite3.c:111633
#10 yy_reduce (yyLookahead=<optimized out>, pParse=0xffff937f2128, yyLookaheadToken=..., yyruleno=80, yypParser=0xffff937f1820)
    at /root/project/src/database/sqlite3.c:24804
#11 sqlite3Parser (yyminor=..., yymajor=<optimized out>, yyp=0xffff937f1820) at /root/project/src/database/sqlite3.c:26109
#12 sqlite3RunParser (pParse=pParse@entry=0xffff937f2128, zSql=<optimized out>, zSql@entry=0x0,
    pzErrMsg=pzErrMsg@entry=0xffff937f2190) at /root/project/src/database/sqlite3.c:27383
#13 0x0000aaaab8f78e98 in sqlite3Prepare (db=db@entry=0xffff7c025d48, zSql=0x0, nBytes=nBytes@entry=-1,
    prepFlags=prepFlags@entry=0, pReprepare=pReprepare@entry=0x0, ppStmt=0x0, ppStmt@entry=0xffff937f2340,
    pzTail=pzTail@entry=0x0) at /root/project/src/database/sqlite3.c:127575
#14 0x0000aaaab8f799f0 in sqlite3InitCallback (pInit=0xffff937f2440, argc=<optimized out>, argv=0xffff7c0842b0,
    NotUsed=<optimized out>) at /root/project/src/database/sqlite3.c:127055
#15 0x0000aaaab8f87c74 in sqlite3_exec (db=0x0, zSql=<optimized out>, xCallback=0xaaaab90ed000 <clock_gettime@got.plt>,
    pArg=0x0, pzErrMsg=0x0) at /root/project/src/database/sqlite3.c:122099
#16 0x0000aaaab8f79dbc in sqlite3InitOne (db=0xffff7c025d48, iDb=iDb@entry=0, pzErrMsg=pzErrMsg@entry=0xffff937f3620,
    mFlags=mFlags@entry=0) at /root/project/src/database/sqlite3.c:127276
#17 0x0000aaaab8f887e8 in sqlite3Init (db=db@entry=0xffff7c025d48, pzErrMsg=pzErrMsg@entry=0xffff937f3620)
    at /root/project/src/database/sqlite3.c:127348
#18 0x0000aaaab8f88838 in sqlite3ReadSchema (pParse=pParse@entry=0xffff937f3618) at /root/project/src/database/sqlite3.c:127374
#19 0x0000aaaab8f88e98 in sqlite3LocateTable (pParse=0xffff937f3618, flags=0, zName=0xffff7c084a08 "domain_audit", zDbase=0x0)
    at /root/project/src/database/sqlite3.c:109478
#20 0x0000aaaab8f89c88 in selectExpander (pWalker=0xffff937f27d8, p=0x0) at /root/project/src/database/sqlite3.c:132826
#21 0x0000aaaab8efcf7c in sqlite3WalkSelect (pWalker=pWalker@entry=0xffff937f27d8, p=0xffff7c084808)
    at /root/project/src/database/sqlite3.c:96749
#22 0x0000aaaab8efd208 in walkExpr (pWalker=pWalker@entry=0xffff937f27d8, pExpr=0xffff7c084788)
    at /root/project/src/database/sqlite3.c:96638
#23 0x0000aaaab8efd288 in sqlite3WalkExpr (pExpr=<optimized out>, pWalker=0xffff937f27d8)
    at /root/project/src/database/sqlite3.c:96655
#24 sqlite3WalkExprList (pWalker=0xffff937f27d8, p=<optimized out>) at /root/project/src/database/sqlite3.c:31131
#25 0x0000aaaab8efcf8c in sqlite3WalkSelectExpr (p=0xffff7c084608, pWalker=0xffff937f27d8)
    at /root/project/src/database/sqlite3.c:96680
#26 sqlite3WalkSelect (pWalker=pWalker@entry=0xffff937f27d8, p=p@entry=0xffff7c084608)
    at /root/project/src/database/sqlite3.c:31215
#27 0x0000aaaab8efd9d4 in sqlite3SelectExpand (pSelect=0xffff7c084608, pParse=0xffff937f3618)
    at /root/project/src/database/sqlite3.c:133114
#28 sqlite3SelectPrep (pParse=0xffff937f3618, p=0xffff7c084608, pOuterNC=0x0) at /root/project/src/database/sqlite3.c:2127
#29 0x0000aaaab8f62cc8 in sqlite3Select (pParse=pParse@entry=0xffff937f3618, p=0xffff7c084608, pDest=0xffff937f2be0,
    pDest@entry=0xffff937f2ce0) at /root/project/src/database/sqlite3.c:133637
#30 0x0000aaaab8f72de4 in yy_reduce (yyLookahead=<optimized out>, pParse=0xffff937f3618, yyLookaheadToken=..., yyruleno=82,
    yypParser=0xffff937f2d10) at /root/project/src/database/sqlite3.c:155887
#31 sqlite3Parser (yyminor=..., yymajor=<optimized out>, yyp=0xffff937f2d10) at /root/project/src/database/sqlite3.c:26109
#32 sqlite3RunParser (pParse=pParse@entry=0xffff937f3618, zSql=<optimized out>, zSql@entry=0x0,
    pzErrMsg=pzErrMsg@entry=0xffff937f3680) at /root/project/src/database/sqlite3.c:27383
#33 0x0000aaaab8f78e98 in sqlite3Prepare (db=db@entry=0xffff7c025d48, zSql=0x0,
    zSql@entry=0xaaaab90575f8 "SELECT EXISTS(SELECT domain, CASE WHEN substr(domain, 1, 1) = '*' THEN '*' || substr(:input, - length(domain) + 1) ELSE :input END matcher FROM domain_audit WHERE matcher = domain);", nBytes=nBytes@entry=-1,
    prepFlags=prepFlags@entry=128, pReprepare=pReprepare@entry=0x0, ppStmt=0x0, ppStmt@entry=0xaaaab90f75d8 <auditlist_stmt>,
    pzTail=pzTail@entry=0x0) at /root/project/src/database/sqlite3.c:127575
#34 0x0000aaaab8f79384 in sqlite3LockAndPrepare (db=0xffff7c025d48,
    zSql=0xaaaab90575f8 "SELECT EXISTS(SELECT domain, CASE WHEN substr(domain, 1, 1) = '*' THEN '*' || substr(:input, - length(domain) + 1) ELSE :input END matcher FROM domain_audit WHERE matcher = domain);", nBytes=-1, prepFlags=128, pOld=0x0,
    ppStmt=0xaaaab90f75d8 <auditlist_stmt>, pzTail=0x0) at /root/project/src/database/sqlite3.c:127647
#35 0x0000aaaab8e9cddc in gravityDB_open () at /root/project/src/database/gravity-db.c:136
#36 0x0000aaaab8e9e294 in gravityDB_open () at /root/project/src/database/gravity-db.c:88
#37 gravityDB_reopen () at /root/project/src/database/gravity-db.c:74
#38 0x0000aaaab8e85698 in FTL_reload_all_domainlists () at /root/project/src/datastructure.c:482
#39 0x0000aaaab8e9c9bc in DB_thread (val=<optimized out>) at /root/project/src/database/database-thread.c:81
#40 0x0000ffff958fc4fc in start_thread (arg=0xffffcbb95bff) at pthread_create.c:477
#41 0x0000ffff958570cc in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:78

The table is defined as

CREATE TABLE domain_audit
(
	id INTEGER PRIMARY KEY AUTOINCREMENT,
	domain TEXT UNIQUE NOT NULL,
	date_added INTEGER NOT NULL DEFAULT (cast(strftime('%s', 'now') as int))
);

The crashing statement can be seen in the backtrace above.

Please ask if you need anything else.

Regards Jens

(2) By Richard Hipp (drh) on 2020-12-21 20:52:08 in reply to 1.0 [source]

Usually when you hit a setfault down inside of malloc() that was called from SQLite, that means that SQLite has had the misfortune of stumbling over heap corruption caused by some other part of the application. In other words, it is not SQLite's fault. SQLite just happened to be the first bit of code to bump into the problem, often because SQLite is a heavy user of malloc().

If you have some evidence that this problem is actually caused by SQLite, then we will look further. But otherwise, we will assume that this is heap corruption.

Since you seem to be running on Linux, I suggest compiling with -fsanitize=memory and/or -fsanitize=address and see what that uncovers. Or run the application using valgrind.