
SQLite 3.53.4 — высокий уровень — локальный — сбой — переполнение стека при очистке fallback в VALUES UNION ALL
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-values-union
Класс: Crash Доступ: Локальный
SQLite 3.53.4 (b09c88c) - Hwaci
По умолчанию VALUES использует сопрограмму. WITH (или перезагрузка схемы, или неконстантная строка) заставляет sqlite3MultiValues перейти на UNION ALL. Проверка длины составного SELECT пропускается, когда установлен SF_Values (parse.y:562-567). Достаточно большой список строк затем отклоняется по SQLITE_LIMIT_EXPR_DEPTH, и рекурсивный sqlite3ExprDeleteNN переполняет стек C на пути очистки после ошибки.
Обычный VALUES из 5000 строк работает нормально. WITH плюс 1000 строк завершается чистой ошибкой (Expression tree is too large). WITH плюс 300000 строк — это переполнение стека ASan в sqlite3ExprDeleteNN (rc=134). Не RCE.
| ID | CVE пока нет |
| Класс | Crash (переполнение стека ASan в ExprDelete; RCE не продемонстрирован) |
| Доступ | Локальный (недоверенный SQL, или VALUES внутри VIEW/TRIGGER) |
| CWE | CWE-674 |
| CVSS | High: 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 в trunk. |
| Аутентификация | SQL от атакующего, или внедрённая схема, попадающая на запасной путь UNION ALL |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | Только 127.0.0.1:18820. ASan-амальгама. Свидетельство краха. |
Подать недоверенный SQL, который хост будет подготавливать. Добавить префикс WITH к огромному списку VALUES, чтобы путь сопрограммы был отключён. Разбор должен завершиться ошибкой превышения глубины выражений. Очистка этого дерева рекурсивно вызывает sqlite3ExprDeleteNN, пока процесс не погибнет.
Тот же запасной путь срабатывает, когда VALUES находится в VIEW или TRIGGER (db->init.busy). Хост — это встраивающая сторона: CLI, приложение, подготавливающее SQL атакующего, сервис, открывающий враждебный .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 и pLeft, когда установлен EP_Static.
Неверные пути: 1000 строк с WITH завершаются чистой ошибкой на документированном пределе глубины и не приводят к краху; потребовалось 300000 строк, чтобы глубина деструктора переполнила 8 MiB стек C. Обычный VALUES остаётся на сопрограмме и служит отрицательным контролем.
cd lab
./run.sh
Канонический zip исходников 3.53.4, ASan sqlite3. Compose sqlite-values-union. Опубликован на 127.0.0.1:18820. Привяжите его к loopback.
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 рекурсией. Более поздний trunk (Bug 2026-10-04T05:34:47Z) появился после этого GA.
b09c88c14082339b66c7b7158d609a771e64ca69)2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bccsrc/parse.y:562-567 пропуск составного SELECT, когда установлен SF_Valuessrc/insert.c:681-704 запасной путь sqlite3MultiValues UNION ALLsrc/expr.c:1406-1430 рекурсивный sqlite3ExprDeleteNN