Record validated encrypted attachment ownership fix and remaining audit scope
This commit is contained in:
1 parent
4862a52684
commit
1227027c2f
3 files changed
+54
-10
No files matched your search
@@ -1,6 +1,6 @@
|
||||
Аудит media_async / media_delivery — 2026-10-24
|
||||
Статус: частичный; остановлен на подтверждённом дефекте по AGENTS.md.
|
||||
Код модулей не изменён. Сборка Linux и 20 профильных тестов прошли.
|
||||
Статус: подтверждённый дефект исправлен; полный аудит двух каталогов ещё не завершён.
|
||||
Ниже сохранены исходное воспроизведение и согласованный проект; результаты исправления — в конце.
|
||||
|
||||
Подтверждённый дефект: исходник уничтожается через другое имя того же файла
|
||||
|
||||
@@ -29,7 +29,7 @@ source/destination. Разные строки могут обозначать о
|
||||
- /tmp/media-encrypted-alias-lvVS77/ — сохранённые входы и результаты опыта.
|
||||
Проектные .c/.h для воспроизведения не менялись.
|
||||
|
||||
Архитектурно уточнённый фикс — проект, код ещё не изменён
|
||||
Согласованная архитектура исправления
|
||||
|
||||
Одной проверки file_io_paths перед fopen(wb) недостаточно для полного исправления
|
||||
контракта владения. Сейчас encrypted_file удаляет destination при ошибке, а
|
||||
@@ -151,8 +151,8 @@ DM не вызывает encrypted_file_write/read: он использует me
|
||||
- Профильные 20 тестов, ASAN/UBSan/LSan и полный набор. Изменение file_io требует
|
||||
также проверки его прежних пользователей: copy, video и media blocks/download.
|
||||
|
||||
Это архитектурный проект. Уточнённый фикс ещё не реализован и не тестировался;
|
||||
успешные 20 тестов ниже относятся к текущей реализации до исправления.
|
||||
Этот проект реализован. Успешные 20 тестов ниже относятся к исходной реализации;
|
||||
проверки исправленного кода приведены в конце.
|
||||
|
||||
Что проверено и что осталось
|
||||
|
||||
@@ -172,4 +172,40 @@ media_delivery_chat, dm_media, dm_worker, services.
|
||||
/tmp/media-doc-audit-logs/. Штатный test_encrypted_file не покрывает alias.
|
||||
Старые сбои encrypted_attachment/media_delivery_chat в этом прогоне не воспроизвелись;
|
||||
один PASS не закрывает задачи о нестабильности.
|
||||
Полный check.sh и новые sanitizer-прогоны в этом аудите не запускались.
|
||||
На исходном этапе полный check.sh и новые sanitizer-прогоны не запускались.
|
||||
|
||||
Результаты исправления — 2026-10-24
|
||||
|
||||
- file_io_temp получил единый FILE_IO_DURABLE: sync открытого fd при finish,
|
||||
write-through rename на Windows и directory sync после rename на POSIX.
|
||||
После rename temporary пуст, включая отказ directory sync; discard не удаляет результат.
|
||||
Общие sync/publish функции перенесены в file_io; DM вызывает их напрямую.
|
||||
- Write/read готовят отдельный закрытый temp. Source/target не открываются с усечением;
|
||||
совпадающая строка, /./, hardlink и конечная ссылка отклоняются до создания выхода.
|
||||
Read выдаёт info/type только после успешного закрытия/сохранения проверенного результата.
|
||||
- ak_file хранит один output, учитывает подготовленный plaintext snapshot и выполненный rename.
|
||||
Worker публикует один раз; completion очищает только собственные артефакты.
|
||||
Кеш использует реестр владельцев; recovery очищает строгие temp в media и decrypted.
|
||||
Построение путей и SQL recovery используют одну каноническую media_base.
|
||||
- test_encrypted_file: прежние шесть размеров, восемь alias-сценариев обоих API,
|
||||
активный output, alias перед publish и 23 отказа I/O с контролем fd/temp/метаданных.
|
||||
До rename прежний target сохраняется; после отказа directory sync новый файл установлен.
|
||||
- test_media_primitives: durable и обычный режим, sync failure до rename, failure после
|
||||
rename, относительный/корневой каталог, защита активного temp в worker и после close.
|
||||
- test_attachment_send детерминированно ждёт настоящего crypto rename без обработки
|
||||
completion, затем останавливает сервис: нет сообщения/ключа/оставшихся файлов/temp.
|
||||
- test_encrypted_attachment при каждом startup/restart проверяет оба дерева:
|
||||
stale temp удалены; открытый/закрытый активные owners, конечные файлы и чужие имена сохранены.
|
||||
- Профильный Linux-набор: 21/21 PASS, включая video/no_ffmpeg, DM, services и media delivery.
|
||||
Основной make check: 185/185 PASS. TUN в отдельном network namespace с тем же бинарником:
|
||||
proxy9/9, burst1/1, load8/8 PASS; 134217728 проверенных байт.
|
||||
- ASAN/UBSan/LSan: 21/21 PASS с detect_leaks=1. Все встроенные зависимости собраны
|
||||
с sanitizer-флагами в /tmp/utun-media-fix-sanitizers; обычные объекты проекта не смешивались.
|
||||
Windows/FreeBSD build/runtime не проверялись.
|
||||
|
||||
Логи: /tmp/media-fix-profile-results.log, /tmp/media-fix-full-check.log,
|
||||
/tmp/media-fix-network-check.log, /tmp/media-fix-sanitizer-results.log,
|
||||
/tmp/media-fix-cancel-after-rename.log, /tmp/media-fix-encrypted-file.log.
|
||||
Проверка реализации не выявила противоречий владения в перечисленных сценариях.
|
||||
Частичные отметки остальных файлов аудита сохраняются; этот фикс не означает полного
|
||||
завершения проверки media_async/media_delivery или закрытия старых нестабильных тестов.
|
||||
+8
-4
@@ -4,19 +4,23 @@
|
||||
|
||||
## Текущие задачи
|
||||
|
||||
[ ] **media_async encrypted_file: не уничтожать source через alias назначения** — подтверждено 24.10.2026.
|
||||
[+] **media_async encrypted_file: не уничтожать source через alias назначения** — исправлено 24.10.2026.
|
||||
write/read отвергают только одинаковые строки; /./ и hardlink обходят проверку одного файла.
|
||||
write возвращает0, заменяя исходные30 байт контейнером пустого файла; read возвращает0,
|
||||
заменяя входной ciphertext182 байта plaintext30 байт. Проверены реальные функции, inode и SHA256.
|
||||
Архитектурный фикс: один file_io_temp в ak_file; codec готовит закрытый проверенный temp,
|
||||
Реализован один file_io_temp в ak_file; codec готовит закрытый проверенный temp,
|
||||
worker публикует его одним rename. Target не открывается с усечением; alias проверяется до work и перед publish.
|
||||
Durability задаётся на весь срок temp; ошибка directory sync после rename не считается откатом.
|
||||
Cleanup удаляет только собственные артефакты; crash recovery учитывает temp в media и decrypted.
|
||||
DM не вызывает codec: сохранить его контракт общих sync/publish helpers при изменениях file_io.
|
||||
Детали, проверка архитектуры исправления и незавершённый аудит: [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.
|
||||
Добавлены восемь alias-сценариев, 23 отказа I/O с контролем fd/temp/метаданных,
|
||||
отмена настоящего worker после rename до completion, startup/restart обоих деревьев.
|
||||
Профильные21/21 и основной make check185/185 PASS; proxy9/9, burst1/1, load8/8 PASS
|
||||
в отдельном network namespace,134217728 проверенных байт. ASAN/UBSan/LSan21/21 PASS, detect_leaks=1.
|
||||
Логи: /tmp/media-fix-full-check.log, /tmp/media-fix-network-check.log, /tmp/media-fix-sanitizer-results.log.
|
||||
Полный аудит остальных контрактов media_async/media_delivery ещё не завершён; Windows/FreeBSD не проверялись.
|
||||
|
||||
[+] **Proxy: исправить HUP/backpressure, владение и rollback** — завершено 24.10.2026.
|
||||
Согласованный проект, причины и результаты: [doc/proxy_fix_plan.txt](proxy_fix_plan.txt).
|
||||
|
||||
@@ -18,7 +18,9 @@ static FILE *input_file, *output_file;
|
||||
FILE* __real_fopen(const char*, const char*);
|
||||
FILE* __real_fdopen(int, const char*);
|
||||
size_t __real_fread(void*, size_t, size_t, FILE*), __real_fwrite(const void*, size_t, size_t, FILE*);
|
||||
#ifdef __GLIBC__
|
||||
size_t __real___fread_chk(void*, size_t, size_t, size_t, FILE*);
|
||||
#endif
|
||||
int __real_ferror(FILE*), __real_fflush(FILE*), __real_fclose(FILE*), __real_fsync(int);
|
||||
int __real_fseeko(FILE*, off_t, int), __real_rename(const char*, const char*);
|
||||
int __real_random_bytes(uint8_t*, size_t);
|
||||
@@ -40,10 +42,12 @@ size_t __wrap_fread(void* data, size_t size, size_t count, FILE* file) {
|
||||
if (file == input_file && inject(F_READ)) { read_failed = 1; return 0; }
|
||||
return __real_fread(data, size, count, file);
|
||||
}
|
||||
#ifdef __GLIBC__
|
||||
size_t __wrap___fread_chk(void* data, size_t cap, size_t size, size_t count, FILE* file) {
|
||||
if (file == input_file && inject(F_READ)) { read_failed = 1; return 0; }
|
||||
return __real___fread_chk(data, cap, size, count, file);
|
||||
}
|
||||
#endif
|
||||
int __wrap_ferror(FILE* file) { return file == input_file && read_failed ? 1 : __real_ferror(file); }
|
||||
size_t __wrap_fwrite(const void* data, size_t size, size_t count, FILE* file) {
|
||||
return file == output_file && inject(F_WRITE) ? 0 : __real_fwrite(data, size, count, file);
|
||||
|
||||
Reference in new issue
Block a user