
SQLite 3.53.4 - 높음 - 로컬 - 크래시 - VALUES UNION ALL 폴백 정리 스택 오버플로
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-values-union
분석 문서: https://abraxaslabs.tech/research/sqlite-values-union
분류: 크래시 도달 범위: 로컬
SQLite 3.53.4 (b09c88c) - Hwaci
기본 VALUES는 코루틴을 사용합니다. WITH(또는 스키마 재로드, 또는 비상수 행)가 있으면 sqlite3MultiValues가 UNION ALL 경로로 강제됩니다. SF_Values가 설정되면 복합 SELECT 길이 검사가 건너뛰어집니다(parse.y:562-567). 그러면 충분히 큰 행 목록이 SQLITE_LIMIT_EXPR_DEPTH에 의해 거부되고, 오류 정리 경로에서 재귀적인 sqlite3ExprDeleteNN이 C 스택을 고갈시킵니다.
5000행의 순수 VALUES는 문제없습니다. WITH와 1000행은 깔끔하게 오류가 납니다(Expression tree is too large). WITH와 300000행은 sqlite3ExprDeleteNN에서 ASan 스택 오버플로입니다(rc=134). RCE는 아닙니다.
| ID | 아직 CVE 없음 |
| 분류 | 크래시 (ExprDelete에서 ASan 스택 오버플로; RCE는 입증되지 않음) |
| 도달 범위 | 로컬 (신뢰할 수 없는 SQL, 또는 VIEW/TRIGGER 내부의 VALUES) |
| CWE | CWE-674 |
| CVSS | 높음: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 제품 | SQLite |
| 영향 버전 | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69, SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc). 이후 트렁크의 VALUES 복합 상한의 잔재. |
| 인증 | 공격자 SQL, 또는 UNION ALL 폴백을 타도록 심어진 스키마 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1:18820 전용. ASan 아말감. 크래시 재현 증거. |
호스트가 prepare할 신뢰할 수 없는 SQL을 공급합니다. 거대한 VALUES 목록 앞에 WITH를 붙여 코루틴 경로를 끕니다. 파싱은 표현식 깊이 오류로 실패해야 합니다. 그 트리의 정리가 sqlite3ExprDeleteNN에서 재귀하다가 프로세스가 죽습니다.
VALUES가 VIEW나 TRIGGER 안에 있을 때(db->init.busy)도 같은 폴백이 발동합니다. 호스트는 임베더입니다: CLI, 공격자 SQL을 prepare하는 앱, 악성 .db를 여는 서비스. SQLite는 VALUES 바이트를 코드로 평가하지 않습니다. 크래시 자체가 발견 사항입니다.
github.com/sqlite/sqlite 태그 version-3.53.4에 대한 스무 차례의 소스 사냥. 스킵 목록은 이미 CVE-2026-11824, 세션 NPD, concat_ws, LOOKASIDE, JSON UAF, WAL-reset을 종결했습니다. 기본 load_extension은 꺼져 있습니다. 파서/VDBE 잔재는 이 VALUES UNION ALL 건너뛰기와 재귀적 소멸자였습니다.
if( (p->selFlags & (SF_MultiValue|SF_Values))==0
&& (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
&& cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
if( pParse->bHasWith
|| pParse->db->init.busy
|| exprListIsConstant(pParse,pRow)==0
...
){
/* The co-routine method cannot be used. Fall back to UNION ALL. */
...
pSelect->op = TK_ALL;
pSelect->pPrior = pLeft;
}
clearSelect()는 pPrior를 반복적으로 순회합니다. sqlite3ExprDeleteNN()은 여전히 pRight에서, 그리고 EP_Static이 설정된 경우 pLeft에서 재귀합니다.
잘못된 접근: WITH를 사용한 1000개 행은 문서화된 깊이 한도에서 깔끔하게 오류를 내고 크래시하지 않음; 소멸자 깊이가 8 MiB C 스택을 초과하도록 300000개 행이 필요했음. 일반 VALUES는 코루틴에 머무르며 음성 대조군 역할을 함.
cd lab
./run.sh
Canonical 3.53.4 소스 zip, ASan sqlite3. sqlite-values-union을 구성합니다. 127.0.0.1:18820에 게시합니다. 루프백에 바인딩합니다.
SUCCESS sqlite-values-union how=with-values-union-all-fallback-exprdelete rows=300000 crash=asan-stack-overflow plain=5000 depth-error=1000 SQLITE-VALUES-UNION-WITNESS
다른 복합 구문이 제한되는 것과 동일한 방식으로 VALUES에 SQLITE_LIMIT_COMPOUND_SELECT를 적용합니다. 삭제 시 UNION ALL 체인을 반복적으로 순회하거나, 트리가 구축되기 전에 EXPR_DEPTH를 제한하여 정리 과정이 C 스택에서 재귀 호출되지 않도록 합니다. 이후 트렁크(Bug 2026-10-04T05:34:47Z)는 이 GA 이후의 버전입니다.
b09c88c14082339b66c7b7158d609a771e64ca69)2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bccsrc/parse.y:562-567 SF_Values가 설정된 경우 복합 SELECT 건너뛰기src/insert.c:681-704 sqlite3MultiValues UNION ALL 폴백src/expr.c:1406-1430 재귀적 sqlite3ExprDeleteNN