链接程序和库指南

审计接口函数

rtld-audit 接口提供了以下函数。这些函数按照其预期的使用顺序进行说明。


注 –

为了简化讨论,对体系结构或目标文件类特定接口的引用会缩减为其通用名称。例如,对 la_symbind32()la_symbind64() 的引用会指定为 la_symbind()


la_version()

此函数可提供运行时链接程序与审计库之间的初次握手。必须提供此接口才能装入审计库。

uint_t la_version(uint_t version);

运行时链接程序通过其可以支持的 version 最高的 rtld-audit 接口来调用此接口。审计库可以检验此版本是否足以供其使用,并返回审计库预期使用的版本。此版本通常为 /usr/include/link.h 中定义的 LAV_CURRENT

如果审计库返回零,或者返回的版本高于运行时链接程序所支持的 rtld-audit 接口的版本,则会废弃该审计库。

la_activity()

此函数可通知审计程序正在进行链接映射活动。

void la_activity(uintptr_t * cookie, uint_t flags);

cookie 标识作为链接映射标题的目标文件。flags 表示活动类型,如 /usr/include/link.h 中所定义:

  • LA_ACT_ADD-正在向链接映射列表中添加目标文件。

  • LA_ACT_DELETE-正在从链接映射列表中删除目标文件。

  • LA_ACT_CONSISTENT-已经完成目标文件活动。

la_objsearch()

此函数可通知审计程序将要搜索目标文件。

char * la_objsearch(const char * name, uintptr_t * cookie, uint_t flags);

name 表示所搜索的文件名或路径名。cookie 标识启动搜索的目标文件。flags 标识 name 的来源和创建方式,如 /usr/include/link.h 中所定义:

  • LA_SER_ORIG-初始搜索名称。通常,此名称表示记录为 DT_NEEDED 项的文件名或者提供给 dlopen(3C) 的参数。

  • LA_SER_LIBPATH-已经通过 LD_LIBRARY_PATH 组件创建了路径名。

  • LA_SER_RUNPATH-已经通过 运行路径 组件创建了路径名。

  • LA_SER_DEFAULT-已经通过缺省搜索路径组件创建了路径名。

  • LA_SER_CONFIG-路径组件源自配置文件。请参见crle(1)

  • LA_SER_SECURE-路径组件特定于安全目标文件。

返回值会指明运行时链接程序应该继续处理的搜索路径名。值为零表示应该忽略此路径。监视搜索路径的审计库会返回 name

la_objopen()

此函数在运行时链接程序装入新目标文件时调用。

uint_t la_objopen(Link_map * lmp, Lmid_t lmid, uintptr_t * cookie);

lmp 提供说明新目标文件的链接映射结构。lmid 标识添加了目标文件的链接映射列表。cookie 提供指向某个标识符的指针。此标识符会初始化为目标文件 lmp。审计库可以修改此标识符,以便更好地标识其他 rtld-audit 接口例程的目标文件。

la_objopen() 函数会返回表示与此目标文件相关的符号绑定的值。返回值是 /usr/include/link.h 中定义的以下值的掩码:

  • LA_FLG_BINDTO-审计此目标文件的符号绑定。

  • LA_FLG_BINDFROM-审计来自此目标文件的符号绑定。

通过这些值,审计程序可以选择要使用 la_symbind() 监视的目标文件。返回值为零表示绑定信息与此目标文件无关。

例如,审计程序可以监视从 libfoo.solibbar.so 的绑定。将 la_objopen() 用于 libfoo.so 会返回 LA_FLG_BINDFROM。将 la_objopen()用于 libbar.so 会返回 LA_FLG_BINDTO

审计程序可以监视 libfoo.solibbar.so 之间的所有绑定。将 la_objopen() 用于这两个目标文件会返回 LA_FLG_BINDFROMLA_FLG_BINDTO

审计程序可以监视到 libbar.so 的所有绑定。将 la_objopen() 用于 libbar.so 会返回 LA_FLG_BINDTO。所有 la_objopen() 调用都会返回 LA_FLG_BINDFROM

la_objfilter()

此函数在过滤器装入新的 filtee 时调用。请参见作为过滤器的共享库

int la_objfilter(uintptr_t * fltrcook, const char * fltestr,

        uintptr_t * fltecook, uint_t flags);

fltrcook 标识过滤器。fltestr 指向 filtee 字符串。fltecook 标识 filtee。flags 当前未使用。对于过滤器和 filtee,la_objfilter()la_objopen() 之后调用。

值为零表示应该忽略此 filtee。监视过滤器使用情况的审计库会返回非零值。

la_preinit()

为应用程序装入所有目标文件之后但在将控制权转交给应用程序之前,会调用一次此函数。

void la_preinit(uintptr_t * cookie);

cookie 标识启动进程的主目标文件,通常为动态可执行文件。

la_symbind()

在已经通过 la_objopen() 标记用于绑定通知的两个目标文件之间进行绑定时,会调用此函数。

uintptr_t la_symbind32(Elf32_Sym * sym, uint_t ndx,

        uintptr_t * refcook, uintptr_t * defcook, uint_t * flags);

 

uintptr_t la_symbind64(Elf64_Sym * sym, uint_t ndx,

        uintptr_t * refcook, uintptr_t * defcook, uint_t * flags,

        const char * sym_name);

