16 октября 2026 года разработчики SQLite выпустили версию 3.54.1, которая устраняет выход за границы выделенной памяти в некоторых 32-битных сборках SQLite 3.54.0. Ошибка возникала при подготовке SQL-команд и могла приводить к аварийному завершению приложения. Обновление затрагивает безопасность работы с памятью, корректность сложных SQL-запросов и производительность подготовленных выражений.

Ошибка SQLite 3.54.0 могла повреждать память в 32-битных приложениях
В SQLite 3.54.0 обнаружили ошибку управления памятью, связанную с внутренним механизмом исполнения SQL. При определённых условиях движок мог записать данные за пределами выделенного буфера. Проблема затрагивала отдельные 32-битные сборки, включая архитектуру ARMv7, на которой исследователям удалось воспроизвести сбой.
SQLite широко используется как встроенная база данных. Она хранит информацию непосредственно в файле и работает внутри приложения, без отдельного сервера. Поэтому ошибка движка может проявиться как сбой самой программы, даже если пользователь никогда не взаимодействует с базой данных напрямую.
Причину обнаружили в функции sqlite3VdbeMakeReady(), которая готовит виртуальную машину SQLite к выполнению SQL-команд. Эта виртуальная машина преобразует запросы в последовательность внутренних инструкций, называемых опкодами.
В версии 3.54.0 при расчёте свободного пространства для таких инструкций возникала ошибка округления. На 32-битных системах размер отдельной инструкции составлял 20 байт. При определённом количестве инструкций движок ошибочно считал доступными четыре дополнительных байта за пределами выделенного участка памяти.
В результате возникало переполнение буфера в куче (heap-buffer overflow). Воспроизведённый исследователями сценарий завершался ошибкой double free or corruption и остановкой процесса.
Разработчики SQLite отдельно подтвердили, что 64-битные сборки этой проблемой не затронуты.
Разработчики SQLite убрали оптимизацию, вызвавшую переполнение
Сообщение об ошибке появилось в официальном трекере SQLite 10 октября 2026 года, на следующий день после выпуска 3.54.0. Исследователь воспроизвёл сбой на ARMv7, используя компилятор GCC и эмуляцию через QEMU. Для проверки хватило создания таблицы и добавления в неё столбца с помощью ALTER TABLE.
Проверка показала, что проблема связана с небольшой оптимизацией распределения памяти, появившейся в ветке 3.54. Разработчик SQLite Ричард Хипп в тот же день внёс исправление, отменяющее эту оптимизацию. Позднее другой участник обсуждения подтвердил, что исправленный код проходит его тесты.
Сравнение с предыдущим выпуском помогает понять границы дефекта. В SQLite 3.53.4 использовался другой расчёт доступной памяти, поэтому описанная ошибка там не воспроизводилась. В 3.54.0 этот расчёт изменили, а в 3.54.1 исправление вошло в официальный выпуск. Сам файл базы данных при этом не является причиной сбоя: ошибка находилась в памяти процесса, выполняющего SQL.
В SQLite 3.54.1 исправили ошибки результатов запросов и лишнюю подготовку SQL
Помимо переполнения памяти, между выпусками 3.54.0 и 3.54.1 разработчики внесли десятки изменений в ветку исправлений. В официальной истории изменений выделены несколько проблем, затрагивающих поведение SQL-запросов.
Одна из них проявлялась при сочетании UNION ALL, внутренних соединений и RIGHT JOIN либо FULL JOIN. В отдельных запросах SQLite возвращала меньше строк, чем следовало. Причиной была ошибка преобразования запроса оптимизатором. Для программы, которая строит отчёты или объединяет результаты нескольких выборок, такой дефект затрагивал уже сами данные, полученные из SQL-запроса.
Другая проблема касалась подготовленных выражений с параметрами, например col = ?. При повторном выполнении запросов с соединениями таблиц SQLite 3.54.0 могла заново подготавливать выражение при каждой смене значения параметра, хотя план выполнения оставался прежним. В отчёте об ошибке исследователь получил 1000 повторных подготовок за 1000 выполнений запроса; в SQLite 3.53.4 их было ноль. Исправление устраняет эту лишнюю работу в затронутом сценарии.
В журнале изменений присутствуют и другие правки: обработки времени 24:00:00, режима CSV в консольной утилите, отдельных выражений с индексами и обработки некоторых символов в полнотекстовом поиске FTS3/FTS5. Эти изменения относятся к конкретным случаям, описанным в сообщениях об ошибках и истории коммитов.
Как определить версию SQLite внутри приложения
SQLite часто поставляется вместе с программой или библиотекой, поэтому установленная в операционной системе консольная утилита и фактически используемый движок могут иметь разные версии.
Выполняемый средствами SQLite SQL-запрос позволяет определить версию той библиотеки, которая обрабатывает конкретное соединение с базой данных:
SELECT sqlite_version();Функция sqlite_version() официально документирована и возвращает строку версии работающей библиотеки. Для уязвимого выпуска результатом будет 3.54.0, для исправленного — 3.54.1. Такой запрос показывает фактическую версию движка, но сам по себе не определяет разрядность процесса и особенности сборки.
Проверка на наличие дефекта зависит сразу от двух факторов: версии SQLite и того, относится ли используемая сборка к затронутым 32-битным вариантам. Согласно официальному сообщению о выпуске, проблема переполнения не распространяется на 64-битные сборки.
SQLite 3.54.1 закрыла ошибки, обнаруженные после октябрьского релиза
Между SQLite 3.54.0 от 9 октября и исправлением 3.54.1 от 16 октября прошла одна неделя. За это время разработчики устранили сбой управления памятью, проблему лишней подготовки выражений и несколько ошибок, способных менять результаты отдельных сложных запросов.
Масштаб последствий зависит от сборки и того, какие SQL-конструкции использует программа. Для некоторых 32-битных приложений главным изменением стало устранение выхода за границы памяти; для остальных различия связаны прежде всего с корректностью и поведением отдельных операций SQLite.
Источники
- SQLite 3.54.1 — официальное описание выпуска от 16 октября 2026 года
- SQLite — сообщение о выпуске версии 3.54.1
- SQLite Bug Forum — переполнение буфера в sqlite3VdbeMakeReady на 32-битных сборках
- SQLite Fossil — исправления между 3.54.0 и 3.54.1
- SQLite Bug Forum — пропущенные строки при UNION ALL и RIGHT JOIN
- SQLite Bug Forum — повторная подготовка параметризованных запросов
- SQLite — документация функции sqlite_version()