
SQLite 3.53.4 — высокий уровень — локальный — сбой — переполнение стека при очистке fallback в VALUES UNION ALL
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-values-union
Разбор: https://abraxaslabs.tech/research/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. Amalgamation с ASan. Свидетельство краха. |
Подать недоверенный SQL, который хост будет подготавливать. Поставить перед огромным списком VALUES префикс WITH, чтобы отключить путь через сопрограмму. Разбор должен завершиться ошибкой глубины выражения. Очистка этого дерева рекурсивно вызывает 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 оказался этим пропуском UNION ALL для VALUES плюс рекурсивным деструктором.
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 пропуск compound-SELECT при установленном SF_Valuessrc/insert.c:681-704 резервный путь UNION ALL в sqlite3MultiValuessrc/expr.c:1406-1430 рекурсивный sqlite3ExprDeleteNN