Debug strings contain all kinds of information including some under user control. Previously we simply sent everything to stderr, but this is potentially insecure, as well as not dealing well with non-printable characters. Escape these strings when printing. --- server/debug.c | 52 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/server/debug.c b/server/debug.c index 2231d40a0..1fc56ec50 100644 --- a/server/debug.c +++ b/server/debug.c @@ -42,6 +42,7 @@ #include "ansi-colours.h" #include "open_memstream.h" +#include "utils.h" #include "internal.h" @@ -69,19 +70,22 @@ prologue (FILE *fp) static void debug_common (bool in_server, const char *fs, va_list args) { - int err = errno; -#ifndef WIN32 - int tty; -#endif - CLEANUP_FREE char *str = NULL; - size_t len = 0; - FILE *fp; - if (!verbose) return; - fp = open_memstream (&str, &len); - if (fp == NULL) { + int err = errno; + +#ifndef WIN32 + int tty; +#endif + CLEANUP_FREE char *str_inner = NULL; + CLEANUP_FREE char *str_outer = NULL; + FILE *fp_inner, *fp_outer; + size_t len_inner = 0, len_outer = 0; + + /* The "inner" string is the debug string before escaping. */ + fp_inner = open_memstream (&str_inner, &len_inner); + if (fp_inner == NULL) { fail: /* Try to emit what we can. */ errno = err; @@ -89,28 +93,34 @@ debug_common (bool in_server, const char *fs, va_list args) fprintf (stderr, "\n"); return; } + errno = err; + vfprintf (fp_inner, fs, args); + close_memstream (fp_inner); + + /* The "outer" string contains the prologue, escaped debug string and \n. */ + fp_outer = open_memstream (&str_outer, &len_outer); + if (fp_outer == NULL) goto fail; #ifndef WIN32 tty = isatty (fileno (stderr)); - if (!in_server && tty) ansi_force_colour (ANSI_FG_BOLD_BLACK, fp); + if (!in_server && tty) ansi_force_colour (ANSI_FG_BOLD_BLACK, fp_outer); #endif - prologue (fp); - - errno = err; - vfprintf (fp, fs, args); + prologue (fp_outer); + c_string_quote (str_inner, fp_outer); #ifndef WIN32 - if (!in_server && tty) ansi_force_restore (fp); + if (!in_server && tty) ansi_force_restore (fp_outer); #endif - fprintf (fp, "\n"); - close_memstream (fp); + fprintf (fp_outer, "\n"); + close_memstream (fp_outer); - if (str) - fputs (str, stderr); - else + if (!str_outer) goto fail; + /* Send it to stderr as atomically as possible. */ + fputs (str_outer, stderr); + errno = err; } -- 2.39.2 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs