libdl 中的链接映射是什么以及为什么它们会使我的应用程序崩溃?

问题描述 投票:0回答:1

最近我尝试构建一个复杂的 C++ 应用程序。应用程序已构建。但是当我尝试启动它时,它因非法内存访问而崩溃。实际上它是带有偏移量的空指针。 我开始调查原因。使用 dlopen 动态加载库 (libXcursor.so) 时发生崩溃。所以原因是空指针

link_map->l_versions
,在
elf_machine_rela
函数内部重定位的过程中没有检查(特别是在
RESOLVE_MAP
宏中)。这发生在这里:map->l_versions[ndx]

          ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
          elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
                   &map->l_versions[ndx],
                   (void *) (l_addr + r->r_offset), skip_ifunc);

前面提到的

link_map
是库在加载过程中的依赖描述。正如我所看到的,这种依赖关系尚未完全初始化。但更奇怪的是,这实际上并不是依赖项:它是一个
libgthread
库 DSO。而 libXcursor.so 确实不依赖于它。

提到的

link_map
libgthread
dl_open_worker进行搬迁:

    _dl_relocate_object (l, l->l_scope, reloc_mode, 0);

正在收集到家属名单这样

  l = new;
  do
    {
      if (! l->l_real->l_relocated)
    maps[nmaps++] = l;
      l = l->l_next;
    }
  while (l != NULL);

这里

new
是libXcursor.so本身找到的
link_map
。 这段代码很奇怪恕我直言。 因为同时其他部门实际上是用这段代码初始化的:

  /* Load that object's dependencies.  */
  _dl_map_object_deps (new, NULL, 0, 0,
               mode & (__RTLD_DLOPEN | RTLD_DEEPBIND | __RTLD_AUDIT));

  /* So far, so good.  Now check the versions.  */
  for (unsigned int i = 0; i < new->l_searchlist.r_nlist; ++i)
    if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
      (void) _dl_check_map_versions (new->l_searchlist.r_list[i]->l_real,
                     0, 0);

所以问题是为什么其他依赖项列表被传递,并且在如此重要的地方(系统加载器)没有进行额外的检查。以及可能在哪里修复崩溃。

使用的libdl版本是来自glibc-2.27-38.fc28.x86_64的/lib64/libdl-2.27.so

似乎问题已在这里这里那里那里得到解决。它不会复制。小应用程序也无法重现 2.27 版本的原始崩溃。

c linux elf libc libdl
1个回答
0
投票

因此,尝试使用新的 glibc 后,我们得到了以下结果。

似乎问题已在这里这里那里那里得到解决。它不会复制。小应用程序也无法重现 2.27 版本的原始崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.