Разбираем вопрос, который звучит интригующе: будто ошибки компиляции под arm64 приводили к попаданию неверной логики в бинарник curl и это оборачивалось уязвимостями. Проверим, что об этом говорят сами инструкции по сборке curl и таблица CVE проекта, и где заканчиваются факты.
Как устроена сборка curl из исходников
Сборка описана как последовательность шагов: сначала настройка через ./configure с нужными опциями, затем make, опционально make test и установка через make install. Если configure завершается успешно, дальше выполняются make и make install как обычно.
./configure --with-openssl [--with-gnutls --with-wolfssl]
make
make test (optional)
make installШаг make test — это запуск набора проверок собранного кода; он помечен как опциональный, потому что для обычной установки достаточно успешной сборки, а тестирование выполняют, когда нужно убедиться в работоспособности сборки.
configureскрипт настройки сборки, который проверяет окружение и генерирует правила для make требует явно выбрать TLS-бэкендбиблиотека, реализующая шифрование транспортного уровня для curl, если только TLS не отключён полностью через --without-ssl. Доступные опции выбора: --with-gnutls, --with-mbedtls, --with-openssl (работает и для форков OpenSSL), --with-rustls, --with-wolfssl и --without-ssl. Несколько бэкендов можно указать в одной команде: тогда в собранном curl доступны сразу несколько реализаций TLS, и при работе можно выбрать нужную из них. Принудительная сборка без SSL — ./configure --without-ssl.
Важная деталь про статическую сборкусборка, при которой код библиотек включается в бинарник, а не подгружается во время работы: чтобы получить статическую библиотеку, отключают создание разделяемой через ./configure --disable-shared. При линковке с разделяемыми библиотеками цепочку зависимостей обрабатывает загрузчик библиотек автоматически, а при статической линковке все библиотеки-зависимости нужно предоставить уже в командной строке линковки. Скрипты сборки в основном предполагают, что пользователь сам передаёт все необходимые дополнительные библиотеки через LIBS или LDFLAGS.
Кросс-компиляция под arm64
Общий шаблон кросс-компиляции — ./configure --host=ARCH-OS, где указывается целевая архитектура и ОС. В разделе Cross compile нужно распаковать пакет curl, перейти в новый каталог, установить переменные окружения для кросс-компиляционного тулчейнанабор инструментов для сборки под целевую платформу и вызвать configure с нужными опциями, обязательно указав --host и --build.
Для arm64 (aarch64) приведён конкретный пример:
./configure --host aarch64-linux-android --with-pic --disable-sharedЗдесь --host aarch64-linux-android задаёт целевую платформу, --with-pic включает позиционно-независимый кодкод, который может быть загружен по любому адресу памяти без изменения, а --disable-shared отключает сборку разделяемых библиотек.
Для сборки под Android сначала нужно установить Android NDKнабор инструментов для сборки нативных приложений под Android. При сборке через configure задаются переменные окружения, включая CC и CXX с префиксом aarch64-linux-android29-clang, а также AR, AS, LD, RANLIB и STRIP из toolchainнабора инструментов для сборки под целевую платформу NDK. При сборке на Linux или для других API levelверсий программного интерфейса операционной системы Android и архитектур эти переменные нужно скорректировать.
Альтернативный путь — через cmake, где для aarch64 и API level 29 задаются -DANDROID_ABI=arm64-v8a, -DANDROID_PLATFORM=android-29 и -DCMAKE_TOOLCHAIN_FILE, указывающий на android.toolchain.cmake в NDK, при этом SSL и libpsl отключаются.
Переменные окружения и флаги кросс-компиляции
Переменные CFLAGS и LDFLAGS применяются для передачи опций компилятору и компоновщику, например CFLAGS='-Os -ffunction-sections' и LDFLAGS='-Wl,--gc-sections'. Переменные CPPFLAGS и LDFLAGS используются для указания путей к заголовкам и библиотекам OpenSSL при использовании --with-openssl.
В примере кросс-компиляции под i586-pc-msdosdjgpp задаются переменные CC, AR, RANLIB, WATT_ROOT и флаги --host, --with-openssl, --with-zlib, --without-libpsl, --disable-shared. Для arm64 с OpenSSL в примере указывается --with-openssl="$TOOLCHAIN/sysroot/usr", а при статической линковке в LIBS перечисляются библиотеки, которые нужно подключить вручную: -lssl и -lcrypto — сам SSL/TLS-слой, а -lc++ — стандартная библиотека C++, от которой он зависит.
Предупреждения о несовпадении версий тулчейна
В инструкции для DJGPP есть прямое требование: Watt-32 и OpenSSL должны компилироваться той же версией DJGPP, иначе «things go wrong because things like FS-extensions and errno values have been changed between releases». Это единственное место, где прямо сформулирована связь между несовпадением версий тулчейна и зависимостей и некорректным поведением.
Для arm64 задаётся конкретный тулчейн через переменные окружения, указывающие на конкретные компиляторы и утилиты. Аналогичное несовпадение на arm64 могло бы проявиться, если бы компиляторы и утилиты сборки относились к одному тулчейну, а библиотеки SSL/TLS или их транзитивные зависимостибиблиотеки, которые нужны не самой программе напрямую, а тем библиотекам, с которыми она линкуется были собраны другим тулчейном.
Компромиссы: переносимость, безопасность, размер
Требование явно выбирать TLS-бэкенд — это компромисс: явный выбор повышает безопасность (не остаёшься без TLS по умолчанию), но снижает переносимость, так как нужно заранее знать доступный бэкенд. Переносимость обеспечивается поддержкой множества ОС (от AIX и AmigaOS до Zephyr) и 28 архитектур CPU, среди которых Alpha, ARC, ARM, AVR32, C-SKY, CompactRISC, Elbrus, ETRAX, HP-PA, Itanium, LoongArch, m68k, m88k, MicroBlaze, MIPS, Nios, OpenRISC, POWER, PowerPC, RISC-V, s390, SH4, SPARC, Tilera, VAX, x86, Xtensa, z/arch. К семейству arm64/aarch64 относятся архитектура ARM как общее название и явно указанные в примерах arm64-v8a и aarch64-linux-android.
Для уменьшения размера бинарника в embedded-приложениях предлагаются опции configure и флаги компилятора. При конфигурировании задаётся CFLAGS с флагами оптимизации; для gcc это как минимум -Os, а также -ffunction-sections и -Wl,--gc-sections среди прочих. Отмечено, что новые компиляторы часто дают меньший код за счёт улучшенной оптимизации. Рекомендуется задавать как можно больше флагов --disable- и --without- для отключения ненужных функций, включая криптографическую аутентификацию (--disable-aws, --disable-basic-auth, --disable-bearer-auth, --disable-digest-auth, --disable-kerberos-auth, --disable-negotiate-auth, --disable-ntlm) и SSL/TLS (--without-ssl).
Уязвимости, связанные с парсерами
В таблице CVE перечислены три уязвимости, относящиеся к разбору входных данных, и во всех случаях речь идёт о чтении за границами буфера:
- CVE-2024-7264 «ASN.1 date parser overread» — затронуты версии с 7.32.0 по 8.9.0, опубликована 2024-07-31, вознаграждение 540 USD.
- CVE-2022-35260 «.netrc parser out-of-bounds access» — с 7.84.0 по 7.85.0, опубликована 2022-10-26, вознаграждение 480 USD.
- CVE-2017-1000101 «URL globbing out of bounds read» — с 7.34.0 по 7.54.1, опубликована 2017-08-09.
Как организована таблица CVE
Записи в таблице организованы как строки с номером, уровень серьёзностиоценка опасности уязвимости: L — низкая, M — средняя, H — высокая (S), метки компонентовуказание, какая часть проекта затронута: библиотека lib или утилита командной строки tool (W), признак Cотметка о том, что уязвимость затрагивает и утилиту, и библиотеку (C), названием уязвимости, датой публикации (Published), первой уязвимой версией (First), последней уязвимой версией (Last) и суммой вознаграждения (Awarded). Уровень серьёзности обозначается буквами L, M, H в колонке S, а фильтры над таблицей позволяют показывать «All | Medium+ | High+ | Critical».
Диапазон версий задаётся парой First/Last: например, для CVE-2026-82209 указаны First 7.46.0 и Last 8.21.0, то есть уязвимы версии от 7.46.0 до 8.21.0 включительно. Дата публикации — это дата раскрытия, например 2026-09-02 для нескольких записей сразу, что показывает пакетное раскрытие. Вознаграждение указывается в долларах США и зависит от серьёзности: за L обычно 505 USD, за M — 2540 USD, за H — 4660 USD, хотя встречаются и другие суммы (480, 540, 800, 1000, 1200, 1500, 2000, 2400 USD).
Классификация последствий: CVE-2015-3236 «lingering HTTP credentials in connection reuse» — severityОценка опасности уязвимости в таблице CVE: L — низкая, M — средняя, H — высокая. H; CVE-2026-7168 «cross-proxy Digest auth state leak» — severity M.
Время жизни ошибки измеряется диапазоном версий, в которых она существовала: CVE-2024-7264 — от 7.32.0 до 8.9.0, CVE-2022-35260 — от 7.84.0 до 7.85.0, CVE-2020-8286 — от 7.41.0 до 7.73.0. Диапазон может охватывать как несколько минорных выпусков, так и более длительный период.
Что из этого следует на практике
- TLS-бэкенд нужно выбирать явно. Configure требует этого, если TLS не отключён через
--without-ssl. Это осознанный компромисс между безопасностью и переносимостью. - Статическая сборка перекладывает зависимости на пользователя. При
--disable-sharedвсе библиотеки-зависимости нужно указывать в командной строке линковки черезLIBSилиLDFLAGS; для arm64 с OpenSSL в примере этоLIBS='-lssl -lcrypto -lc++'. - Уязвимости парсеров существуют независимо от архитектуры. CVE-2024-7264, CVE-2022-35260 и CVE-2017-1000101 — это чтение за границами буфера при разборе ASN.1-дат, файла
.netrcи шаблонов URL. Диапазоны уязвимых версий измеряются годами выпусков. - Процесс раскрытия координирован и вознаграждается. Публикации группируются по датам, суммы вознаграждений градируются по уровню серьёзности, а диапазон версий фиксируется парой First/Last.