From c0aea35e13bfd9a8ecca3825f64d97cfb3e6667e Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Thu, 20 Feb 2020 08:50:00 +0000 Subject: In _dbus_verbose_real() avoid possible stack overflows on output to the Windows debug port Instead of creating a fixed memory area on the stack that can lead to a stack overflow if exceeded, this configuration now uses a DBusString instance that dynamically manages memory. Resolves: https://gitlab.freedesktop.org/dbus/dbus/issues/45 --- dbus/dbus-internals.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------- dbus/dbus-internals.h | 1 + dbus/dbus-memory.c | 2 +- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index 7eb85501..57b8cea7 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -381,6 +381,30 @@ dbus_bool_t _dbus_get_verbose (void) return verbose; } +/** + * Low-level function for displaying a string + * for the predefined output channel, which + * can be the Windows debug output port or stderr. + * + * This function must be used instead of + * dbus_verbose(), if a dynamic memory request + * cannot be used to avoid recursive call loops. + * + * @param s string to display + */ +void +_dbus_verbose_raw (const char *s) +{ + if (!_dbus_is_verbose_real ()) + return; +#ifdef DBUS_USE_OUTPUT_DEBUG_STRING + OutputDebugStringA (s); +#else + fputs (s, stderr); + fflush (stderr); +#endif +} + /** * Prints a warning message to stderr * if the user has enabled verbose mode. @@ -429,16 +453,37 @@ _dbus_verbose_real ( need_pid = FALSE; va_start (args, format); + #ifdef DBUS_USE_OUTPUT_DEBUG_STRING { - char buf[1024]; - strcpy(buf,module_name); + DBusString out = _DBUS_STRING_INIT_INVALID; + const char *message = NULL; + + if (!_dbus_string_init (&out)) + goto out; + + if (!_dbus_string_append (&out, module_name)) + goto out; + #ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS - sprintf (buf+strlen(buf), "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function); + if (!_dbus_string_append_printf (&out, "[%s(%d):%s] ", _dbus_file_path_extract_elements_from_tail (file, 2), line, function)) + goto out; #endif - vsprintf (buf+strlen(buf),format, args); - va_end (args); - OutputDebugStringA(buf); + if (!_dbus_string_append_printf_valist (&out, format, args)) + goto out; + message = _dbus_string_get_const_data (&out); +out: + if (message == NULL) + { + OutputDebugStringA ("Out of memory while formatting verbose message: '"); + OutputDebugStringA (format); + OutputDebugStringA ("'"); + } + else + { + OutputDebugStringA (message); + } + _dbus_string_free (&out); } #else #ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS @@ -446,10 +491,10 @@ _dbus_verbose_real ( #endif vfprintf (stderr, format, args); - va_end (args); - fflush (stderr); #endif + + va_end (args); } /** diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 94bd7801..73443e23 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -119,6 +119,7 @@ DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_get_verbose (void); DBUS_PRIVATE_EXPORT void _dbus_set_verbose (dbus_bool_t state); +void _dbus_verbose_raw (const char *s); # define _dbus_verbose_reset _dbus_verbose_reset_real # define _dbus_is_verbose _dbus_is_verbose_real diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c index 5468561a..96df2357 100644 --- a/dbus/dbus-memory.c +++ b/dbus/dbus-memory.c @@ -261,7 +261,7 @@ _dbus_decrement_fail_alloc_counter (void) if (!called) { - _dbus_verbose("TODO: memory allocation testing errors disabled for now\n"); + _dbus_verbose_raw ("TODO: memory allocation testing errors disabled for now\n"); called = 1; } return FALSE; -- cgit v1.2.1