84b277
From 0fca5aae90d5a4e292db8db7b9c31c8390799368 Mon Sep 17 00:00:00 2001
84b277
From: Daniel Mack <zonque@gmail.com>
84b277
Date: Fri, 7 Mar 2014 14:43:59 +0100
84b277
Subject: [PATCH] manager: flush memory stream before using the buffer
84b277
84b277
When the manager receives a SIGUSR2 signal, it opens a memory stream
84b277
with open_memstream(), uses the returned file handle for logging, and
84b277
dumps the logged content with log_dump().
84b277
84b277
However, the char* buffer is only safe to use after the file handle has
84b277
been flushed with fflush, as the man pages states:
84b277
84b277
  When the stream is closed (fclose(3)) or flushed (fflush(3)), the
84b277
  locations pointed to by ptr and sizeloc are updated to contain,
84b277
  respectively, a pointer to the buffer and the current size of  the
84b277
  buffer.
84b277
  These values remain valid only as long as the caller performs no
84b277
  further output on the stream.  If further output is performed, then the
84b277
  stream must again be flushed before trying to access these variables.
84b277
84b277
Without that call, dump remains NULL and the daemon crashes in
84b277
log_dump().
84b277
84b277
Conflicts:
84b277
	src/core/manager.c
84b277
84b277
(cherry-picked from b2cdc6664ef6b56e47d38649d69b9943d9f9f5d0)
84b277
84b277
Resolves: #1147524
84b277
---
84b277
 src/core/manager.c | 17 +++++++++--------
84b277
 1 file changed, 9 insertions(+), 8 deletions(-)
84b277
84b277
diff --git a/src/core/manager.c b/src/core/manager.c
84b277
index 4ad26e1..e48ea36 100644
84b277
--- a/src/core/manager.c
84b277
+++ b/src/core/manager.c
84b277
@@ -1536,11 +1536,12 @@ static int manager_process_signal_fd(Manager *m) {
84b277
                 }
84b277
 
84b277
                 case SIGUSR2: {
84b277
-                        FILE *f;
84b277
-                        char *dump = NULL;
84b277
+                        _cleanup_free_ char *dump = NULL;
84b277
+                        _cleanup_fclose_ FILE *f = NULL;
84b277
                         size_t size;
84b277
 
84b277
-                        if (!(f = open_memstream(&dump, &size))) {
84b277
+                        f = open_memstream(&dump, &size);
84b277
+                        if (!f) {
84b277
                                 log_warning("Failed to allocate memory stream.");
84b277
                                 break;
84b277
                         }
84b277
@@ -1549,16 +1550,16 @@ static int manager_process_signal_fd(Manager *m) {
84b277
                         manager_dump_jobs(m, f, "\t");
84b277
 
84b277
                         if (ferror(f)) {
84b277
-                                fclose(f);
84b277
-                                free(dump);
84b277
                                 log_warning("Failed to write status stream");
84b277
                                 break;
84b277
                         }
84b277
 
84b277
-                        fclose(f);
84b277
-                        log_dump(LOG_INFO, dump);
84b277
-                        free(dump);
84b277
+                        if (fflush(f)) {
84b277
+                                log_warning("Failed to flush status stream");
84b277
+                                break;
84b277
+                        }
84b277
 
84b277
+                        log_dump(LOG_INFO, dump);
84b277
                         break;
84b277
                 }
84b277