Provided by: manpages-ru_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       rtld-audit - программный интерфейс слежения за динамическим компоновщиком

ОБЗОР

       #define _GNU_SOURCE             /* смотрите feature_test_macros(7) */
       #include <link.h>

ОПИСАНИЕ

       Динамический  компоновщик  GNU  (компоновщик  времени  выполнения)  предоставляет  API  слежения, который
       позволяет приложению получать уведомления о различных событиях динамической компоновки. Данный API  очень
       похож  на  интерфейс  слежения,  предоставляемый компоновщиком времени выполнения из Solaris. Необходимые
       константы и прототипы определены в <link.h>.

       Чтобы использовать этот интерфейс, программист создаёт общую  библиотеку  функций  со  стандартизованными
       именами.  Не  все функции нужно реализовывать: в большинстве случаев, если программист не заинтересован в
       конкретном классе отслеживаемых событий, то нет нужды в создании соответствующей отслеживающей функции.

       Для применения интерфейса слежения переменная окружения LD_AUDIT должна содержать разделённый двоеточиями
       список общих библиотек, каждая из которых может реализовывать (частично) API  слежения.  Когда  возникает
       отслеживаемое  событие,  из каждой библиотеки вызывается соответствующая функция в том порядке, в котором
       эти библиотеки были перечислены.

   la_version()

       unsigned int la_version(unsigned int version);

       This is the only function that must be defined by an auditing library: it performs the initial  handshake
       between  the  dynamic  linker  and the auditing library.  When invoking this function, the dynamic linker
       passes, in version, the highest version of the auditing interface that the linker supports.

       A typical implementation of this function simply returns the constant LAV_CURRENT,  which  indicates  the
       version of <link.h> that was used to build the audit module.  If the dynamic linker does not support this
       version  of  the  audit interface, it will refuse to activate this audit module.  If the function returns
       zero, the dynamic linker also does not activate this audit module.

       In order to enable backwards compatibility with older dynamic linkers, an audit module  can  examine  the
       version  argument  and  return  an  earlier  version than LAV_CURRENT, assuming the module can adjust its
       implementation to match the requirements of the previous version of the audit interface.  The  la_version
       function  should not return the value of version without further checks because it could correspond to an
       interface that does not match the <link.h> definitions used to build the audit module.

   la_objsearch()

       char *la_objsearch(const char *name, uintptr_t *cookie,
                          unsigned int flag);

       Динамический компоновщик вызывает эту функцию для  информирования  отслеживающей  библиотеки  при  поиске
       общего  объекта.  Аргумент  name  содержит  имя  файла  или  путь,  который будет разыскиваться. В cookie
       указывается общий объект, который  начал  поиск.  Аргумент  flag  устанавливается  в  одно  из  следующих
       значений:

       LA_SER_ORIG      Это  оригинальное  имя,  которое  будет  разыскиваться.  Как правило, это имя хранится в
                        записи ELF DT_NEEDED или был передан в аргументе filename при вызове dlopen(3).

       LA_SER_LIBPATH   Значение name было создано с использованием каталога из LD_LIBRARY_PATH.

       LA_SER_RUNPATH   Значение name было  создано  с  использованием  каталога  из  списка  ELF  DT_RPATH  или
                        DT_RUNPATH.

       LA_SER_CONFIG    Значение name было найдено в кэше ldconfig(8) (/etc/ld.so.cache).

       LA_SER_DEFAULT   Значение name было найдено при поиске в одном из каталогов по умолчанию.

       LA_SER_SECURE    Значение name относится к объекту безопасности (не используется в Linux).

       Функция la_objsearch() возвращает путь, который динамический компоновщик должен использовать в дальнейшей
       работе.  Если  возвращается  NULL,  то  путь  игнорируется в дальнейшей работе. Если данная отслеживающая
       библиотека создана для простого слежения за путями поиска, то должно возвращаться name.

   la_activity()

       void la_activity( uintptr_t *cookie, unsigned int flag);

       Динамический компоновщик вызывает  эту  функцию  для  информирования  библиотеки  слежения  о  выполнении
       действия  с  картой ссылок (link-map). В cookie задаётся объект, находящийся в начале карты ссылок. Когда
       динамический компоновщик вызывает  эту  функцию,  аргумент  flag  устанавливается  в  одно  из  следующих
       значений:

       LA_ACT_ADD         В карту ссылок добавляется новый объект.

       LA_ACT_DELETE      Из карты ссылок удаляется объект.

       LA_ACT_CONSISTENT  Действие с картой ссылок завершено: карта снова корректна (consistent).

   la_objopen()

       unsigned int la_objopen(struct link_map *map, Lmid_t lmid,
                               uintptr_t *cookie);

       Динамический  компоновщик  вызывает эту функцию при загрузке нового общего объекта. Аргумент map является
       указателем на структуру карты ссылок (link-map), которая описывает объект. Поле  lmid  устанавливается  в
       одно из следующих значений:

       LM_ID_BASE       Карта ссылок является частью начального пространства имён (namespace).

       LM_ID_NEWLM      Карта ссылок является частью нового пространства имён, запрошенного через dlmopen(3).

       Аргумент  cookie  —  указатель на идентификатор этого объекта. Идентификатор используется при последующих
       вызовах  функций  отслеживающей  библиотеки  для  идентификации  этого  объекта.   Данный   идентификатор
       инициализируется  указателем  на  карту  ссылок  объекта,  но  отслеживающая  библиотека  может  изменить
       идентификатор на другое значение, которое ей удобней использовать для обращения к объекту.

       Функция la_objopen() возвращает битовую маску, созданное с помощью сложения (OR) нуля или более следующих
       констант, которые позволяют отслеживающей библиотеке выбирать наблюдаемые объекты через la_symbind*():

       LA_FLG_BINDTO    Следить за символьными привязками этого объекта.

       LA_FLG_BINDFROM  Следить за символьными привязками из этого объекта.

       Возвращаемое значение 0 из la_objopen() указывает на то, что не  нужно  отслеживать  символьные  привязки
       этого объекта.

   la_objclose()

       unsigned int la_objclose(uintptr_t *cookie);

       Динамический  компоновщик вызывает эту функцию после выполнения конечного кода (finalization code), но до
       выгрузки объекта. В cookie задаётся идентификатор, полученный ранее из вызова la_objopen().

       В текущей реализации значение, возвращаемое la_objclose(), игнорируется.

   la_preinit()

       void la_preinit(uintptr_t *cookie);

       Динамический компоновщик вызывает эту  функцию  после  загрузки  всех  общих  объектов,  но  до  передачи
       управления  приложению (то есть, до вызова main()). Заметим, что main() позднее всё ещё может динамически
       загрузить объекты с помощью dlopen(3).

   la_symbind*()

       uintptr_t la_symbind32(Elf32_Sym *sym, unsigned int ndx,
                              uintptr_t *refcook, uintptr_t *defcook,
                              unsigned int *flags, const char *symname);
       uintptr_t la_symbind64(Elf64_Sym *sym, unsigned int ndx,
                              uintptr_t *refcook, uintptr_t *defcook,
                              unsigned int *flags, const char *symname);

       Динамический компоновщик вызывает одну из этих функций при выполнении  символьной  привязки  между  двумя
       общими  объектами,  которые  были  помечены для уведомления функцией la_objopen(). Функция la_symbind32()
       применяется на 32-битных платформах; la_symbind64() применяется на 64-битных платформах.

       Аргумент sym является указателем на структуру,  которая  содержит  информацию  о  привязываемом  символе.
       Определение  структуры  находится  в  <elf.h>. Среди полей структуры есть поле st_value, которое содержит
       адрес привязываемого символа.

       В аргументе ndx указывается индекс символа в таблице символов привязываемого общего объекта.

       В аргументе refcook указывается общий объект, который ссылается на  символ;  это  тот  же  идентификатор,
       который указывается в функции la_objopen(), возвращающей LA_FLG_BINDFROM. В аргументе defcook указывается
       общий  объект,  который  определяет  символ,  на  который  производится ссылка; это тот же идентификатор,
       который указывается в функции la_objopen(), возвращающей  LA_FLG_BINDTO.

       В аргументе symname задаётся строка, содержащая имя символа.

       Аргумент flags  представляет  собой  битовую  маску,  которая  содержит  информацию  о  символе  и  может
       использоваться  для  изменения  дальнейшего  отслеживания  этой  записи  PLT  (Procedure  Linkage Table).
       Динамический компоновщик может передавать следующие битовые значения в этом аргументе:

       LA_SYMB_DLSYM         Привязка возникла из-за вызова dlsym(3).

       LA_SYMB_ALTVALUE      Предыдущий вызов la_symbind*() вернул альтернативное значение для этого символа.

       По умолчанию, если в отслеживающей библиотеке реализованы функции la_pltenter() и la_pltexit()  (смотрите
       ниже),  то  эти  функции  вызываются  после la_symbind() для записей PLT каждый раз при ссылке на символ.
       Следующие флаги могут объединяться с помощью OR в *flags для изменения данного поведения по умолчанию:

       LA_SYMB_NOPLTENTER    Не вызывать la_pltenter() для этого символа.

       LA_SYMB_NOPLTEXIT     Не вызывать la_pltexit() для этого символа.

       Возвращаемое значение la_symbind32()  и  la_symbind64()  представляет  собой  адрес,  по  которому  нужно
       передать  управление  после возврата функций. Если отслеживающая библиотека просто наблюдает за привязкой
       символов, то должно возвращаться sym->st_value. Может возвращаться другое значение, если библиотека хочет
       передать управление в другое место.

   la_pltenter()
       Точное имя и типы аргументов данной функции  зависят  от  аппаратной  платформы  (подходящее  определение
       приведено в <link.h>). Ниже показано определение для x86-32:

       Elf32_Addr la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
                        uintptr_t *refcook, uintptr_t *defcook,
                        La_i86_regs *regs, unsigned int *flags,
                        const char *symname, long *framesizep);

       Эта  функция  вызывается  до  вызова  записи  PLT  между  двумя  общими  объектами,  которые помечены для
       уведомления о привязке.

       Значение аргументов sym, ndx, refcook, defcook и symname такое же как у la_symbind*().

       Аргумент regs указывает на структуру (определена в  <link.h>),  содержащую  значения  регистров,  которые
       будут использованы для вызова этой записи PLT.

       Аргумент  flags  указывает  на  битовую  маску,  которая  сообщает  информацию и может использоваться для
       изменения последующего слежения за этой записью PLT; значения как у la_symbind*().

       The framesizep argument points to a long int buffer that can be used to explicitly  set  the  frame  size
       used  for  the  call  to  this PLT entry.  If different la_pltenter()  invocations for this symbol return
       different values, then the maximum returned value is used.  The la_pltexit() function is called  only  if
       this buffer is explicitly set to a suitable value.

       Возвращаемое la_pltenter() значение подобно la_symbind*().

   la_pltexit()
       Точное  имя  и  типы  аргументов  данной  функции зависят от аппаратной платформы (подходящее определение
       приведено в <link.h>). Ниже показано определение для x86-32:

       unsigned int la_i86_gnu_pltexit(Elf32_Sym *sym, unsigned int ndx,
                        uintptr_t *refcook, uintptr_t *defcook,
                        const La_i86_regs *inregs, La_i86_retval *outregs,
                        const char *symname);

       Эта функция вызывается после завершения вызова записи PLT,  выполняемой  между  двумя  общими  объектами,
       которые  были  помечены  для  уведомления  при привязке. Функция вызывается перед передачей управления из
       записи PLT вызывающему.

       Значение аргументов sym, ndx, refcook, defcook и symname такое же как у la_symbind*().

       Аргумент  inregs  указывает  на  структуру  (определена  в  <link.h>),  содержащую  значения   регистров,
       используемых для вызова этой записи PLT. Аргумент outregs указывает на структуру (определена в <link.h>),
       содержащую  значения  для  вызова  в эту запись PLT. Эти значения могут изменяться вызывающим и изменения
       будут видимы вызывающему запись PLT.

       В текущей реализации GNU возвращаемое значение la_pltexit() игнорируется.

