Record reproducible encrypted file alias data loss during media audit

This commit is contained in:
evgeny committed 2026-10-24 14:17:35 +02:00
1 parent 461417beac
commit 8cc97d2ffe
2 files changed
+81

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
Аудит media_async / media_delivery — 2026-10-24
Статус: частичный; остановлен на подтверждённом дефекте по AGENTS.md.
Код модулей не изменён. Сборка Linux и 20 профильных тестов прошли.
Подтверждённый дефект: исходник уничтожается через другое имя того же файла
encrypted_file_write, src/media_async/encrypted_file.c:79-87, сравнивает только строки
source/destination. Разные строки могут обозначать один inode. fopen(destination,"wb")
усекает уже открытый source. Криптография затем успешно обрабатывает пустой файл.
Контейнер корректен для нулевого содержимого, но исходные данные потеряны; возврат равен 0.
Воспроизведено на настоящих функциях из src/libutun.a:
- source и source с компонентом /./: исходные30 байт заменены контейнером152 байта,
plaintext_size=0, rc=0, SHA256 исходника изменился;
- source и hardlink: тот же результат;
- encrypted_file_read тоже пропускает оба вида alias: контейнер182 байта заменяется
plaintext30 байт, rc=0, исходный ciphertext больше не существует в прежнем виде.
У read такая же проверка strcmp в строке118 и разрушающий fopen в строке142.
В текущем групповом pipeline вызывающий выбирает отдельный .part; воспроизведение
доказывает дефект файлового API, а не наблюдавшуюся потерю реального пользовательского вложения.
Ошибку нельзя замаскировать описанием одинаковых файлов как успешного no-op:
шифрование и расшифровка должны создавать другое содержимое.
Диагностика:
- /tmp/media-encrypted-alias-repro.c — четыре проверки, сверяются inode, размеры и SHA256;
- /tmp/media-encrypted-alias-repro.mk — использует цели/библиотеки/флаги tests/Makefile;
- /tmp/media-encrypted-alias-repro.log — полный журнал с media=debug;
- /tmp/media-encrypted-alias-lvVS77/ — сохранённые входы и результаты опыта.
Проектные .c/.h для воспроизведения не менялись.
Рекомендуемое исправление
1. У обеих функций явно закрепить контракт: source остаётся неизменным;
destination — отдельный временный файл вызывающего, который допустимо удалить при ошибке.
Файлы/каталоги не должны подменяться во время вызова; это тот же контракт стабильности,
что у существующих file_io-примитивов.
2. До открытия назначения с усечением проверить идентичность через общий file_io_paths.
Результат1 (один файл) здесь означает ошибку. Отдельно проверять успешное открытие
источника до создания назначения. Использовать общие UTF-8/regular-file примитивы,
не дублировать POSIX/Windows сравнение идентичности в encrypted_file.
3. Ранняя ошибка не должна изменять source, удалять его alias или менять существующее
назначение. Сообщение об отказе должно назвать операцию/пути и причину до усечения.
4. Сохранить нынешнее владение: chat_attachment/dm_media публикуют результат после work.
Внутри encrypted_file не нужен второй независимый слой публикации или новый async owner.
5. Добавить регрессии write/read: совпадающая строка, /./, hardlink, конечная ссылка;
при отказе проверять неизменность файлов и отсутствие удаления alias. Проверить
отсутствующий источник и размеры0/1/32768/32769, обычные roundtrip и отмену pipeline.
6. Прогнать профильные тесты, ASAN/UBSan и полный набор; затем продолжить аудит
остальных контрактов обоих каталогов. Формат контейнера и nonce менять не требуется.
Что проверено и что осталось
Прочитаны все шесть пар .c/.h media_async, целиком file_transfer.c/h, заголовки
media_delivery/download/index/proto, sync.md и doc/encrypted_attachments.md.
Полная повторная сверка остальных реализаций media_delivery и исправление контрактов
ещё не выполнены. Прежние [V] в общем checklist относятся к предыдущим аудитам;
новые незавершённые пункты отмечены [~].
Linux: ./build.sh --no-gui -j4 — PASS;20/20 профильных тестов — PASS:
media_primitives, attachment, attachment_send, encrypted_file, encrypted_attachment,
media_async, media_index, media_index_regressions, media_delivery_sql,
media_delivery_download, media_download_timeout, media_query, media_blocks,
media_replication, media_delivery_integration, media_delivery_full,
media_delivery_chat, dm_media, dm_worker, services.
Логи: /tmp/media-audit-build.log, /tmp/media-doc-audit-results.log,
/tmp/media-doc-audit-logs/. Штатный test_encrypted_file не покрывает alias.
Старые сбои encrypted_attachment/media_delivery_chat в этом прогоне не воспроизвелись;
один PASS не закрывает задачи о нестабильности.
Полный check.sh и новые sanitizer-прогоны в этом аудите не запускались.
+11
View File
@@ -4,6 +4,17 @@
## Текущие задачи
[ ] **media_async encrypted_file: не уничтожать source через alias назначения** — подтверждено 24.10.2026.
write/read отвергают только одинаковые строки; /./ и hardlink обходят проверку одного файла.
write возвращает0, заменяя исходные30 байт контейнером пустого файла; read возвращает0,
заменяя входной ciphertext182 байта plaintext30 байт. Проверены реальные функции, inode и SHA256.
До fopen(wb) проверять идентичность общими file_io-примитивами; один файл — ошибка без изменения/удаления.
Сохранить destination как временный файл вызывающего, публикацию оставить chat_attachment/dm_media.
Детали, проверка архитектуры исправления и незавершённый аудит: [media_async_audit_findings.txt](media_async_audit_findings.txt).
Воспроизведение: /tmp/media-encrypted-alias-repro.c, /tmp/media-encrypted-alias-repro.log.
Linux-сборка и20/20 профильных тестов PASS; штатный test_encrypted_file не проверяет alias.
/tmp/media-doc-audit-results.log. Код модулей не изменён; дальнейший аудит остановлен по AGENTS.md.
[+] **Proxy: исправить HUP/backpressure, владение и rollback** — завершено 24.10.2026.
Согласованный проект, причины и результаты: [doc/proxy_fix_plan.txt](proxy_fix_plan.txt).
HUP больше не обходит read_high_water/ручную паузу; idle HUP снимается с poll,