sym 是构造的符号结构,其 sym->st_value 表示所绑定的符号定义的地址。 请参见 /usr/include/sys/elf.hla_symbind32() 可将 sym->st_name 调整为指向实际符号名称。la_symbind64() 可保留 sym->st_name 作为绑定目标文件字符串表的索引。

ndx 表示绑定目标文件的动态符号表内的符号索引。refcook 标识引用此符号的目标文件。此标识符与传递给 la_objopen() 函数的标识符相同,此函数会返回 LA_FLG_BINDFROMdefcook 标识定义此符号的目标文件。此标识符与传递给 la_objopen() 的标识符相同,此函数会返回 LA_FLG_BINDTO

flags 指向可以传送与绑定相关的信息的数据项。此数据项还可用于修改对此过程链接表项的继续审计。该值是 /usr/include/link.h 中定义的符号绑定标志的掩码。

可以为 la_symbind() 提供以下标志:

  • LA_SYMB_DLSYM-由于调用 dlsym(3C) 而发生的符号绑定。

  • LA_SYMB_ALTVALUE (LAV_VERSION2)-通过先前调用 la_symbind() 为符号值返回替换值。

如果 la_pltenter()la_pltexit() 函数存在,则对于过程链接表的各项,这些函数在 la_symbind() 之后调用。每次引用符号时都会调用这些函数。 另请参见审计接口限制

la_symbind() 可以提供以下标志来更改此缺省行为。这些标志可应用于按位或运算(包含边界值),并通过 flags 参数来指示其值。

  • LA_SYMB_NOPLTENTER请勿针对此符号调用 la_pltenter() 函数。

  • LA_SYMB_NOPLTEXIT请勿针对此符号调用 la_pltexit() 函数。

返回值表示在此调用后将控制权传递到的地址。监视符号绑定的审计库应该返回值 sym->st_value,以便将控制权传递给绑定符号定义。审计库可以通过返回不同的值对符号绑定进行专门重定向。

sym_name 仅适用于 la_symbind64(),其中包含所处理的符号的名称。对于 32 位接口,可在 sym->st_name 字段中使用此名称。

la_pltenter()

这些函数是系统特定的。调用过程链接表中位于已经标记用于绑定通知的两个目标文件之间的一项时,会调用这些函数。

uintptr_t la_sparcv8_pltenter(Elf32_Sym * sym, uint_t ndx,

        uintptr_t * refcook, uintptr_t * defcook,

        La_sparcv8_regs * regs, uint_t * flags);

 

uintptr_t la_sparcv9_pltenter(Elf64_Sym * sym, uint_t ndx,

        uintptr_t * refcook, uintptr_t * defcook,

        La_sparcv9_regs * regs, uint_t * flags,

        const char * sym_name);

 

uintptr_t la_i86_pltenter(Elf32_Sym * sym, uint_t ndx,

        uintptr_t * refcook, uintptr_t * defcook,

        La_i86_regs * regs, uint_t * flags); 

uintptr_t la_amd64_pltenter(Elf64_Sym * sym, uint_t ndx,

        uintptr_t * refcook, uintptr_t * defcook,

        La_amd64_regs * regs, uint_t * flags, const char * sym_name);

symndxrefcookdefcooksym_name 提供的信息与传递给 la_symbind() 的信息相同。

对于 la_sparcv8_pltenter()la_sparcv9_pltenter()regs 指向输出寄存器。对于 la_i86_pltenter()regs 指向栈寄存器和帧寄存器。对于 la_amd64_pltenter()regs 指向栈寄存器、帧寄存器以及用于传递整数参数的寄存器。regs/usr/include/link.h 中定义。

flags 指向可以传送与绑定相关的信息的数据项。此数据项可用于修改对此过程链接表项的继续审计。此数据项与 la_symbind() 中的 flags 指向的数据项相同。

la_pltenter() 可以提供以下标志来更改当前的审计行为。这些标志可应用于按位或运算(包含边界值),并通过 flags 参数来指示其值。

  • LA_SYMB_NOPLTENTER不能针对此符号再次调用 la_pltenter()

  • LA_SYMB_NOPLTEXIT不能针对此符号再次调用 la_pltexit()

返回值表示在此调用后将控制权传递到的地址。监视符号绑定的审计库应该返回值 sym->st_value,以便将控制权传递给绑定符号定义。审计库可以通过返回不同的值对符号绑定进行专门重定向。

la_pltexit()

返回过程链接表中位于已经标记用于绑定通知的两个目标文件之间的一项时,会调用此函数。此函数在调用方获取控制权之前调用。

uintptr_t la_pltexit(Elf32_Sym * sym, uint_t ndx, uintptr_t * refcook,

        uintptr_t * defcook, uintptr_t retval);



uintptr_t la_pltexit64(Elf64_Sym * sym, uint_t ndx, uintptr_t * refcook,

        uintptr_t * defcook, uintptr_t retval, const char * sym_name);

symndxrefcookdefcooksym_name 提供的信息与传递给 la_symbind() 的信息相同。retval 是绑定函数的返回代码。监视符号绑定的审计库应该返回 retval。审计库可以专门返回不同的值。


注 –

la_pltexit() 接口是实验接口。请参见审计接口限制


la_objclose()

此函数在执行目标文件的任何终止代码之后和卸载目标文件之前调用。

uint_t la_objclose(uintptr_t * cookie);

cookie 标识目标文件,并从先前的 la_objopen() 中获取。当前会忽略任何返回值。