Очиститель адресов и __attribute(section("mysection")) не работают
Я использую библиотеку для регистрации некоторых структур во время компиляции. В этом случае это регистрация структуры, представляющей метод 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-я команда является действительным указателем (предположительно, из-за заполнения).
Теперь реальный вопрос: каков самый чистый способ исправить это? Должен ли я попытаться увеличить размер шага (в этом случае необходима инструкция препроцессора, чтобы отличить использование дезинфицирующего средства)? Или есть способ отключить этот отступ для вещей в разделе?
1 ответ
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, чтобы заставить Clang вести себя как GCC или добавить специальный флаг для управления инструментарием пользовательских секций (в последнем случае нам также необходимо обновить вики-страницу о несовместимости Asan Clang/GCC).