
SQLite 3.53.4 - 높음 - 로컬 - 크래시 - VALUES UNION ALL 폴백 정리 스택 오버플로
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · 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, session 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
정식 3.53.4 소스 zip, ASan sqlite3. Compose 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
다른 복합문이 상한이 걸리는 것과 같은 방식으로 SQLITE_LIMIT_COMPOUND_SELECT를 VALUES에 적용하라. 삭제 시 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