C语言 两次发出RTLD_DI_SERINFOSIZE请求背后的考虑是什么?

zzzyeukh  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(105)

从我对dlinfoRTLD_DI_SERINFO的使用的理解来看,第一次调用给出了dls_size的值,这有助于确保结构体足够大,但第二次调用似乎没有做什么新的事情,只是重复第一次调用的计算,以填写两个字段dls_sizedls_cnt。此外,从dlopen接口调用的代码来看,我无法找到一些区分这两个调用的代码,因此我的问题是,这种两步调用序列是否真的有必要,或者仅仅复制这些统计数据就足够了,比如通过一个名为RTLD_DI_SERINFOSIZE_COPY的新请求项,从库作者的Angular 提供一些向前兼容性。下面的代码在我的机器上打印了两行完全相同的代码。

Dl_serinfo dl_search_size;
  if (dlinfo(dl_handle, RTLD_DI_SERINFOSIZE, &dl_search_size)) {
    printf("dlinfo: %s while populating search info size", dlerror());
    return;
  }
  printf("%d %ld\n", dl_search_size.dls_cnt, dl_search_size.dls_size);
  Dl_serinfo *dl_search_info = (Dl_serinfo *)malloc(dl_search_size.dls_size);
  if (!dl_search_info) {
    perror("malloc");
    return;
  }
  if (dlinfo(dl_handle, RTLD_DI_SERINFOSIZE, dl_search_info)) {
    printf("dlinfo: %s while ", dlerror());
    return;
  }
  printf("%d %ld\n", dl_search_info->dls_cnt, dl_search_info->dls_size);
cqoc49vn

cqoc49vn1#

两次发出RTLD_DI_SERINFOSIZE请求背后的考虑是什么?
做那件事毫无意义。
您调用dlinfo(..., RTLD_DI_SERINFOSIZE, ...)来获得足够的空间,以便可以调用dlinfo(..., RTLD_DI_SERINFO, ...),即获取您感兴趣的 * 实际 * 数据。

更新:

man page目前列出了4个步骤:
1.使用RTLD_DI_SERINFOSIZE请求
1.分配正确大小的Dl_serinfo缓冲区
1.使用另一个RTLD_DI_SERINFOSIZE请求
1.使用RTLD_DI_SERINFO获取库搜索路径。
第3步显然是假的/不必要的。我99.99%肯定这是手册页中的一个错误。

  • authoritative* 描述是glibc/manual/dynlink.texi文件,它说:
@item RTLD_DI_SERINFO
@itemx RTLD_DI_SERINFOSIZE
These requests can be used to obtain search path information for
@var{handle}.  For both requests, @var{arg} must point to a
@code{Dl_serinfo} object.  The @code{RTLD_DI_SERINFOSIZE} request must
be made first; it updates the @code{dls_size} and @code{dls_cnt} members
of the @code{Dl_serinfo} object.  The caller should then allocate memory
to store at least @code{dls_size} bytes and pass that buffer to a
@code{RTLD_DI_SERINFO} request.  This second request fills the
@code{dls_serpath} array.  The number of array elements was returned in
the @code{dls_cnt} member in the initial @code{RTLD_DI_SERINFOSIZE}
request.  The caller is responsible for freeing the allocated buffer.

This interface is prone to buffer overflows in multi-threaded processes
because the required size can change between the
@code{RTLD_DI_SERINFOSIZE} and @code{RTLD_DI_SERINFO} requests.

相关问题