Один бит в DRAM обходит защиты AMD Family 16h

Один бит в DRAM обходит защиты AMD Family 16h

На GitHub опубликован рабочий PoC, проект skitter-creek-bath-salts. Он показывает, что один переключаемый бит в служебном регистре контроллера памяти AMD переписывает соответствие между физическим адресом обращения и реальными координатами внутри чипа DRAM (банк, ранг, строка, столбец), и тем самым открывает доступ к зарезервированным областям памяти, невидимым даже для ядра ОС: область Platform Security Processor (PSP, выделенный сопроцессор AMD), область System Management Mode (SMM, привилегированный режим прошивки), защищённую память в энергосберегающем состоянии C6 и область микрокода процессора. Проект разработан и протестирован на процессорах AMD семейства 16h (Family 16h).

Причина в том, что путь от обращения по указателю до физического бита в DRAM состоит из множества последовательных проверок: разбор виртуального адреса и TLB, постраничный поиск прав доступа, при виртуализации, повторный проход через таблицы EPT/NPT, при обращении устройства, таблицы IOMMU, затем определение типа памяти (MTRR/PAT), кэши и когерентность между ядрами и сокетами, системная шина, и лишь в самом конце физический адрес попадает в контроллер памяти (в терминологии AMD, MCT/DCT), который окончательно переводит его в координаты внутри модуля DRAM. Все перечисленные механизмы защиты проверяют именно физический адрес; ни один из них не видит и не контролирует этот последний шаг перевода. Проект формулирует это так: «Барьеры охраняют физические адреса, а не координаты DRAM; переставь координаты, и те, что выше, этого не заметят».

Технически весь трюк, переключение так называемого режима перемешивания банков (bank swizzle) в регистре DCT по MMIO-адресу 0xf80c2094: инструкция xor dword [0xf80c2094], 0x00400000 (маска соответствует 22-му биту регистра). Повторное выполнение той же инструкции возвращает всё обратно. Проект описывает результат как «спагеттификацию» DRAM, по аналогии с тем, как приливные силы у чёрной дыры бесконечно растягивают падающее вещество; после переключения бита указатель на одни и те же данные (&x) перестаёт быть равен самому себе. Заголовок «Spaghettifying DRAM» носит раздел README и будущий доклад на Black Hat 2026, а не сам проект: тот называется skitter-creek-bath-salts. Эксплуатируемый бит, лишь один из десятков подобных настроек в DCT, управляющих финальным преобразованием адреса.

Чтобы прочитать данные из защищённой области, не вызвав сбоя платформы, проект описывает короткую последовательность действий: остановить остальные ядра процессора, заранее прогреть TLB и кэш для служебного и целевого адресов, отключить прерывания, сбросить кэш для целевого адреса, переключить бит в регистре DCT, прочитать данные в «перепутанном» отображении памяти (в опубликованном примере, по адресу 0x6f800000), вернуть бит обратно, включить прерывания и возобновить работу остальных ядер, так, чтобы платформа тут же вернулась в нормальное состояние. Рабочий пример приведён и на чистом ассемблере, и, при аккуратной настройке страничных таблиц, состояния кэша, потоков и TLB, на языке C.

Отдельная сложность, после переключения бита заранее неизвестно, куда именно «уехал» нужный адрес: даташиты AMD описывают эту часть контроллера не полностью (XOR-преобразования в них расходятся с реальностью, порядок исключения диапазонов MMIO не задан, детали различаются между моделями). Проект решает это математически: преобразование адреса в контроллере памяти, линейное отображение над полем Галуа GF(2), то есть комбинация XOR над отдельными битами адреса, а значит, новое отображение можно восстановить методами линейной алгебры, а не подбором. Это показано на конкретном примере: матрица обычного преобразования переводит один и тот же секрет в DRAM в определённый физический адрес, а после переключения бита уже другая, пересчитанная матрица показывает, какой другой адрес указывает на тот же самый секрет. Вывод в тексте проекта звучит жёстко: с таким подходом любая защищённая область памяти на платформе становится достижимой «с помощью калькулятора».

Материал прямо ограничивает область действия. AMD Family 16h назван последним поколением, чьи даташиты документируют регистры трансляции контроллера памяти и прямо показывают, что заблокировать их нельзя; начиная с Family 17h AMD убрала это описание из открытой документации. Проект утверждает, что похожий путь трансляции адреса существует в разных поколениях процессоров и архитектурах и что описанные преобразования «распространяются даже на ARM, RISC-V и далее», но оговаривается, что показывает лишь то, как эта работа «начинается»: рабочий код и точные адреса регистров в материале относятся исключительно к AMD Family 16h. Текст не описывает это как случившуюся атаку в реальных условиях, это демонстрация техники, а не отчёт об инциденте; в нём нет ни присвоенного CVE, ни сведений об уведомлении AMD, ни конкретной модели процессора или платы за пределами обозначения семейства, ни данных о том, сколько времени занимает атака и насколько она надёжна.

