From 003f455dab0204dd3f066ecdbea0470035f8181f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Thu, 13 Apr 2023 14:31:33 -0400 Subject: [PATCH] Fix: logging: unhandled error in *_FMT macros MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Coverity reports: 1508779 Uncaught exception If the exception is ever thrown, the program will crash. In lttng::​sessiond::​rotation_thread::​_thread_function(): A C++ exception is thrown but never caught (CWE-248) The *_FMT macros, which use fmtlib, don't handle the case where fmt::format throws. This can happen, in particular, when an invalid format string is used. The macros are modified to log the exception and abort. Signed-off-by: Jérémie Galarneau Change-Id: I7f4a066b418a9d544a679f773df7e94640755f47 --- src/common/error.cpp | 10 ++++++++++ src/common/error.hpp | 42 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/common/error.cpp b/src/common/error.cpp index 0bb088066..cafb15f92 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -452,3 +453,12 @@ void lttng_abort_on_error(void) abort(); } } + +[[noreturn]] void +lttng::logging::details::die_formatting_exception(const char *format, + const std::exception& formatting_exception) +{ + std::cerr << "Error occurred while formatting logging message: msg=`" << format + << "`: " << formatting_exception.what(); + abort(); +} diff --git a/src/common/error.hpp b/src/common/error.hpp index 7ce643411..93616718f 100644 --- a/src/common/error.hpp +++ b/src/common/error.hpp @@ -242,6 +242,7 @@ static inline void __lttng_print_check_abort(enum lttng_error_level type) /* * Version using GNU strerror_r, for linux with appropriate defines. */ +const char *error_get_str(int32_t code); #define PERROR(call, args...) \ do { \ char *_perror_buf; \ @@ -251,11 +252,44 @@ static inline void __lttng_print_check_abort(enum lttng_error_level type) } while (0); #endif -#define DBG_FMT(format_str, args...) DBG("%s", fmt::format(format_str, ##args).c_str()) -#define WARN_FMT(format_str, args...) WARN("%s", fmt::format(format_str, ##args).c_str()) -#define ERR_FMT(format_str, args...) ERR("%s", fmt::format(format_str, ##args).c_str()) +namespace lttng { +namespace logging { +namespace details { +[[noreturn]] void die_formatting_exception(const char *format, + const std::exception& formatting_exception); +} /* namespace details */ +} /* namespace logging */ +} /* namespace lttng */ -const char *error_get_str(int32_t code); +#define DBG_FMT(format_str, args...) \ + do { \ + try { \ + DBG("%s", fmt::format(format_str, ##args).c_str()); \ + } catch (const std::exception& _formatting_exception) { \ + lttng::logging::details::die_formatting_exception(format_str, \ + _formatting_exception); \ + } \ + } while (0); + +#define WARN_FMT(format_str, args...) \ + do { \ + try { \ + WARN("%s", fmt::format(format_str, ##args).c_str()); \ + } catch (const std::exception& _formatting_exception) { \ + lttng::logging::details::die_formatting_exception(format_str, \ + _formatting_exception); \ + } \ + } while (0); + +#define ERR_FMT(format_str, args...) \ + do { \ + try { \ + ERR("%s", fmt::format(format_str, ##args).c_str()); \ + } catch (const std::exception& _formatting_exception) { \ + lttng::logging::details::die_formatting_exception(format_str, \ + _formatting_exception); \ + } \ + } while (0); /* * Function that format the time and return the reference of log_time.str to -- 2.34.1