docs(media): record unchecked SQLite announcements and fix plan

This commit is contained in:
evgeny committed 2026-10-24 17:26:11 +02:00
1 parent 7ff8e1f15a
commit 0d616ce1e7
2 files changed
+82 -2

No files matched your search

+69 -2
View File
@@ -1,6 +1,6 @@
Аудит media_async / media_delivery — 2026-10-24
Статус: encrypted_file и отдельный дефект границы voice_file исправлены.
Полный аудит двух каталогов ещё не завершён. Граница voice_file и результаты исправления — в конце.
Статус: encrypted_file и граница voice_file исправлены; подтверждён отдельный дефект переанонса записей SQLite.
Полный аудит двух каталогов ещё не завершён. Последнее продолжение и проект исправления — в конце.
Ниже сохранены исходное воспроизведение, согласованный проект и результаты исправления encrypted_file.
Подтверждённый дефект: исходник уничтожается через другое имя того же файла
@@ -296,3 +296,70 @@ attachment_send.c вызывает voice_file_encode в worker, а attachment_va
выше не относятся к этому изменению. Windows/FreeBSD не проверялись.
voice_file.h и attachment.h сохраняют [~]: завершение этого фикса не закрывает
оставшуюся сверку контрактов всего аудита. Повторная проверка media_delivery ещё не завершена.
Продолжение аудита — 2026-10-24: переанонс записей SQLite
Полностью прочитаны media_index.c/h, media_download.c/h, media_delivery.c/h,
file_transfer.c/h, media_delivery_proto.h и sync.md. Повторно сверены media_crypto.c/h.
В media_crypto.h уточнены native байты nonce, границы CCM/буферов, пустой поток,
момент выдачи размеров/хеша и отсутствие close/fsync/rename; неверный аргумент не обнуляет выходы.
В file_transfer.h уточнены lookup/авторизация, 16 операций, размер1..INT64_MAX,
усечение своего временного назначения даже при отказе запуска, таймаут и отмена/владение callback.
Изменения только описаний сохранены коммитом5dbca4a2.
Подтверждённый дефект
media_delivery_announce_local_blocks (media_delivery.c:1604) читает media_id/block_id
через sqlite3_column_blob, но проверяет только ненулевой указатель. Затем
media_delivery_send_have_block копирует по16 байт в пакет и подписывает объявление.
media_files имеет BLOB NOT NULL без CHECK длины: такие строки допустимы текущей схемой.
Обычные media_index writers пишут правильные длины; опыт моделирует повреждённые
локальные данные, а не доказанный путь внесения повреждения удалённым участником.
Настоящие SQLite, схема, обработчик, выбор группы/суперузла и Ed25519; перехвачена
только транспортная отправка в существующем tests/media_delivery_fixture.h:
- Контрольные UUID16/16, chunk0, chat_id111: один корректный HAVE_BLOCK.
- media_id длиной1 байт: один HAVE_BLOCK с16-байтным media_id, из них15 байт вне BLOB.
В журнале вместо ожидаемого единственного7a видны посторонние ненулевые байты памяти.
- block_id длиной1 байт: аналогичное чтение15 лишних байт в сетевой block_id.
- media_id или block_id длиной17 байт: отправка с молчаливым усечением до16.
- chunk=-1: wire_chunk=4294967295; chunk=4294967296: wire_chunk=0.
Причина — sqlite3_column_int с последующим приведением к uint32_t без диапазона.
- chat_id111junk: strtoull без endptr принимает префикс111 и направляет объявление в группу111.
- Итого8 случаев,7 повреждённых строк из7 отправлены; invalid_records_sent=7, confirmed=1.
Ошибки соответствующих полей в модуле не логируются. Пакеты сохранены только стендом,
реальные удалённые узлы в опыте не участвовали. Ошибка ASAN или падение не воспроизводились.
Артефакты: /tmp/media-announcement-audit.c, /tmp/media-announcement-audit.mk,
/tmp/media-announcement-audit-build.log, /tmp/media-announcement-audit.log.
Сборка через tests/Makefile с настоящими src/libutun.a/libuasync.a и штатными флагами;
проектные .c для диагностики не менялись. Очистка собственного стенда исправлена и повторно проверена.
Отдельно по коду видно: результаты bind/завершающего step/finalize игнорируются;
SQL-ошибку окончания обхода нельзя выдавать как обычное «done». Инъекция SQL-ошибок здесь не выполнялась.
Проект простого исправления
1. Проверять строку на границе чтения SQLite до доступа как к фиксированным структурам:
media_id/block_id имеют тип BLOB и ровно16 байт; проверить полученные указатели.
Скопировать прошедшие проверку UUID в локальные массивы до вложенных SQL/отправок.
2. chunk читать как int64: тип INTEGER, 0..UINT32_MAX, только затем cast.
chat_id — TEXT, длина1..20 без embedded NUL, каноническое ненулевое uint64 decimal.
Полный разбор должен отвергать суффиксы, знаки, пробелы, leading zero и переполнение;
строка канала должна сохранять свой смысл при переводе в router group_id.
3. Плохую строку пропускать с WARN, указав rowid/типы/длины/некорректное поле,
без чтения за BLOB и без анонса. Корректные соседние строки продолжать обрабатывать.
Никакого общего выделяемого снимка или отката уже отправленных корректных анонсов не требуется.
4. Проверять bind, terminal step и finalize; SQL-ошибки логировать с фазой/кодами
и количеством обработанных строк. Не превращать их в обычный успешный финальный лог.
Сохранить существующий void API, поштучные анонсы и wire-формат.
5. Регрессии в штатной media-цели: valid row, длины UUID0/1/15/16/17 и неверные SQL-типы,
chunk=-1/0/UINT32_MAX/UINT32_MAX+1, неверные/граничные chat_id, embedded NUL;
смесь корректных/плохих записей и ошибки SQL. Перехват HAVE_BLOCK обязан доказать,
что наружу ушли только исходные16 байт проверенных UUID и правильный номер группы/блока.
Аудит остановлен по AGENTS.md:10 после подтверждения дефекта и подготовки проекта исправления.
Новые полные build/check/sanitizer-прогоны не запускались: изменения в репозитории только документальные.
media_crypto.h и file_transfer.h можно отметить [V]; media_delivery.h/proto.h остаются [~]:
нужно исправление этого пути и завершение сверки описаний. Остальные прежние отметки не закрывают
весь аудит. Остались контракты attachment/attachment_send/voice, связанные encrypted/lifecycle документы
и устаревший _desc.txt (RTT-подбор, direct-only репликация и её интервалы расходятся с текущим кодом).
+13
View File
@@ -4,6 +4,19 @@
## Текущие задачи
[ ] **media_delivery: проверять записи SQLite перед переанонсом локальных блоков** — подтверждено 24.10.2026.
announce_local_blocks не проверяет длины media_id/block_id, диапазон chunk и полный chat_id.
Реальный обработчик отправил все7 повреждённых записей: UUID длиной1/17 байт, chunk=-1/2^32, chat_id=111junk.
При UUID длиной1 байт остальные15 байт сетевого поля взяты за границей BLOB;
chunk=-1 превращается в4294967295, 2^32 — в0, 111junk — в группу111.
Стенд использует настоящие SQLite/Ed25519; отправка перехвачена, пакеты в реальную сеть не уходят.
Воспроизведение: /tmp/media-announcement-audit.c и .mk; лог: /tmp/media-announcement-audit.log.
План: проверять типы/точные длины UUID, chunk через int64 и канонический ненулевой десятичный chat_id
до копирования/кастов/отправки. Плохие строки логировать и пропускать; проверять bind/step/finalize.
Сохранить текущий void API, поштучные анонсы и формат wire; общий снимок всех файлов не нужен.
Архитектура, границы воспроизведения и регрессии: [media_async_audit_findings.txt](media_async_audit_findings.txt).
Рабочий код не изменён: остановлено по AGENTS.md:10. Сверка описаний двух каталогов ещё не завершена.
[+] **media_async voice_file: согласовать верхнюю границу длительности с метаданными** — исправлено 24.10.2026.
Прежняя проверка samples/channels/rate >86400 пропускала полные кадры 24ч+20..980мс,
хотя attachment_validate отклоняет duration_ms >86400000. В штатном pipeline это означает