首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在动态加载的共享库中使用UBSAN

在动态加载的共享库中使用UBSAN
EN

Stack Overflow用户
提问于 2019-08-05 15:33:28
回答 1查看 466关注 0票数 1

我试图在一个项目中使用UBSAN,但遇到了一个似乎不可能解决的问题:该项目使用通过共享库实现的插件系统。也就是说,每个插件都提供一个工厂方法,该方法返回带有插件特定派生类的某个抽象类的实例。然后,该项目遍历文件夹中的所有共享库,用dlopen打开它们,通过dlsym获取工厂方法,并创建插件实例,然后使用插件实例。

然而,在使用任何接口方法时,UBSAN抛出member call on address 0x... which does not point to an object of type '...'

MWE:

foo.h

代码语言:javascript
复制
struct Foo{
  virtual int g() = 0;
};
extern "C" Foo* create();

foo.cpp

代码语言:javascript
复制
#include "foo.h"
struct Bar: Foo{
    int g(){ return 42; }
};
Foo* create(){
  return new Bar();
}

main.cpp

代码语言:javascript
复制
#include "foo.h"
#include <dlfcn.h>
#include <cassert>

int main(){
  void* h = dlopen("libfoo.so", RTLD_GLOBAL | RTLD_NOW);
  assert(h);
  void* c = dlsym(h, "create");
  assert(c);
  using create_t = Foo*();
  Foo* f  = reinterpret_cast<create_t*>(c)();
  return f->g() != 42;
}

用下列方法汇编:

  • g++ -shared -fPIC -o libfoo.so foo.cpp
  • g++ -fsanitize=vptr main.cpp -ldl
  • ./a.out

https://whatofhow.wordpress.com/2015/03/17/odr-rtti-dso解释说,这是由于共享库中的RTTI信息和二进制文件不同造成的。

一个非常类似的问题也会发生,当您在共享库中导出一个函数时,使用dlsym导入它并尝试调用它。结果将是call to function <...> through pointer to incorrect function type '<...>'-fsanitize=function的clang。

有什么办法解决这个问题吗?我不使用Clang,也不玩-fvisibility,所以不知道在这里做什么。

EN

回答 1

Stack Overflow用户

发布于 2019-08-06 15:53:07

-fsanitize=function中使用clang已经报告了对create调用的违反:

通过指向不正确函数类型'Foo ()()的指针调用函数创建

这看起来同样是一个假阳性,只有当共享库和可执行文件用‘-fsanitize=.’编译时才会发生。

通过将不同编译的共享库的类型信息与nm -C libfoo.so | grep typeinfo进行比较,发现使用消毒液的库中有一个用于typeinfo for Foo* ()的额外类型信息。

为什么要输入信息?那么,UBSAN比较类型信息,以确定传递的指针(函数还是类)是预期的指针。typeinfo比较是通过指针比较完成的。这对速度是很好的,但也带来了一个微妙的问题:即使实际的类型实际上是相同的,它们也可能不共享相同的typeinfo

这里的情况是这样的:库中的typeinfo和可执行文件没有合并,所以有两个相同类型信息的实例。

解决方案是在创建可执行文件时传递-rdynamic。来自GCC手册

将标志-导出-动态传递给ELF链接器,在支持它的目标上。这将指示链接器向动态符号表中添加所有符号,而不仅仅是使用的符号。对于dlopen的某些用途,或为了允许从程序中获取回溯跟踪,需要此选项。

在这里,我们似乎有这样一个“使用dlopen”。

对于CMake,在可执行目标上使用属性ENABLE_EXPORTS

有关UBSAN问题的更多乐趣,请参见相关问题通过指向不正确函数类型的指针调用函数(未知)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57361776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档