Ключевые факты

  • Проект skitter-creek-bath-salts на GitHub одним переключаемым битом в регистре контроллера памяти AMD (MMIO-адрес 0xf80c2094, маска 0x00400000 / 22-й бит) переписывает соответствие между физическим адресом и реальными координатами ячейки в DRAM.
  • Так обходятся все механизмы, которые проверяют физический адрес, но не видят финальный шаг его перевода в контроллере памяти: Platform Security Processor, System Management Mode, защищённая память в состоянии C6 и область микрокода.
  • Поскольку преобразование адреса контроллером памяти, линейное отображение над полем Галуа GF(2), новое расположение данных после переключения бита вычисляется методами линейной алгебры, даже когда даташиты AMD описывают регистр не полностью.
  • Практическая процедура чтения защищённых данных, несколько быстрых шагов (остановить остальные ядра, прогреть кэш и TLB, отключить прерывания, переключить бит, считать данные, вернуть всё обратно), показанная и на ассемблере, и на языке C.
  • Техника разработана и протестирована на AMD Family 16h, последнем поколении, чьи даташиты документируют эти регистры; начиная с Family 17h документация этого не описывает, а сам материал, демонстрация PoC, а не отчёт о реальной атаке, без CVE и данных об ответе AMD.

Почему это важно

Все стандартные механизмы защиты процессора и платформы, Platform Security Processor, System Management Mode, зарезервированная память в состоянии C6, область микрокода, проверяют физический адрес обращения к памяти. Но между физическим адресом и реальной ячейкой DRAM есть ещё один, последний шаг: контроллер памяти (MCT/DCT) переводит физический адрес в координаты банка, ранга, строки и столбца внутри самого чипа. Этот перевод не проверяет ни одна из систем защиты выше по стеку, они его попросту не видят. Проект показывает, что для того, чтобы переписать, куда на самом деле ведёт физический адрес, достаточно одной инструкции XOR по конкретному MMIO-регистру (0xf80c2094), и все проверки выше остаются в неведении. Это демонстрация не единичной ошибки в одном продукте, а того, что вся многоуровневая защита современного процессора опирается на предположение, которое сама не проверяет: что физический адрес, последнее слово в том, где реально лежат данные.

Кому это важно

В первую очередь, тем, кто проектирует или оценивает аппаратные механизмы изоляции памяти на уровне процессора и прошивки: инженерам AMD и других производителей чипов, исследователям безопасности прошивки, командам, отвечающим за конфиденциальные вычисления и доверенное окружение выполнения на серверах, которые полагаются на PSP, SMM и подобные механизмы как на границу доверия. Практическая демонстрация в проекте ограничена процессорами AMD семейства 16h, сравнительно старым поколением. Но сам проект утверждает, что похожий путь трансляции адреса существует в разных поколениях процессоров и архитектурах, включая ARM и RISC-V, то есть значение находки, по формулировке проекта, выходит за рамки одного семейства чипов, даже если рабочий код и точные адреса регистров показаны только для AMD.

Как это применить

Это не абстрактное описание, а рабочий код: репозиторий skitter-creek-bath-salts на GitHub содержит и ассемблерную последовательность, и версию на языке C, которые можно запустить и увидеть эффект напрямую, момент, когда указатель на одни и те же данные (&x) перестаёт быть равен самому себе. Порядок действий, который описывает проект: остановить остальные ядра процессора, заранее прогреть TLB и кэш для служебного и целевого адресов, отключить прерывания, сбросить кэш для целевого адреса, переключить бит bank-swizzle в регистре DCT (xor dword [0xf80c2094], 0x00400000, он же 22-й бит), прочитать данные в «перепутанном» отображении памяти, вернуть бит обратно, включить прерывания и возобновить работу остальных ядер. Поскольку сразу после переключения бита неизвестно, куда переместился нужный адрес, даташиты AMD эту часть контроллера описывают не полностью, проект показывает, как восстановить новое отображение адресов методами линейной алгебры, рассматривая преобразование как линейную операцию над полем Галуа GF(2), а не подбором вручную.

Можно ли доверять

Это не голословное заявление, а воспроизводимый технический материал: указан точный MMIO-адрес регистра (0xf80c2094), точная битовая маска (0x00400000, 22-й бит), приведён рабочий код на ассемблере и на C, а математика восстановления отображения адресов, линейная алгебра над GF(2), показана на конкретных примерах матриц, а не только описана словами. Обсуждение на Hacker News набрало 591 голос и 153 комментария, заметная вовлечённость технической аудитории, у которой была возможность указать на ошибку в коде или в адресах регистров, если бы она была. Атрибуция не анонимна: в README проекта указан автор, Christopher Domas (@xoreaxeaxeax), а в разделе References, доклад Black Hat 2026. Слабое место в другом: сама статья не называет дату публикации, поэтому точный приоритет разработки по одному этому материалу не проверить.

Риски и подводные камни

Материал не описывает это как случившуюся атаку в реальных условиях, это демонстрация техники на собственном стенде, PoC, а не отчёт об инциденте. Конкретная модель процессора или материнской платы, помимо обозначения семейства Family 16h, в тексте не названа. Нет ни присвоенного CVE, ни сведений об уведомлении AMD или статусе исправления, ни данных о том, сколько времени занимает атака и насколько она надёжна (сколько попыток нужно, сохраняется ли эффект на разных экземплярах железа). Рабочий код и точные адреса регистров относятся только к AMD Family 16h, сравнительно старому поколению, чьи даташиты AMD ещё публиковала полностью; начиная с Family 17h такого описания в открытой документации уже нет, о чём проект прямо пишет. Заявление, что похожие преобразования адреса «распространяются даже на ARM, RISC-V и далее», тезис самого проекта, а не показанный на этих архитектурах рабочий эксплойт: конкретные регистры и код в материале приведены только для AMD.

«Вот и весь эксплойт. Целиком.»

— проект skitter-creek-bath-salts