Можно ли сказать libfuzzer игнорировать определенный код?

Я использую libfuzzer, и до сих пор это был отличный опыт. Мой код под fuzz полон таких ветвей:

bool fuzzingThisFunc() {
  if (!checkSomething()) {
    fmt::printf("error log");
    return false;
  }

  ...

  return true;
}

Где fmt::printf — функция из сторонней библиотеки (http://github.com/fmtlib/fmt).

Я чувствую, что после нескольких итераций фаззер входит в эту функцию и фактически начинает фаззить все ветки внутри нее (например, когда он использует DFS вместо BFS).

Я хотел бы добавить некоторый барьер или инструкцию к фаззеру, чтобы не вставлять инструменты в сторонние библиотеки, поэтому мой фаззер будет пытаться охватить только мой код.

Является ли это возможным?

Я был бы обеспокоен тем, что ошибки в вашем коде естественным образом проявляются в сторонних API с узким контрактом. В этом случае включение {fmt} в ваш поиск будет необходимо, хотя и дорого.

John McFarlane 22.04.2022 13:24

Мне любопытно узнать, какой уровень оптимизации вы используете и насколько это помогает?

John McFarlane 22.04.2022 13:24
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
581
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Libfuzzer поддерживает инструментирование на уровне исходного файла. Вариантом может быть создание сторонних библиотек без флага -fsanitize=fuzzer. Проверьте CFLAGS, переданные для настройки этих библиотек, чтобы снять этот флаг.

Библиотеки только для заголовков обычно включают шаблоны, как в случае с fmt. Они должны быть созданы во время компиляции. Я не вижу простого способа справиться с этим. Вы можете найти все используемые аргументы шаблона, создать преобразователь кода, который использует их с этими аргументами, исключить этот код из инструментовки и изменить свой вызывающий код, чтобы использовать эти экземпляры функций, но это очень сложно.

Когда код, который вы хотите не инструментировать, выполняет только ведение журнала или другие действия, которые можно пропустить без изменения поведения вашего приложения, вы можете сделать его условным для компиляции. Документы Libfuzzer предлагают использовать FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION define для пометки кода, который вы не хотите создавать для фаззинга. В первом случае это будет:

bool fuzzingThisFunc() {
  if (!checkSomething()) {
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
    fmt::printf("error log");
#endif
    return false;
  }

  ...

  return true;
}

или изменение кода библиотеки:

template <typename S, typename... Args,
          FMT_ENABLE_IF(detail::is_string<S>::value)>
inline int printf(const S& format_str, const Args&... args) {

#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  using context = basic_printf_context_t<char_t<S>>;
  return vprintf(to_string_view(format_str),
                 make_format_args<context>(args...));
#else
  return 0; //C printf returns number of characters written, I assume same for fmt.
#endif
}

Второй случай кодировать проще (одна модификация для каждой исключенной функции), но вам придется добавлять эту модификацию каждый раз, когда вы получаете новую версию fmt. В первом случае вам нужно изменить каждый исключенный сайт вызова функции.

В обоих случаях вы должны добавить -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION в CFLAGS конфигурации для фаззинга целевой сборки.

Интересная идея! Как насчет библиотек только для заголовков?

warchantua 22.01.2021 19:32

Изменил мой ответ. Libfuzzer может исследовать fmt::printf, если он может что-то изменить, что влияет на его внутреннее поведение. Очевидным выбором являются аргументы функции. Когда они жестко закодированы, как в случае с fmt::printf("журнал ошибок"), он не может их изменить. В этом случае ваши предположения о том, что libfuzzer застревает при изучении fmt, могут быть ошибочными.

nevilad 23.01.2021 11:44

Как только я отключил ведение журнала, мой фаззер сразу обнаружил проблему... Я использовал переключатель компиляции, чтобы отключить все регистраторы (к счастью, они были скрыты под макросом, поэтому я изменил 1 место).

warchantua 25.01.2021 19:12

Другие вопросы по теме