我使用a library在编译时注册一些结构。在本例中,它注册了一个表示我想公开的JSON-RPC方法的结构。该库使用__attribute(section("xautodata_" "somename"))标记结构,以便将其放在单独的部分中,以便稍后可以检索。生成的内容将如下所示:
static const autodata_json_command_ *__attribute__((__used__)) __attribute__((section("xautodata_" "json_command"))) autodata_json_command_151 = (&help_command);;
static const autodata_json_command_ *__attribute__((__used__)) __attribute__((section("xautodata_" "json_command"))) autodata_json_command_173 = (&stop_command);;稍后检索命令的代码将获得指向该部分的指针(并计算该部分中的元素数量),并对其进行迭代,如下所示:
size_t count;
struct json_command **commands = get_json_commands(&count);
for (size_t i=0; i<count; i++) {
// Access commands[i];
}如果我们不使用-fsanitize=address编译,这将非常好地工作,但是当我们使用-fsanitize=address编译时,它将添加填充。
如果没有地址消毒器,命令是相邻的,即commands[0]和commands[1]是指向结构的有效指针。使用杀菌器,每隔8个命令才是一个有效的指针(可能是由于填充)。
现在是真正的问题:解决这个问题的最干净的方法是什么?我是否应该尝试使步长更大(在这种情况下,需要一个预处理器指令来区分消毒剂的使用)?或者,有没有办法禁用该部分中的内容的填充?
发布于 2018-11-28 03:46:21
出于您概述的原因,GCC Asan故意避免在自定义部分中插入变量(即保持连续性):
/* Don't protect if using user section, often vars placed
into user section from multiple TUs are then assumed
to be an array of such vars, putting padding in there
breaks this assumption. */
|| (DECL_SECTION_NAME (decl) != NULL
&& !symtab_node::get (decl)->implicit_section
&& !section_sanitized_p (DECL_SECTION_NAME (decl)))(来自gcc/asan.c)。在这种情况下,可以使用特殊的标志-fsanitize-sections=wildcard1,wildcard2,...来强制插入。
另一方面,Clang Asan忽略用户部分注释(参见AddressSanitizer.cpp)。
我建议将PR添加到Asan tracker中,以使Asan Clang/GCC incompatibility wiki的行为像GCC一样,或者添加一个特殊的标志来控制用户部分的插入(在后一种情况下,我们还需要更新Clang )。
https://stackoverflow.com/questions/53503870
复制相似问题