ВЕРСИИ

       This API is very similar to the Solaris API described in the Solaris Linker and Libraries Guide,  in  the
       chapter Runtime Linker Auditing Interface.

СТАНДАРТЫ

       Отсутствуют.

ПРИМЕЧАНИЯ

       Отметим следующие отличия API динамического компоновщика в Solaris:

       •  Интерфейс Solaris la_objfilter() не поддерживается в реализации GNU.

       •  В функциях Solaris la_symbind32() и la_pltexit() нет аргумента symname.

       •  В  функции Solaris la_pltexit() нет аргументов inregs и outregs (но есть аргумент retval со значением,
          возвращаемым функцией).

ОШИБКИ

       В glibc до версии 2.9 включительно, указание более одной отслеживающей библиотеки в LD_AUDIT  приводит  к
       падению во время выполнения. Это исправлено в glibc 2.10.

ПРИМЕРЫ

       #include <link.h>
       #include <stdio.h>

       unsigned int
       la_version(unsigned int version)
       {
           printf("la_version(): version = %u; LAV_CURRENT = %u\n",
                   version, LAV_CURRENT);

           return LAV_CURRENT;
       }

       char *
       la_objsearch(const char *name, uintptr_t *cookie, unsigned int flag)
       {
           printf("la_objsearch(): name = %s; cookie = %p", name, cookie);
           printf("; flag = %s\n",
                   (flag == LA_SER_ORIG) ?    "LA_SER_ORIG" :
                   (flag == LA_SER_LIBPATH) ? "LA_SER_LIBPATH" :
                   (flag == LA_SER_RUNPATH) ? "LA_SER_RUNPATH" :
                   (flag == LA_SER_DEFAULT) ? "LA_SER_DEFAULT" :
                   (flag == LA_SER_CONFIG) ?  "LA_SER_CONFIG" :
                   (flag == LA_SER_SECURE) ?  "LA_SER_SECURE" :
                   "???");

           return name;
       }

       void
       la_activity (uintptr_t *cookie, unsigned int flag)
       {
           printf("la_activity(): cookie = %p; flag = %s\n", cookie,
                   (flag == LA_ACT_CONSISTENT) ? "LA_ACT_CONSISTENT" :
                   (flag == LA_ACT_ADD) ?        "LA_ACT_ADD" :
                   (flag == LA_ACT_DELETE) ?     "LA_ACT_DELETE" :
                   "???");
       }

       unsigned int
       la_objopen(struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
       {
           printf("la_objopen(): loading \"%s\"; lmid = %s; cookie=%p\n",
                   map->l_name,
                   (lmid == LM_ID_BASE) ?  "LM_ID_BASE" :
                   (lmid == LM_ID_NEWLM) ? "LM_ID_NEWLM" :
                   "???",
                   cookie);

           return LA_FLG_BINDTO | LA_FLG_BINDFROM;
       }

       unsigned int
       la_objclose (uintptr_t *cookie)
       {
           printf("la_objclose(): %p\n", cookie);

           return 0;
       }

       void
       la_preinit(uintptr_t *cookie)
       {
           printf("la_preinit(): %p\n", cookie);
       }

       uintptr_t
       la_symbind32(Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
               uintptr_t *defcook, unsigned int *flags, const char *symname)
       {
           printf("la_symbind32(): symname = %s; sym->st_value = %p\n",
                   symname, sym->st_value);
           printf("        ndx = %u; flags = %#x", ndx, *flags);
           printf("; refcook = %p; defcook = %p\n", refcook, defcook);

           return sym->st_value;
       }

       uintptr_t
       la_symbind64(Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
               uintptr_t *defcook, unsigned int *flags, const char *symname)
       {
           printf("la_symbind64(): symname = %s; sym->st_value = %p\n",
                   symname, sym->st_value);
           printf("        ndx = %u; flags = %#x", ndx, *flags);
           printf("; refcook = %p; defcook = %p\n", refcook, defcook);

           return sym->st_value;
       }

       Elf32_Addr
       la_i86_gnu_pltenter(Elf32_Sym *sym, unsigned int ndx,
               uintptr_t *refcook, uintptr_t *defcook, La_i86_regs *regs,
               unsigned int *flags, const char *symname, long *framesizep)
       {
           printf("la_i86_gnu_pltenter(): %s (%p)\n", symname, sym->st_value);

           return sym->st_value;
       }

СМОТРИТЕ ТАКЖЕ

       ldd(1), dlopen(3), ld.so(8), ldconfig(8)

ПЕРЕВОД

       Русский  перевод  этой  страницы  руководства  разработал(и) aereiae <aereiae@gmail.com>, Azamat Hackimov
       <azamat.hackimov@gmail.com>,     Dmitriy     S.     Seregin     <dseregin@59.ru>,     Katrin     Kutepova
       <blackkatelv@gmail.com>,   Lockal   <lockalsash@gmail.com>,  Yuri  Kozlov  <yuray@komyakino.ru>,  Баринов
       Владимир, Иван Павлов <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях  общедоступной
       лицензии  GNU  (GNU  General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите  об  этом
       разработчику(ам)   по   его(их)  адресу(ам)  электронной  почты  или  по  адресу  списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                                   RTLD-AUDIT(7)