Заметки с bring‑up‑а собственной ОС на Samsung Galaxy Tab S6 (SM‑T865, Snapdragon 855). Всё ниже — не гипотеза, а то, что пришлось выяснить, чтобы Wi‑Fi просто заработал.
Проблема
На макетке Wi-Fi — 950 строк Rust за несколько дней. На планшете «то же самое» стало 32 000 строк: девять стадий, десяток тихих сбросов из secure world, четыре сервера для чипа. Объяснение «SoC сложнее» — неверное.
Что сделали
Разобрали, кем радио является в системе: половина модема с DMA в нашу память, файловым сервером и своим радио — жилец с ключами арендодателя. Построили модель угроз по каналам для Android, Linux и нас, и принцип прозрачной изоляции: тень вместо диска, пустой список вместо отказа.
Что получилось
Прошивка получает синтаксически правильные, пустые по сути ответы и работает; писать на диск хоста ей некуда. Честный список «не можем»: трафик, ключи, эфир, сотовый uplink — конфиденциальность строится выше, в TLS и e2e.
0. Затравка: почему «то же самое» стало в тридцать раз сложнее
Мы пишем ОС на Rust с нуля — без Linux, без Android. Началось всё с макетки: STM32F407 (плата F4VE), к ней по SPI дисплей ILI9341 и резистивный тач, а рядом — модуль ESP32 со стоковой прошивкой ESP‑AT, подключённый к микроконтроллеру одним UART‑ом. Wi‑Fi выглядел так: пишешь в порт AT+CWJAP="ssid","pass", читаешь WIFI GOT IP; пишешь AT+CIPSTART="SSL","api.cursor.com",443 — и MCU без единого байта криптографии разговаривает с сервером по HTTPS, потому что TLS считает модуль. Весь драйвер — парсер строк и несколько команд: около 950 строк Rust. Скан сетей, вход, captive portal, обновление по воздуху — всё заработало за считанные дни. Потом ESP32 стал самостоятельной платой той же ОС — те же 950 строк, только теперь Wi‑Fi‑стек Espressif линковался прямо в образ.
Дальше захотелось настоящего устройства: планшет Samsung Galaxy Tab S6 на Snapdragon 855 — экран, тач, батарея, Wi‑Fi, всё уже в корпусе. План был буквально «сделать то же самое». Дисплей и тач сопротивлялись в меру. А Wi‑Fi — нет. Вместо одного UART‑а — девять стадий инициализации, десяток тихих перезагрузок всего чипа, каждая — из secure world, без паники, без сообщения, без прерывания, так что причину приходилось доказывать по слову, записанному в энергонезависимую память PMIC перед шагом. Вместо парсера AT‑команд — загрузчик подписанных образов через TrustZone, четыре сервера IPC, которые мы должны поднять для чипа, DMA в нашу память, рукопожатие QMI с передачей регионов RAM через secure world, семь рельс питания и два опорных такта, без любого из которых — снова тихий сброс. Около 32 000 строк вместо 950 — в тридцать с лишком раз.
Первое объяснение было простое: «ну, SoC сложнее». Оно неверное. Сложность пришла не от размера чипа, а от того, кем радио является в системе. На F4VE радио было периферией за проводом: что бы оно ни думало, дотянуться оно могло только до UART‑а. На планшете радио оказалось жильцом с ключами от дома — и все девять стадий были не «настройкой чипа», а обслуживанием его требований. Дальше — что это за жилец, почему отказать ему нельзя, что он может, касается ли это вашего телефона и ноутбука (да), и что с этим делать.
1. С чего началось
Когда на планшете дело дошло до Wi‑Fi, ожидание было простое: как на ESP32 или ноутбуке — есть чип, есть шина к нему, драйвер шлёт команды, чип отвечает. Пассивная периферия.
Реальность оказалась другой. На Snapdragon 855 «Wi‑Fi‑чип» WCN3990 — это радио‑фронтенд. Вся логика 802.11 — сканирование, ассоциация, шифрование, очереди — исполняется в прошивке на Hexagon DSP сотового модема, в той же подсистеме, что и LTE. Эта прошивка подписана Qualcomm, загружается и проверяется TrustZone, и мы не можем ни прочитать её, ни изменить, ни посмотреть на её регистры (чтение QDSP6SS из обычного мира — bus error).
И у неё есть требования к нам. Без их выполнения Wi‑Fi не поднимается — а часто и не падает с ошибкой, а тихо перезагружает весь SoC из secure world, так что единственный свидетель — слово, которое мы успели записать в энергонезависимую память PMIC перед шагом.
Вот что прошивка требует от «хоста» (нас), чтобы соизволить работать:
| Требование | Что это | Зачем ей |
|---|---|---|
| DMA в нашу память | 12 «copy engines», каналы прямого доступа к RAM | кольца дескрипторов, буферы кадров |
Файловый сервер (tqftp) | TFTP поверх внутреннего IPC | читает свои прошивки; пишет файл‑проверку server_check.txt и без успеха не грузится |
Дисковый сервер (rmtfs) | сектора разделов modemst1/2, fsg, fsc | EFS — её постоянная память на нашем диске |
Карта доменов (pd-mapper) | список «кто где живёт» | без ответа kernel/elf_loader WLAN не стартует |
Передача памяти (memshare) | перевод регионов RAM в её собственность через secure world | MSA — регион самоаутентификации |
| IPC (SMEM, SMP2P, GLINK→QRTR→QMI) | общая память и очереди сообщений | всё управление |
Это не периферия. Это со‑процессор с DMA, файловой системой, IPC и собственным радио, чей код мы не контролируем, и который ведёт себя как жилец с правами арендодателя. Отсюда рабочее название — паразит.
Оговорка сразу: мы не утверждаем, что прошивка Qualcomm делает что‑то злонамеренное. Мы говорим о структурных привилегиях — о том, что она могла бы сделать, будь она скомпрометирована (а Wi‑Fi‑прошивки компрометируют по воздуху регулярно: Broadpwn, Project Zero «Over The Air», десятки CVE Qualcomm WLAN). Модель угроз строится по привилегиям, не по намерениям.
2. Как это устроено: анатомия
2.1 Где исполняется
Дерево устройств стокового Android: qcom,icnss@18800000 — и рядом qcom,mss@4080000 с PAS id 4. WLAN — это protection domain внутри MPSS (модемной подсистемы). Один Hexagon, одна прошивка modem.mbn, внутри неё WLAN.HL.3.2.0.c3‑00910. Отдельного «чипа» с отдельной шиной (PCIe) нет: он отключён, WCN3990 сидит на SNoC — системном NoC, то есть на той же шине, что и память.
2.2 Как она достаёт нашу память
Между DMA‑мастерами и RAM на ARM стоит SMMU (IOMMU). Он умеет транслировать адреса мастера (IOVA) в физические по таблицам, которые заполняет ОС, — и тогда мастер физически не может коснуться того, чего ему не отобразили.
Поток WLAN в apps_smmu — 0x640. И в дереве стокового Android он помечен qcom,smmu-s1-bypass: трансляция stage‑1 выключена. Адрес, который прошивка пишет в дескриптор DMA, — это физический адрес RAM. Единственные заборы — stage‑2 гипервизора (Samsung) и XPU (Qualcomm TrustZone). Оба — чужие; для нашей ОС это значит: по нашей части системы паразит не ограничен ничем. Он может прочитать ядро, кучу, пароли сетей, токены аккаунта — и переписать код ядра.
Почему так сделано? Простота и совместимость. Downstream‑драйвер icnss работает так годами, и первый bring‑up у нас пошёл тем же путём: цель была «Wi‑Fi заработал», а включение трансляции по дороге ломало инициализацию тихим сбросом.
2.3 Как она достаёт наш диск и файлы
Через IPC прошивка находит на «роутере» QRTR сервисы rmtfs (id 14) и tqftp (4096) и начинает ими пользоваться как клиент: OPEN /boot/modem_fs1, RW_IOVEC (перенеси такие‑то сектора туда‑то), RRQ /readonly/firmware/image/…, WRQ /readwrite/server_check.txt.
В Linux и Android эти серверы — rmtfs и tqftpserv из qrtr‑утилит (или их проприетарные аналоги). Они делают ровно то, что просят: читают и пишут настоящие разделы modemst1/2, пишут в настоящую директорию файловой системы хоста (в Android — под /data/vendor). Модем получает персистентное хранилище на диске хоста. Это by design — EFS должна переживать перезагрузку.
2.4 Как она достаёт остальное
- SMEM — 2 МиБ общей памяти, где обе стороны аллоцируют структуры; цепочка элементов с canary, которую хост обходит по указателям, которые писал модем.
- GLINK/QRTR/QMI — очереди FIFO в SMEM; смещения и длины элементов — слова, написанные модемом.
- memshare — модем через QMI просит регионы RAM в собственность; хост идёт в secure world (
SCM assign_mem) и переводит владение. Отданный регион модем пишет своим путём — Q6 → XPU — минуяapps_smmuвообще. - Шифрование трафика — в прошивке (
hwcrypto). Ключи сессии (PTK/GTK) хост ставит в неё командойVDEV_INSTALL_KEY. Даже если WPA‑handshake считается на хосте, ключ трафика уезжает в модем. - Радио — её собственное. Что она передаёт в эфир сама — мы не видим. И у того же Hexagon есть сотовый uplink.
2.5 Схема
Всё из §2.1–2.4 в одной картинке: где живёт прошивка (модем, красное), какими путями она достаёт нашу память, диск и файлы, и где стоят — и не стоят — заборы. Синее — память, за которую идёт спор; зелёное — наш код; пунктир — «может, если захочет» (DMA куда угодно сегодня, эксфильтрация по сотовой, координаты из GNSS). Жирным обведён путь, который делает радио жильцом, а не периферией: copy engines → SMMU → RAM. Это Wi‑Fi‑срез общей карты устройства; полная карта всех жильцов (TrustZone, гипервизор, AOP, дисплей, PMIC) — во вводной статье.
3. Модель угроз: что паразит может
Разложим по трём осям — слежка, исполнение кода, данные. Для каждой: что даёт структура, и чем это ограничено у Linux/Android и у нас.
| Канал | Что даёт | Android (стоковый, icnss) | Mainline Linux (ath10k_snoc) | Наша ОС |
|---|---|---|---|---|
| DMA copy engines | чтение/запись физической RAM | bypass — физические адреса | трансляция через dma-iommu (узел wifi@18800000 с iommus, не в списке identity‑доменов) | bypass → закрываем (§8) |
rmtfs | чтение/запись разделов модема | настоящий диск | настоящий диск | тень в RAM |
tqftp | чтение прошивок, запись scratch | настоящая директория | настоящая директория | RAM‑scratch 64 КиБ |
memshare | владение регионами RAM | через TZ, свой путь | через TZ, свой путь | через TZ, минимальные гранты |
| SMEM / QMI | указатели и длины от модема | C‑парсеры, история CVE | C‑парсеры | safe Rust, баг = паника |
| Ключи трафика | видит весь трафик | в прошивке | в прошивке | в прошивке |
| Эфир, сотовая сеть | эксфильтрация | есть | есть | есть |
Ответ на вопрос «а на Linux так же?» — да, паразит тот же, и Linux его обслуживает щедрее: настоящий диск, настоящие файлы. По одному пункту mainline Linux лучше стокового Android и нас сегодня: DMA WLAN идёт через трансляцию SMMU. Это же — доказательство, что трансляция для потока 0x640 на этом SoC с этой прошивкой работает.
4. Это не про один планшет: Android, Windows, Apple
Всё, что выше, выяснено на одном устройстве. Но ни одна деталь в этом не является особенностью планшета. Это протокол, который Qualcomm предъявляет любому хосту: без обслуживания требований прошивки радио не инициализируется. Хост не может отказаться — он может только выбирать, как обслуживать.
4.1 Android на Snapdragon — весь парк
- Сотовый модем (MPSS) есть в каждом Snapdragon с X‑модемом — это практически все Android‑телефоны на Qualcomm. И каждому нужны
rmtfs(EFS на диске хоста),tqftp/pd‑mapper,memshareчерез TrustZone, GLINK/QMI. В Android это делают проприетарные демоны Qualcomm (rmt_storage,tftp_server,pd‑mapper), которые пишут на настоящий диск. - Wi‑Fi на модемном Hexagon — поколение 2018–2020: Snapdragon 845, 855, большая часть 6xx/7xx с интегрированным WCN3980/3988/3990. Downstream‑ драйвер
icnssсqcom,smmu-s1-bypass— DMA по физическим адресам. - Wi‑Fi на отдельном ядре — с 2020 (FastConnect: QCA6390, WCN6750, WCN6855, WCN7850; Snapdragon 865 и новее). Прошивка исполняется не на модеме, а на собственном процессоре WLAN‑чипа, но протокол тот же: QMI WLFW, прошивка требует у хоста память (
REQUEST_MEM_IND— десятки мегабайт, которые хост обязан выделить и отдать под DMA), файлы прошивки и калибровки, ключи трафика — в ней. Меняется только то, делит ли она процессор с сотовым модемом. - Не Qualcomm — тот же класс. Samsung Exynos (Shannon), MediaTek, Broadcom Wi‑Fi — везде отдельный процессор с прошивкой вендора, DMA и требованиями к хосту. Qualcomm отличается лишь тем, что его больше всех и что WLAN у него годами жил внутри модема.
4.2 Windows — Snapdragon и не только
- Ноутбуки на Snapdragon (8cx, X Elite, X Plus): Wi‑Fi — Qualcomm FastConnect 6900/7800 по PCIe, сотовый — SDX по PCIe/MBIM, драйверы от Qualcomm. Протокол тот же.
- x86‑ноутбуки с Wi‑Fi‑картой Qualcomm (QCA61x4A, QCNFA765/WCN6855 — Lenovo, HP, Dell, Acer массово ставят их вместо Intel). Здесь важна деталь Windows: DMA‑ремаппинг для внутренних PCIe‑устройств — opt‑in драйвера. Kernel DMA Protection по умолчанию защищает внешние порты (Thunderbolt); для внутренней карты IOMMU включается только если драйвер объявил
DmaRemappingCompatible/RemappingSupported. Без этого, по документации Microsoft, «DMA remapping is not enforced for this device» — карта пишет по физическим адресам. Проверить можно в Диспетчере устройств, свойство «DMA Remapping Policy»:2— транслируется,0/1или отсутствует — нет.
4.3 Apple — модем, не Wi‑Fi
Wi‑Fi у Apple — Broadcom, а с 2025 собственный чип N1; Qualcomm тут не было. Но сотовый модем в iPhone — Qualcomm с 2011 года: вся линейка iPhone 17 (2025) — Snapdragon X80, американский iPhone 18 Pro Max (2026) — всё ещё X80, и только модели с собственными C1/C1X/C2 из этого выходят. Модем дискретный, по PCIe, iOS ставит перед ним IOMMU (DART) — DMA транслируется. Это самая сильная из трёх конфигураций. Но всё «незакрываемое» остаётся: собственное радио, собственный uplink, память, которую хост обязан ему выдать, и код, который Apple не читает.
4.4 Общий знаменатель
| Android (стоковый) | Windows (без opt‑in) | Apple (iPhone c Qualcomm) | Linux mainline | Наша ОС | |
|---|---|---|---|---|---|
| Прошивка вендора, хост не читает | да | да | да | да | да |
| Хост обязан выдать память под DMA | да | да | да | да | да |
| DMA транслируется IOMMU | нет (WCN39xx) | нет | да (DART) | да | после stage‑1 |
| EFS модема на настоящем диске | да | да | да | да | нет (тень) |
| Ключи трафика в прошивке | да | да | да | да | да |
| Собственный uplink у прошивки | да | да | да | да | да |
Та же таблица — как пять путей DMA от радио до RAM. Прошивка вендора (красное) есть на всех платформах; разница — в одном узле посередине: транслирует его IOMMU или нет. У стокового Android и Windows без opt‑in его нет — прошивка пишет по физическим адресам; у Apple (DART), mainline Linux (dma‑iommu) и у нас (stage‑1, план) — есть, и у нас окно сужено до одного региона.
И ещё одна деталь Qualcomm, которую легко упустить: GNSS у Qualcomm — в модеме (gpsOne/IZat, отдельный protection domain на том же Hexagon). Паразит знает координаты устройства нативно, без запроса к ОС. В 2023 году Nitrokey зафиксировал, что телефоны на Qualcomm без Google‑сервисов шлют трафик на izatcloud.net; Qualcomm ответил, что это сервис XTRA (ассистированный GPS), описанный в его политике конфиденциальности. Не компрометация — но иллюстрация того, что у подсистемы есть собственные отношения с внешним миром, о которых ОС не спрашивают.
5. А на ESP32 и у других производителей этого нет?
Естественный вопрос после §0: раз на макетке всё было просто — значит, там паразита нет? Ответ: там нет этого паразита. Закрытый код там есть тоже, и вопрос «есть ли закладка» — неправильный. Правильный: кто держит ключи, где исполняется чужой код, какая между вами граница и какие у него собственные каналы наружу.
5.1 ESP32 как самостоятельная плата
Wi‑Fi и Bluetooth на ESP32 — тоже закрытый код: библиотеки Espressif (libnet80211, libpp, libphy, libbt, libcoexist) поставляются бинарями и линкуются в ваш образ. Исходников 802.11‑стека и PHY нет ни у кого, кроме Espressif. Но три вещи устроены иначе:
- Он исполняется на вашем процессоре, в вашем адресном пространстве, с вашими привилегиями. Отдельного ядра, TrustZone, гипервизора — нет. Это значит, что если блоб злонамерен, ему не нужны трюки с DMA: он уже внутри. Но это же значит, что ему негде спрятаться: каждое обращение к памяти, каждая запись во флеш, каждый кадр в эфир проходят там, где вы можете поставить точку останова, трассу или обёртку вокруг обработчика прерывания радио.
- Ключи — ваши. Secure boot и шифрование флеша на ESP32 — на ключах, которые вы сами генерируете и прожигаете в eFuse. Прошивка не приходит подписанной вендором через чужое OTA; она собирается вами.
- Собственных каналов у него нет. Только то же самое Wi‑Fi/BT‑радио, которым вы и управляете и которое слушаете с того же ядра. Ни сотового uplink’а, ни GNSS, ни файлового сервера, ни EFS на вашем диске. Ему нечего требовать у хоста — он и есть хост.
Уязвимости по воздуху при этом есть — тот же класс «блоб парсит кадры»: CVE‑2019‑12586/12587 (падение и обнуление PMK через EAP), BrakTooth (2021, Bluetooth). Только последствие — RCE в вашем процессе, где и так весь ваш код, а не в скрытой подсистеме с собственным выходом в мир.
Отдельно — история марта 2025: Tarlogic объявила о «скрытом бэкдоре в ESP32» — 29 недокументированных vendor‑команд HCI (CVE‑2025‑27840), дающих чтение и запись RAM и флеша, подмену MAC. При разборе оказалось: все они требуют уже исполняемого кода на самом ESP32 (это локальный интерфейс между хостом и BT‑контроллером внутри одного чипа), удалённо недоступны; Espressif назвала их отладочными и обещала убрать. Не бэкдор в смысле «вход снаружи» — но хорошая иллюстрация: у любого закрытого блоба есть недокументированная поверхность, и отличие вендоров не в её наличии, а в том, с какой стороны границы она торчит.
5.2 ESP32 как модем за UART‑ом (макетка F4VE)
Это, как ни странно, самая чистая конфигурация из всех, что мы видели. Модуль со стоковой ESP‑AT — отдельный процессор с закрытым кодом, как и Qualcomm. Но граница между ним и MCU — провод и текстовый протокол. DMA в память хоста невозможен по конструкции: у модуля нет шины к ней. Файлов он не просит, диска не просит, памяти не просит. Всё, что он может сделать с хостом, — прислать строку, которую хост распарсит (и вот парсер — да, это ваша поверхность атаки).
Что он при этом видит — всё, что вы через него шлёте, открытым текстом, потому что TLS считается внутри модуля (и в ESP‑AT по умолчанию без проверки сертификата — CIPSSLCCONF=0, «доверяй проводу»). То есть конфиденциальность содержимого ограничена так же, как на планшете: границу надо проводить выше радио. Но контроля над хостом у такого модема нет. Это ровно та модель, к которой Apple пришла с дискретным модемом за IOMMU — только на 115200 бод.
5.3 Остальные: Intel, Broadcom, MediaTek, Samsung
Никто не делает Wi‑Fi без прошивки на отдельном процессоре — это физика 802.11: тайминги в микросекундах не живут на процессоре общего назначения под ОС. Разница между вендорами — по тем же четырём осям:
| Где исполняется | Кто держит ключи | Граница с хостом | Свои каналы | Что хост обязан обслужить | |
|---|---|---|---|---|---|
| ESP32, блоб в образе | ваш процессор | вы | нет (одно адресное пространство) | только это радио | ничего |
| ESP32/ESP‑AT за UART | свой процессор | Espressif | провод, текст | только это радио | ничего |
| Intel Wi‑Fi (PCIe) | свой процессор | Intel | PCIe; IOMMU — Linux по умолчанию да, Windows — opt‑in драйвера | только это радио | память под DMA |
| Broadcom (Apple/Samsung до 2025) | свой процессор | Broadcom | PCIe/SDIO; IOMMU — где есть (Apple DART) | только это радио | память под DMA |
| MediaTek (интегрированный в Dimensity) | свой процессор в SoC | MediaTek | шина SoC; IOMMU — зависит от OEM | Wi‑Fi + сотовый модем рядом | память, файлы |
| Samsung Exynos Shannon (baseband) | свой процессор | Samsung | шина SoC; IOMMU — зависит | сотовый uplink, GNSS | память, файлы, NV |
| Qualcomm, дискретный (FastConnect, X‑модем в iPhone) | свой процессор | Qualcomm | PCIe; IOMMU — Apple да, Windows opt‑in | сотовый uplink, GNSS (модем) | память под DMA, файлы |
| Qualcomm, интегрированный WCN39xx | Hexagon сотового модема | Qualcomm (+ OEM для гипервизора) | шина SoC; stage‑1 bypass в стоке | Wi‑Fi + сотовый + GNSS в одном | память, файлы, EFS на диске, карта доменов |
Итог по столбцам: у ESP32 чужой код есть, но периметр ваш — ключи, флеш, адресное пространство, единственный канал наружу. У Qualcomm периметр проводит вендор вместе с OEM, а внутри периметра — процессор с DMA, хранилищем на вашем диске и собственным выходом в сотовую сеть. Слово «закладка» тут не помогает; правильное слово — доверенная база, которую вы не выбирали и не можете проверить. На макетке она маленькая и в вашей власти; на телефоне — большая и в чужой.
6. Что это даёт спецслужбам
Разложим по тому, что нужно иметь атакующему. Три градации: что документировано, что продемонстрировано исследователями, что структурно возможно.
6.1 Ничего, кроме сети (оператор, государство)
Это не про паразита как таковой, но он — конечная точка этой сети: местоположение по соте, законный перехват (CALEA/СОРМ), SS7/Diameter, IMSI‑catcher’ы, silent SMS. Всё документировано десятилетиями. Модем делает ровно то, для чего создан: отвечает сети. Wi‑Fi здесь даёт меньше: probe‑запросы с MAC (рандомизация MAC в ОС мешает — но настоящий MAC знает прошивка).
6.2 Уязвимость в прошивке, по воздуху
Радиус — сотни метров для Wi‑Fi, поддельная базовая станция или просто сеть для сотового модема. Прецеденты:
- Project Zero, 2023 — 18 zero‑day в Samsung Exynos baseband, четыре из них — RCE «из интернета в модем», зная только номер телефона (Pixel 6/7, Galaxy S22). Не Qualcomm, но тот же класс и та же позиция в системе.
- Broadpwn и «Over The Air», 2017 — RCE в прошивке Broadcom Wi‑Fi одним кадром, затем — в хост через DMA на устройствах без IOMMU (Nexus 6P, Galaxy S7). Точная схема из §2.2.
- Check Point, 2021 (CVE‑2020‑11292) — уязвимость в QMI модема Qualcomm: из Android в модем, чтение SMS, звонков, разблокировка SIM. Направление обратное (хост → модем), но показывает, что QMI‑парсеры модема — не крепость.
- Qualcomm, октябрь 2023 (CVE‑2023‑33063/33106/33107) и CVE‑2024‑43047 — уязвимости в Hexagon DSP, о которых Qualcomm сообщил как об «ограниченно, целенаправленно эксплуатируемых»; вторая, по отчёту Amnesty International (декабрь 2024), использовалась сербской полицией через Cellebrite. Это не модем, а соседний DSP, и с физическим доступом — но это Hexagon, эксплуатируемый государством, в поле.
Что получает тот, кто сидит в прошивке Wi‑Fi или модема:
| Возможность | Статус | Кого касается |
|---|---|---|
| Весь Wi‑Fi‑трафик на канальном уровне: метаданные, DNS, SNI, всё нешифрованное | структурно, всегда | всех |
| Местоположение: BSSID соседей + GNSS в модеме | структурно, всегда | всех на Qualcomm |
| Эксфильтрация по сотовой сети мимо VPN, файрвола и «авиарежима» (это запрос к модему, не рубильник) | структурно, всегда | всех с интегрированным модемом |
| Полный контроль хоста через DMA: память, ключи, сообщения, микрофон и камера через ОС | продемонстрировано (2017) там, где нет IOMMU | стоковый Android с WCN39xx; Windows без opt‑in драйвера |
Персистентность: запись в EFS (modemst1/2) на диске хоста — разделы переживают factory reset и переустановку ОС | структурно (код прошивки подписан и грузится заново, но данные/NV — её, и парсит их она же) | Android, Linux, Windows, Apple — везде, где EFS на диске |
| Подмена скан‑результатов: увести устройство в свой AP | структурно | всех |
6.3 Сотрудничество или принуждение вендора / OEM
Прошивка подписана ключом Qualcomm, проверяется TrustZone и приходит с OTA производителя устройства. Тот, кто может подписать образ и доставить его через OTA — Qualcomm плюс OEM, или тот, кто ими распоряжается, — получает имплант, который легитимен для всех проверок устройства, невидим для ОС, переживает любую переустановку и имеет всё из таблицы выше сразу, без единой уязвимости. Технически препятствий нет; есть ли юридические и институциональные — вопрос юрисдикции и доверия, не инженерии. Каталог ANT АНБ 2008 года (утечка 2013) содержал baseband‑импланты для телефонов того времени — то есть направление это не гипотетическое.
Сюда же — гипервизор EL2 и XPU: на стоковом Android это единственный забор перед DMA паразита, и оба — код Samsung и Qualcomm.
6.4 Физический доступ
Режим EDL (Emergency Download) Qualcomm с подписанным OEM программатором Firehose даёт чтение и запись всей флеш‑памяти, включая EFS — штатный путь криминалистики (Cellebrite, GrayKey и аналоги). Это отдельная тема; здесь важно одно: разделы модема при этом — самое стойкое место для закладки, потому что ни одна переустановка ОС их не трогает.
6.5 Чего это не даёт
Честности ради:
- Содержимое TLS — если сертификат проверяется, паразит видит только метаданные. Поэтому TLS без проверки — не мелочь.
- Содержимое e2e‑сообщений — пока хост не скомпрометирован через DMA. IOMMU перед паразитом превращает «полный контроль» в «видит трафик».
- Микрофон и камера напрямую — у WLAN/модема их нет; путь только через хост.
Отсюда и приоритеты: IOMMU (закрывает пивот в хост), TLS с проверкой (закрывает содержимое), тень вместо диска (закрывает персистентность). Эфир, ключи и uplink — остаются, и это надо знать, а не надеяться.
7. Принцип нейтрализации: прозрачная изоляция
Отключить каналы нельзя: без любого из них прошивка не стартует или роняет SoC. Значит, стратегия — отвечать на всё, что модем спрашивает, но не отдавать ничего лишнего. Синтаксически корректный ответ, семантически пустой. Паразит должен на каждом шаге видеть SUCCESS — и получать тень.
7.1 Диск — тень вместо диска
rmtfs при OPEN читает раздел в RAM один раз. Все RW_IOVEC идут в копию. Диск не меняется никогда, перезагрузка забывает. Модем видит, что его записи «легли»; на деле не легло ничего. Каждый перенос проверяется дважды — по сектору тени и по смещению в общем регионе.
Деталь, которую пришлось узнать живьём: раздел fsg (золотая копия EFS) на этом планшете отсутствует. Ответ «нет такого файла» ронял модем через 23 мс. Ответ «вот он, пустой» (нули = стёртая копия) — модем доволен.
7.2 Файлы — ограниченный scratch
/readonly/... → только путь поиска прошивок, обход .. режется. /readwrite/... → RAM, 64 КиБ, 16 файлов, старые вытесняются. Запись куда‑то ещё — access violation. server_check.txt пишется и читается из scratch: модем «проверил сервер» и загрузил WLAN.
7.3 Память — только именованные регионы
memshare переводит владение только для регионов, которые платформа явно объявила, с конкретными владельцами и правами. Произвольный адрес модем себе назначить не может.
7.4 Ввод — валидация всего недоверенного
Всё, что пришло от модема — база FIFO, смещение элемента, длина, адрес в QMI — проверяется против окна до разыменования. Цепочка SMEM обходится с лимитом шагов. Чужие разделы SMEM (TZ–модем) не читаются вообще: чтение за MPU — зависание ядра до watchdog.
Всё это написано на safe Rust. Баг в парсере данных модема — паника и перезагрузка, не запись мимо буфера.
7.5 Кэш — ничего общего
Вся память, которую пишет модем или secure world, отображена некэшируемой, окнами по 2 МиБ на границе блока. Урок, стоивший одного сброса: лент‑RAM, начавшаяся не на границе блока, получила первый МиБ кэшируемым — модем прочитал пустые заголовки EFS из буфера, который мы писали через кэш, восстановил золотую копию поверх и упал на рестарте.
8. Главное: запереть DMA
Всё выше — обезвреживание командной поверхности. Но пока поток 0x640 идёт без трансляции, паразит физически может писать куда угодно, и всё остальное — декорация.
Лечение — включить stage‑1 для 0x640: контекст‑банк SMMU с трансляцией, таблицы страниц, отображающие только 4‑мегабайтное окно, где живут кольца и буферы (identity внутри окна: IOVA = PA, снаружи — ничего). Тогда любой DMA прошивки за пределы окна — fault контекст‑банка, не запись в память. Кольца программируются теми же адресами; для честной прошивки ничего не меняется.
Нюанс SoC: гипервизор Samsung ветирует S2CR типа bypass (запись возвращается как fault) — поэтому и текущий bypass у нас реализован как банк типа translate с выключенной трансляцией. Включить трансляцию в том же банке — шаг, который нужно пройти живьём, потому что любое отклонение здесь — тихий сброс. Mainline Linux на HDK SM8150 с той же прошивкой это делает, так что ответ известен: работает.
9. Что остаётся и после этого
Честно — потому что модель угроз, в которой «всё закрыто», врёт.
Не закрывается нашей стороной, потому что это функция паразита, а не побочный канал:
- Весь Wi‑Fi‑трафик открытым текстом. Шифрует он. Ключи у него. Граница конфиденциальности — TLS и end‑to‑end, не WPA. (И поэтому TLS без проверки сертификата — а на маленьких платах это соблазн — здесь не «пока сойдёт», а дверь: паразит становится MITM для токенов, API и, если через сеть когда‑то пойдут обновления, для кода.)
- Эфир. Список сетей, RSSI соседей (= геолокация), возможность увести в чужой AP — всё его.
- Сотовый uplink того же Hexagon. Канал эксфильтрации, который не проходит ни через один наш слой. Это, а не DMA, — главный канал утечки для скомпрометированного модема.
Закрывается частично:
- Регионы
memshare(MSA, буферrmtfs) — модем пишет туда своим путём, минуяapps_smmu; stage‑1 их не запирает. Лечение — минимальные гранты и размер; забор — XPU от TZ. - Баги парсеров — safe Rust превращает их в DoS; фаззинг на детерминированных фейках (у нас каждый сервер имеет фейк‑модем для тестов на хосте) добивает остаток.
Уже закрыто:
- Персистентность через хост. Скомпрометированной по воздуху прошивке некуда через нас записаться: тень EFS и scratch — в RAM, диск не трогается. Каждая перезагрузка — чистый лист. На Linux/Android это не так:
rmtfsпишет на диск.
10. Что мы не можем и не притворяемся
- Гипервизор EL2 и XPU TrustZone — Samsung и Qualcomm. Пока stage‑1 не включён, они — единственный забор DMA, и полагаться на них как на свою границу нельзя. После — второй эшелон.
- Сама прошивка подписана Qualcomm. Мы не читаем её и не меняем. Наша граница — вокруг, не внутри.
- Лог TrustZone зашифрован и чистится при сбросе. Свидетеля компрометации со стороны secure world у нас нет.
11. Как посмотреть на своё устройство
Почти всё из статьи проверяется без разборки.
Linux (ноутбук или телефон с mainline). Транслируется ли DMA Wi‑Fi‑карты — тип её IOMMU‑группы:
for d in /sys/class/net/*/device; do
echo "$(basename $(dirname $d)): $(cat $d/iommu_group/type 2>/dev/null || echo 'no IOMMU')"
doneDMA или DMA-FQ — транслируется; identity — физические адреса; нет файла — IOMMU перед устройством нет. Кто обслуживает модем — pgrep -a 'rmtfs|tqftpserv|pd-mapper'; на что он пишет — rmtfs покажет в аргументах устройство или разделы.
Android (нужен root или хотя бы adb shell). Разделы модема на диске: ls -l /dev/block/by-name/ | grep -E 'modemst|fsg|fsc' — вот EFS, которую не трогает factory reset. Режим SMMU для Wi‑Fi — в живом дереве устройств: find /proc/device-tree -name 'qcom,smmu-s1-bypass' | grep -i -E 'icnss|wifi|wlan' — нашлось, значит bypass. Где исполняется Wi‑Fi — есть ли узел qcom,icnss (интегрированный, на модеме) или qcom,cnss/PCIe (отдельный чип).
Windows. Диспетчер устройств → Wi‑Fi‑адаптер → Сведения → свойство «DMA Remapping Policy»: 2 — DMA транслируется, 0/1 или свойства нет — физические адреса. msinfo32 → «Kernel DMA Protection» — включена ли защита вообще (она про внешние порты; внутреннюю карту она не спасает без 2 выше).
iPhone. Проверять нечего — DART перед модемом всегда. Какой модем — надёжнее всего по номеру модели и опубликованным разборкам (iFixit, TechInsights): вся линейка 17 — Qualcomm X80; Air, 16e и 18 Pro вне США — Apple C1X/C1/C2. Строка «Прошивка модема» в «Об этом устройстве» показывает версию, но не вендора.
Любой телефон. «Авиарежим» — это запрос ОС к модему, а не разрыв питания. Единственная проверка, что радио не излучает, — измерение снаружи.
12. Выводы
- На современном SoC «Wi‑Fi‑чип» — это половина модема с DMA, IPC, файловым сервером и собственным радио. Драйвер Wi‑Fi — это не «управление периферией», а обслуживание привилегированного арендатора.
- Это не особенность одного планшета, а протокол Qualcomm: его обслуживает каждый Android на Snapdragon, каждый ноутбук с Wi‑Fi‑картой или модемом Qualcomm под Windows, каждый iPhone с модемом Qualcomm — и отказаться нельзя, иначе радио не стартует. Разница между платформами — только в том, транслируется ли DMA (Apple, mainline Linux — да; стоковый Android с WCN39xx и Windows без opt‑in драйвера — нет) и получает ли модем настоящий диск (везде, кроме нас).
- Linux и Android этого арендатора обслуживают целиком и честно: настоящий диск, настоящие файлы, а в стоковом Android — ещё и DMA по физическим адресам. Mainline Linux хотя бы транслирует DMA.
- На ESP32 и у других вендоров закрытый код тоже есть — но вопрос не «есть ли закладка», а чей периметр. На макетке чужой блоб живёт в вашем адресном пространстве, под вашими ключами, с единственным каналом наружу, который вы же и слушаете; за UART‑ом — и вовсе за проводом. На Qualcomm периметр проводят вендор и OEM, а внутри — процессор с DMA, вашим диском и сотовым uplink’ом. Тридцатикратная разница в объёме драйвера из §0 — это цена не сложности чипа, а обслуживания жильца.
- Для того, у кого есть уязвимость в прошивке, ключ подписи или власть над вендором, это даёт: весь трафик на канальном уровне, координаты (GNSS живёт в модеме), uplink мимо VPN и «авиарежима», персистентность в разделах модема, переживающих factory reset, — и там, где DMA не транслируется, полный контроль хоста. Прецеденты по каждому пункту, кроме последнего на Qualcomm, опубликованы.
- Правильная стратегия — не отключать (нельзя), а изолировать прозрачно: правильный по форме ответ, пустой по сути. Тень вместо диска, scratch вместо файлов, именованные регионы вместо произвольных, валидация всего, что он написал, — и IOMMU, запирающий DMA в окно.
- И после всего этого остаётся то, что закрыть нельзя: трафик, ключи, эфир, сотовая сеть. Это значит, что конфиденциальность нужно строить выше — TLS с проверкой, e2e — а не надеяться на радиоуровень.
- Модель угроз, в которой всё закрыто, — не модель угроз. Честный список «не можем» — часть результата.
Это центральная статья серии; карта всех жильцов устройства и порядок чтения — во вводной. Частные истории: сброс без свидетелей, мегабайт, который убил модем, 23 миллисекунды, чтобы солгать, гипервизор, который сказал «нет», граница WPA, доверяй проводу?.
Технические детали — карта памяти, все сбросы SoC с причинами, регистры SMMU, форматы сообщений — в docs/wifi-sm8150.md и docs/wifi-threat-model.md репозитория. Код: crates/qcom (SMMU, SMEM, GLINK), crates/tools (rmtfs, tqftp, memshare, wifi), crates/ath10k (copy engines, HTT, WMI), crates/wpa.
Тот же чип и тот же протокол — в каждом Snapdragon-Android, во многих Windows-ноутбуках и в iPhone с модемом Qualcomm. Разница только в том, обслуживает ли хост жильца щедро (настоящий диск, DMA без трансляции) или скупо. В § 11 — как посмотреть на своё устройство; мы делаем это на заказ и строим дома на ОС, где жильцу дают ровно столько, сколько нужно.Продукты из статьи
Устройство, где хозяин — вы
Мы строим умные дома на 0xd-os — и проводим аудит чужих устройств и прошивок с письменным scope. Напишите, что у вас.
Умный дом под ключ на собственной ОС: 0xd-os и 0xd-uiМы строим умные дома под ключ на компонентах собственной разработки. В основе — ОС 0xd-os, которая одинаково работает на флагманском планшете и в устройстве с 512 КБ памяти.
Зачем агенту безопасности нужна песочницаАгент, который «просто запускает инструменты» на разборе, — второй атакующий, пока у каждого вызова нет гранта. AGI Core изолирует инструменты; Forge держит список скиллов в UIDE.