
CVE-2025-62518: TARmageddon

Этот репозиторий демонстрирует критическую ошибку в tokio-tar и связанных асинхронных Rust-библиотеках для tar, где переопределения размера в PAX-расширенных заголовках не применяются до расчета позиции следующего заголовка.
Корневая причина: При обработке tar-файлов с PAX-расширенными заголовками, которые переопределяют размер файла, библиотека использует восьмеричное поле размера (часто ноль) вместо PAX-переопределения для расчета позиции.
Воздействие: Это заставляет парсер перескакивать в содержимое файла и ошибочно принимать его за tar-заголовки, что приводит к извлечению неправильных файлов.
Известные затронутые библиотеки:
async-tar https://github.com/dignifiedquire/async-tartokio-tar https://github.com/vorot93/tokio-tarkrata-tokio-tar https://github.com/edera-dev/tokio-tarastral-tokio-tar https://github.com/astral-sh/tokio-tar# Требования: CMake, Rust/Cargo, компилятор C++, системная команда tar
cmake -S . -B build
cmake --build build --target generate_report
Это позволит:
build/output/├── disclosure/ # Security disclosure documentation tree
│ └── blast_radius/ # Record of projects depending on tokio-tar variants
├── repro_generator/ # C++ tool to generate a repro case tar file
├── tar-bug-detector/ # Rust tool comparing tar libraries
├── tarwalk/ # Correct C++ tar parser
│ ├── tarwalk.cpp # Handles PAX correctly
│ └── tarwalk_bad.cpp # Reproduces the same bug
├── CMakeLists.txt # Build system
├── generate_report.cmake # Report generation
└── README.md # This file
Header -> Content (size from octal field) -> Next Header
PAX Header (size=1024) -> File Header (octal size=0) -> Content (1024 bytes) -> Next Header
PAX Header (size=1024) -> File Header (octal size=0) -> Content (0 bytes) -> WRONG POSITION
↓
Reading content as headers!
Docker save создаёт tar-файлы с:
etc/, usr/)pax_bug_compact.tar — Минимальный пример для воспроизведенияКорректные библиотеки (GNU tar, синхронный крейт tar):
normal.txt -> blob.bin -> marker.txt
Библиотеки с ошибкой (tokio-tar):
normal.txt -> blob.bin -> INNER_FILE -> marker.txt
Появление INNER_FILE указывает на ошибку — библиотека перескочила в содержимое blob.bin и приняла поддельный tar-заголовок за настоящую запись.
Исправление требует применения PAX-переопределений перед расчётом позиции:
// Чтение заголовка
let mut file_size = header.size();
// Применение PAX-переопределений ПЕРЕД расчётом следующей позиции
if let Some(pax_size) = pending_pax.get("size") {
file_size = pax_size.parse().unwrap();
}
// Теперь расчёт позиции следующего заголовка с использованием эффективного размера
let next_pos = current_pos + 512 + pad_to_512(file_size);
Этот код для воспроизведения предоставлен в целях исследования безопасности и ответственного раскрытия информации.
См. COPYING для лицензии исходного кода.