Как читать авторский курс и нормативные материалы
Это учебные материалы, а не заключение о соответствии конкретного продукта. Организационные модели курса отделяйте от терминов стандарта: ППК в опубликованном проекте — машиночитаемый перечень, а живой реестр его версий является практикой сопровождения. Термин OSA в разных материалах имеет разный охват. Статус и обязательность нормативного документа проверяются отдельно; проект КАПО опубликован как проект первой редакции.
ELF и разделы dynamic
Почему это важно для SCA/OSA
Секция .dynamic ELF-файла — это машиночитаемая запись о том, что бинарь требует от загрузчика. Она хранит набор тегов DT_*: имена нужных библиотек (DT_NEEDED), собственное имя модуля (DT_SONAME), пути поиска (DT_RPATH/DT_RUNPATH) и прочее. Для SCA это самый прямой и дешёвый источник состава: чтобы перечислить динамические зависимости, достаточно прочитать структуру .dynamic, не запуская файл и не имея журнала сборки.
Понимать .dynamic именно как структуру данных важно, потому что от тегов зависит интерпретация. DT_NEEDED даёт имя, но не путь; DT_RPATH/DT_RUNPATH меняют, какой файл реально подставится под это имя. Читать список зависимостей в отрыве от тегов поиска — значит рисковать тем, что инвентаризация назовёт системный пакет, а в продукт уедет vendored-копия.
Как это проявляется
Полный дамп секции читается одной командой; каждая строка — отдельный тег DT_*:
$ readelf -d ./app
Dynamic section at offset 0x2da8 contains 27 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libssl.so.3]
0x0000000000000001 (NEEDED) Shared library: [libcrypto.so.3]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libapp.so.1]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/../lib]
0x000000000000000c (INIT) 0x3000
Здесь читается всё нужное для инвентаризации: какие библиотеки требуются (NEEDED), как называет себя сам модуль (SONAME — по нему его найдут другие), и — критично — RUNPATH: $ORIGIN/../lib, то есть загрузчик будет искать .so рядом с бинарём раньше системных путей.
Ключевые теги
.dynamicдля SCA | Тег | Что означает | Зачем SCA | |-----|--------------|-----------| |DT_NEEDED| имя требуемой.so(soname) | список динамических зависимостей | |DT_SONAME| как называется сам модуль | идентичность библиотеки-артефакта | |DT_RPATH| устаревший путь поиска (доLD_LIBRARY_PATH) | риск подмены/vendored | |DT_RUNPATH| современный путь поиска (послеLD_LIBRARY_PATH) | то же, приоритетнее RPATH |
Слепая зона или приём
Слепая зона .dynamic — расхождение между именем и файлом. DT_NEEDED называет libssl.so.3, но DT_RUNPATH = $ORIGIN/../lib заставит загрузчик взять libssl.so.3 из каталога поставки, а не системный libssl3. Инвентаризация по одному DT_NEEDED запишет системную версию, тогда как в рантайме поедет vendored-копия с другой. Приём — всегда читать RPATH/RUNPATH вместе со списком NEEDED и сверять с фактическим путём резолвинга (ldd, см. ldd readelf objdump).
Вторая граница: .dynamic по определению не содержит статически вшитого кода — там нет ни DT_NEEDED, ни иного следа для .a-архивов. Это зона статической линковки, а не .dynamic.
Что делать на проекте
- Снимать состав из
.dynamicчерезreadelf -d— статически, не исполняя файл; это базовый источник динамических зависимостей. - Читать не только
DT_NEEDED, но иDT_RPATH/DT_RUNPATH: их наличие — сигнал, что фактический файл может отличаться от системного. - При непустом
RPATH/RUNPATHсверять имя изNEEDEDс реальным путём резолвинга и помечать vendored-копии отдельно. - Использовать
DT_SONAMEкак идентичность модуля при маппинге и дедупликации компонентов. - Отсутствие
DT_NEEDEDдля ожидаемой библиотеки трактовать не как «зависимости нет», а как «возможно, вшита статически» — и уходить в build-scan. - Для разбора
.dynamicпачкой бинарей — программный парсер вместо ручногоreadelf(см. LIEF как программный анализ ELF).
Связь
- Модуль: М09. C/C++ legacy
- Практики: П22. ELF dynamic dependencies
- Нормативка: CISA Minimum Elements for SBOM · BSI TR-03183-2 v2.1.0 · ГОСТ Р 56939-2024
- Смежные заметки 06: динамическая линковка · статическая линковка · ldd readelf objdump · LIEF как программный анализ ELF · unresolved libraries