Приватный пакет для воспроизведения сквозной санитизации по шести находкам GDCM
Шесть дефектов парсера/кодека в GDCM, воспроизведённых на v3.2.6 как сбои санитайзера или ограниченные проверки распространения. Каждый автоматический триггер имеет почти валидный контроль, который не производит уязвимый сигнал. Результат 1 также включает инструментированный примитив потока управления.
Предназначено для проверки сопровождающим и координатором по уязвимостям. Прочитайте SAFETY.md перед
запуском чего-либо.
manifest/targets.env:
| Имя | Ревизия | Что это |
|---|
vulnerable | 9c71b163 | тег v3.2.6 |
master | 2cd05d13 | снимок upstream master, проверенный статически; матрица времени выполнения ожидается |
fixed | не задано | заполняется только после появления проверенного коммита исправления |
master — это датированный снимок, а не движущаяся ветка. Обе ревизии доступны из
публичного репозитория, поэтому bootstrap.sh может подготовить любую из них без приватных исходников.
Доказательства времени выполнения в этом репозитории относятся к v3.2.6. Более широкие диапазоны ниже получены из инспекции истории исходников; затронутые паттерны также остаются в закреплённом снимке master.
| # | CWE | Диапазон по исходникам | Требуемый путь |
|---|---|---|---|
| 1 | CWE-787 | с v3.0.4 по v3.2.7 | чтение многокадрового RLE YBR_FULL_422 |
| 2 | CWE-787 | с v2.0.16 по v3.2.7 | кодирование/транскодирование JPEG2000 |
| 3 | CWE-125 | с v2.0.5 по v3.2.7 | разбор сегментированной палитры; применение LUT раскрывает распространённые значения |
| 4 | CWE-787 | с v2.0.8 по v3.2.7 | ImageRegionReader::ReadIntoBuffer; связано с неполной валидацией точности после CVE-2024-22373 |
| 5 | CWE-674 | с v2.0.4 или ранее по v3.2.7 | обычный разбор вложенных последовательностей |
| 6 | CWE-369 | с v2.0.4 или ранее по v3.2.7 | обычный разбор RLE с NumSegments=0 |
fixtures/ — инертные входные данные DICOM, закреплённые по SHA-256 в manifest/expectations.json
и проверяемые перед каждым запуском триггераgenerators/ — детерминированные генераторы исходников без зависимостей для каждого фикстураharnesses/ — минимальные обвязки чтения/кодирования/декодирования; Результат 2 показан как через
CLI gdcmconv, так и через библиотечный API транскодирования, который вызвал бы серверmanifest/expectations.json — машиночитаемые команды, решающие сигналы и
критерии приёмки для цели fixedscripts/ — подготовка закреплённых исходников, сборки с санитайзерами, ограниченное выполнение, очисткаevidence/ — краткие уже наблюдавшиеся результаты с явным указанием непроверенных целейLICENSE — лицензия MITОдноразовая среда сборки Linux или macOS с Git, Python 3, CMake 3.20+, Ninja и
инструментальной цепочкой C++11 (Clang или GCC). В Ubuntu: git python3 cmake ninja-build clang zlib1g-dev. Установите CC/CXX, чтобы использовать GCC вместо этого.
Подготовка исходников клонирует по HTTPS, если GDCM_SOURCE_REPO не указывает на существующий
локальный клон. SSH-хост не используется.
Эти команды подготавливают только исходники и артефакты сборки; они не открывают никакой фикстур.
./scripts/build-target.sh vulnerable asan debug
./scripts/build-target.sh vulnerable ubsan debug
./scripts/build-target.sh master asan debug
./scripts/build-target.sh master ubsan debug
Третий аргумент — это профиль. debug — это -O0 -g; release — это -O2 -g -DNDEBUG,
что исключает gdcm_debug_assert() из GDCM и соответствует тому, как дистрибутивы собирают
библиотеку. Запуск матрицы под обоими отвечает на первый вопрос, который задаёт сопровождающий,
а именно: являются ли отчёты артефактом сборки с включёнными утверждениями.
GDCM_SUPPORT_BROKEN_IMPLEMENTATION=ON — это собственное значение по умолчанию GDCM, и оно оставлено без изменений.
Переопределите консервативный параллелизм с помощью JOBS=8.
Каждая сборка записывает build-info.json (ревизия, компилятор, флаги, платформа) в своё дерево сборки GDCM,
и каждое резюме запуска встраивает его, поэтому архивированные доказательства самодостаточны.
export GDCM_REPRO_ACK=I_UNDERSTAND_THIS_CRASHES_A_LOCAL_PROCESS
./scripts/run-matrix.sh vulnerable master --profile debug # все автоматические случаи
./scripts/run-one.sh vulnerable f1 # один триггер
./scripts/run-one.sh vulnerable f1 --control # его контроль
run-matrix.sh запускает каждый автоматический случай для каждой цели, не останавливается на первом
сбое и записывает _runs/matrix-<stamp>.json плюс отрендеренный
_runs/matrix-<stamp>.md. Двухэтапный случай f1-exploit остаётся ручным и сообщается
как таковой, а не ошибочно классифицируется как неудавшийся автоматический случай.
У каждого дочернего процесса отключены дампы ядра и установлен 15-секундный тайм-аут; Результат 5 дополнительно получает
ограниченный лимит стека. Выходные данные остаются в _runs/. Классификатор сопоставляет класс санитайзера
и затронутую функцию, никогда — адреса, PID или номера строк исходников.
Для vulnerable случай проходит, когда появляется решающий сигнал и его контроль остаётся
чистым. Для master раннер записывает наблюдение, а не предварительно объявленный вердикт.
Для fixed случай проходит только когда сигнал отсутствует, не появляется никакой другой сигнал санитайзера или фатальный
сигнал, и обвязка возвращает допустимый чистый результат. Эти правила предварительны, пока FIXED_REV не назовёт фактический патч; они должны быть проверены на предмет
предполагаемого поведения патча «отклонить или обработать».
| Случай | Результат | Что показывает |
|---|---|---|
f1 | 1 | запись в кучу ASan в RLECodec::DecodeFragment |
f1-exploit | 1 | инструментированная перезапись соседнего объекта и управление косвенной ветвью (Linux x86-64) |
f2 | 2 | запись в кучу ASan в opj_write_from_memory через gdcmconv --j2k |
f2-lib | 2 | та же запись через ImageChangeTransferSyntax::Change |
f3 | 3 | чтение из кучи ASan при расширении сегментированной палитры |
f3-propagation | 3 | байты за пределами границ достигают декодированных пикселей, сообщается как количество |
f3-sentinel | 3 | ограниченное известное защитное слово пересекает логическую границу LUT |
f4 | 4 | запись в кучу ASan при декодировании области JPEG2000 |
f5 | 5 | исчерпание стека ASan на вложенных элементах последовательности |
f6 | 6 | деление на ноль UBSan при декодировании RLE; SIGFPE на x86 |
Ещё две обвязки являются исследованием эксплуатируемости, а не случаями воспроизведения, и собираются только в профиле без санитайзеров на Linux x86-64:
| Обвязка | Результат | Что устанавливает |
|---|---|---|
finding01_groom | 1 | протестированная смежность glibc, наблюдаемая через хуки записи выделений |
finding03_leak | 3 | перечитывание на 131070 байт может раскрыть специфичный для сборки указатель библиотеки |
evidence/v3.2.6-macos-arm64-debug.md фиксирует завершённую отладочную матрицу v3.2.6,
включая каждый контроль и обе ограниченные проверки распространения Результата 3.
evidence/v3.2.6-linux-x86_64-finding01-groom.md и
evidence/v3.2.6-linux-x86_64-finding03-leak.md фиксируют два результата эксплуатируемости
ниже. Результаты текущего master, полной матрицы релизного профиля и f1-exploit не
заявляются, пока их стенограммы не сохранены.
./scripts/clean.sh
Очистка отказывается запускаться без маркера пакета и удаляет только _work, _build,
_generated, _runs и кэши байт-кода Python под этим репозиторием. Сохранённые
доказательства в evidence/ не удаляются.
f1-exploit работает только на Linux-x86_64 и запускается вручную; manifest/expectations.json содержит
точную последовательность команд. При детерминированной схеме размещения обвязки он проверяет
три отдельных факта, каждый с согласованным негативным случаем:
f1 сообщает о повреждении, но явно
не о контроле содержимого, поэтому проверка фальсифицируема;Примерно половина 8-байтовых окон в пределах 12288-байтового переполнения принимает произвольное
значение. Остальные связаны, потому что DoYBRFull422 дублирует один исходный байт в две
выходные позиции; смещение 6144 — одно из свободных окон. Декодирование кадра 1 выполняется последним, поэтому
именно содержимое кадра 1 сохраняется после выделения.
Обвязка записывает, возвращает ли ImageReader::Read() true, пока соседний объект
изменён. Успешная стенограмма Linux x86-64 должна быть сохранена, прежде чем описывать этот
результат как наблюдаемое доказательство.
f1-exploit предоставляет свою собственную схему жертвы, поэтому он не может ответить, имеет ли немодифицированный
процесс такую схему. finding01_groom использует стандартную glibc, PIE по умолчанию и ASLR, с
глобальными хуками выделения, которые записывают, но не перемещают выделения. В сохранённых
тестах:
finding01 умирает так же без какого-либо инструментирования.На протестированной сборке glibc Результат 1 надёжно вызывал отказ в обслуживании; путь выполнения кода не был найден. Протестированная геометрия была фиксированной, и другие аллокаторы или платформы могут размещать кучу иначе.
finding03_leak — более сильный результат. В протестированной сборке чтение за пределами границ
достигает 131070 байт, указатель vtable gdcm::ByteValue попадает в декодированные пиксели, и
обвязка выводит базу загрузки библиотеки, используя известное смещение vtable этой сборки. Это
результат локального раскрытия на уровне API: он требует применения LUT и доступа к декодированному
буферу пикселей. Он не показывает, что сетевой сервис возвращает эти пиксели.
Эти два нельзя объединить в выполнение кода здесь, и не только потому, что жертва не была найдена: им нужны разные значения PhotometricInterpretation, поэтому нужны два файла, и утечка базы полезна только пока процесс, выполняющий утечку, ещё жив.
Отчёт санитайзера доказывает заявленное событие нарушения безопасности памяти или неопределённого поведения в
протестированном процессе и ревизии. f1-exploit проверяет контроль байтов и перезапись соседнего указателя
на функцию под инструментированным аллокатором, который намеренно предоставляет целевую
схему. Он не устанавливает эту схему в немодифицированном потребителе. Сохранённые
испытания finding01_groom не наблюдали эту схему для протестированной геометрии и сборки
glibc.
Ничто из этого не доказывает удалённую достижимость в каком-либо конкретном продукте, персистентность или применимость в нижележащих системах. Аргумент достижимости для данного развёртывания — это отдельное утверждение, сделанное в тексте раскрытия, а не этим пакетом.