Clarify attachment commit ownership and SQL failure diagnostics
This commit is contained in:
1 parent
e5ca2e174c
commit
71dfc9d70d
2 files changed
+29
-13
No files matched your search
@@ -14,16 +14,23 @@ Android показывает зашифрованное вложение отд
|
||||
Список чатов сохраняет общее название зашифрованного вложения вместо manifest.
|
||||
|
||||
Автор генерирует независимые случайные crypto_UUID и ключ AES-256 на каждую
|
||||
подготовку. Штатно ключ записывается в локальную SQLite до шифрования. При аудите
|
||||
26.10.2026 подтверждено исключение: отказ `sqlite3_bind_blob` ключа не проверяется,
|
||||
и подготовка запускается со строкой `key=NULL`, несмотря на сообщение «key saved».
|
||||
Контейнер создаётся, переданный исходник удаляется; последующая проверка
|
||||
`chat_attachment_bind` запрещает публикацию, и отправка завершается событием ошибки.
|
||||
Это открытый дефект сохранения ключа; аудит модуля остаётся частичным.
|
||||
Стенд, точная граница проверки и план исправления — в
|
||||
[chat_audit_findings.txt](chat_audit_findings.txt), продолжение chat_attachment.
|
||||
Готовый контейнер
|
||||
передаётся через обычные media_index/media_delivery. UUID транспортного медиа
|
||||
подготовку. Ключ, UUID, автор, пути и метаданные записываются в локальную SQLite
|
||||
собственной короткой транзакцией до передачи подготовленного файла worker.
|
||||
Проверяются prepare, все bind, step, ровно одна добавленная строка, finalize и commit.
|
||||
Внешняя транзакция отклоняется без изменений. До принятия ошибка возвращает `-1`:
|
||||
файл остаётся у вызывающего, worker и событие отправки не создаются.
|
||||
После commit возвращается `0`, файл принадлежит задаче и удаляется также при её отказе;
|
||||
ненулевой request получает один `MSG_SUBMITTED`, в том числе синхронно при отказе запуска worker.
|
||||
Исходный пользовательский файл сохраняется: общий frontend передаёт сюда собственную подготовленную копию.
|
||||
|
||||
Неудачный rollback с оставшейся открытой транзакцией отключает модуль вложений и
|
||||
запрашивает остановку ядра. Desktop и Android учитывают запрос в своих poll-циклах;
|
||||
владелец освобождает ядро и закрывает SQLite после возврата из poll. Текущий poll может
|
||||
доставить другие callbacks до выхода. Политика общей БД остаётся WAL/synchronous=NORMAL:
|
||||
завершённый commit до worker не является гарантией сохранности после отключения питания.
|
||||
История дефекта и проверок — в [chat_audit_findings.txt](chat_audit_findings.txt).
|
||||
|
||||
Готовый контейнер передаётся через обычные media_index/media_delivery. UUID транспортного медиа
|
||||
и crypto_UUID имеют разные назначения: первый идентифицирует сетевые блоки,
|
||||
второй — контейнер и ключ. Повтор доставки передаёт прежний контейнер.
|
||||
|
||||
@@ -154,6 +161,12 @@ backpressure и повтором через 5 секунд; restart продол
|
||||
`test_attachment_send` проверяет восемь отказов MIME до ключей/worker/файлов,
|
||||
затем останавливает сервис после настоящего crypto rename до completion.
|
||||
|
||||
`test_chat_attachment` проверяет 13 SQL-отказов с сохранением source/прежних строк/файлов,
|
||||
отсутствием worker и события до принятия, затем настоящую публикацию при каждом повторе.
|
||||
Отдельное readonly-соединение проверяет точные ключ, автора, UUID, метаданные и пути до worker.
|
||||
Дополнительно проверяются настоящий commit veto, INSERT ABORT/IGNORE, внешняя транзакция,
|
||||
синхронный отказ запуска, restart с опубликованным ключом и отказ rollback с закрытием БД владельцем.
|
||||
|
||||
`test_encrypted_attachment`: реальные A–S–B/C, скачивание с S при выключенном A,
|
||||
перезапуски автора с запросами и получателя с ключом, выдача B и отказ C,
|
||||
отсутствие ключа на S/C, отрицательные control-пакеты, повтор GRANT,
|
||||
|
||||
@@ -236,16 +236,19 @@ static int ak_store_preparation(struct ak_file* job, const uint8_t* info, int in
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEDIA, "attachment keys: author preparation committed before encryption channel=%s", job->channel);
|
||||
return 0;
|
||||
fail:
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: preparation channel=%s stage=%s rc=%d: %s", job->channel, stage, rc, sqlite3_errmsg(db));
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: preparation channel=%s stage=%s rc=%d (%s) db=%s",
|
||||
job->channel, stage, rc, sqlite3_errstr(rc), sqlite3_errmsg(db));
|
||||
int final_rc = sqlite3_finalize(st);
|
||||
if (final_rc != SQLITE_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: preparation cleanup finalize channel=%s rc=%d", job->channel, final_rc);
|
||||
if (!sqlite3_get_autocommit(db)) {
|
||||
int rollback_rc = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
|
||||
if (rollback_rc != SQLITE_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: preparation rollback channel=%s rc=%d: %s", job->channel, rollback_rc, sqlite3_errmsg(db));
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: preparation rollback channel=%s rc=%d (%s) db=%s",
|
||||
job->channel, rollback_rc, sqlite3_errstr(rollback_rc), sqlite3_errmsg(db));
|
||||
if (!sqlite3_get_autocommit(db)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: transaction remains open channel=%s; quiescing attachments and requesting core stop", job->channel);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment keys: transaction remains open channel=%s; quiescing attachments and requesting core stop",
|
||||
job->channel);
|
||||
chat_attachment_quiesce(inst);
|
||||
utun_instance_stop(inst);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user