From: Zbigniew Jędrzejewski-Szmek Date: Tue, 10 May 2022 12:11:55 +0000 (+0200) Subject: Optionally call printf on LOG_MESSAGE() arguments X-Git-Tag: v251-rc3~14^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9ce5cf9caf52503394ad5eac7a3dee2eee1a296;p=thirdparty%2Fsystemd.git Optionally call printf on LOG_MESSAGE() arguments With an intentional mistake: ../src/login/logind-dbus.c: In function ‘bus_manager_log_shutdown’: ../src/login/logind-dbus.c:1542:39: error: format ‘%s’ expects a matching ‘char *’ argument [-Werror=format=] 1542 | LOG_MESSAGE("%s %s", message), | ^~~~~~~ --- diff --git a/meson.build b/meson.build index 051eea9aac0..46f062d5303 100644 --- a/meson.build +++ b/meson.build @@ -33,6 +33,7 @@ conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path) conf.set10('BUILD_MODE_DEVELOPER', get_option('mode') == 'developer', description : 'tailor build to development or release builds') +conf.set10('LOG_MESSAGE_VERIFICATION', get_option('log-message-verification')) want_ossfuzz = get_option('oss-fuzz') want_libfuzzer = get_option('llvm-fuzz') diff --git a/meson_options.txt b/meson_options.txt index 2a030ac28ec..ff59120f77d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -470,6 +470,8 @@ option('fuzz-tests', type : 'boolean', value : 'false', description : 'run the fuzzer regression tests by default (with sanitizers)') option('install-tests', type : 'boolean', value : 'false', description : 'install test executables') +option('log-message-verification', type : 'boolean', value : 'false', + description : 'do fake printf() calls to verify format strings') option('ok-color', type : 'combo', choices : ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', diff --git a/src/basic/log.h b/src/basic/log.h index 6f0d838de37..b03ca3ef21c 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -300,7 +300,13 @@ bool log_on_console(void) _pure_; /* Helper to wrap the main message in structured logging. The macro doesn't do much, * except to provide visual grouping of the format string and its arguments. */ -#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__ +#if LOG_MESSAGE_VERIFICATION +/* Do a fake formatting of the message string to let the scanner verify the arguments + * against the format message. */ +# define LOG_MESSAGE(fmt, ...) "MESSAGE=%.0d" fmt, printf(fmt, ##__VA_ARGS__), ##__VA_ARGS__ +#else +# define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__ +#endif void log_received_signal(int level, const struct signalfd_siginfo *si); diff --git a/src/core/unit.h b/src/core/unit.h index 733eeecd7f0..20c511c108c 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -1046,7 +1046,8 @@ Condition *unit_find_failed_condition(Unit *u); #define log_unit_struct_iovec(unit, level, iovec, n_iovec) log_unit_struct_iovec_errno(unit, level, 0, iovec, n_iovec) -#define LOG_UNIT_MESSAGE(unit, fmt, ...) "MESSAGE=%s: " fmt, (unit)->id, ##__VA_ARGS__ +/* Like LOG_MESSAGE(), but with the unit name prefixed. */ +#define LOG_UNIT_MESSAGE(unit, fmt, ...) LOG_MESSAGE("%s: " fmt, (unit)->id, ##__VA_ARGS__) #define LOG_UNIT_ID(unit) (unit)->manager->unit_log_format_string, (unit)->id #define LOG_UNIT_INVOCATION_ID(unit) (unit)->manager->invocation_log_format_string, (unit)->invocation_id_string