🌚

Kam's Online Notebook


Relocation 中的一个 UB

起因是同事更新了项目所使用的百度地图 SDK 之后,我们的 XML 解析库就没法用了。解析库每次运行到 xmlFree 函数就会跳到 baidu 开头的另一个函数里面去,然后爆出:

Pointer being freed was not allocated

看起来像是调用 libxmlxmlFree 函数代码,最后调用了百度提供的实现。

Reproduce

已知 XML 解析库和百度 SDK 都是静态库,然后 XML 解析库引用了 libxmlxmlFree 函数,所以很容易重现。

// in A.a, a.o
void xmlFree(void *ptr) {   
}

// in B.a, b.o
#import <libxml/HTMLparser.h>
#import <libxml/xpath.h>
#import <libxml/xpathInternals.h>

void foo(void) {
    xmlFree(NULL);
}

// in main executable
foo()

测试了一下,发现是 A.a 里面的 extern xmlFree 的存在,会导致在重定位阶段把 b.o 的 fooxmlFree 的引用指向了 A.a 中的定义。而且这样的结果貌似是未定义行为,暂时还没搜索到具体文档说明。

顺便提一下,两个静态库函数同名 linkage 会报错;两个动态库函数同名实际调用顺序就跟动态链接顺序相关。不过这都不是什么好的工程实践,SDK 提供方还是得注意符号可见性问题。

Resolution

具体到这个案例上,只能先把 SDK 降回去,因为符号可见性的改变需要 SDK 提供方执行。

题外话,说起来 SDK 提供方对命名空间缺失的漠视(符号可见性控制、category naming clash),我觉得这么些年就没几个人在意过。

EOF

— Jul 6, 2021