Jakub Filak 1c1276
From 2e74ca0f15d6d25568f5af1cc9cd30b4b01aa849 Mon Sep 17 00:00:00 2001
Jakub Filak 1c1276
From: Jakub Filak <jfilak@redhat.com>
Jakub Filak 1c1276
Date: Tue, 14 Oct 2014 03:15:28 +0200
Jakub Filak 1c1276
Subject: [PATCH 20/21] journal-oops: use the length result of
Jakub Filak 1c1276
 sd_journal_get_data()
Jakub Filak 1c1276
Jakub Filak 1c1276
journald doesn't guarantee NULL terminated strings returned from
Jakub Filak 1c1276
sd_journal_get_data(). It usually works but not always.
Jakub Filak 1c1276
Jakub Filak 1c1276
This patch fixes the issue by using the length of field data instead of
Jakub Filak 1c1276
assuming that string is NULL terminated.
Jakub Filak 1c1276
Jakub Filak 1c1276
Resolves: #1141549
Jakub Filak 1c1276
Jakub Filak 1c1276
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Jakub Filak 1c1276
---
Jakub Filak 1c1276
 src/plugins/abrt-dump-journal-oops.c | 13 ++++++-----
Jakub Filak 1c1276
 src/plugins/abrt-journal.c           | 43 ++++++++++++++++++++++--------------
Jakub Filak 1c1276
 src/plugins/abrt-journal.h           |  8 ++++---
Jakub Filak 1c1276
 3 files changed, 40 insertions(+), 24 deletions(-)
Jakub Filak 1c1276
Jakub Filak 1c1276
diff --git a/src/plugins/abrt-dump-journal-oops.c b/src/plugins/abrt-dump-journal-oops.c
Jakub Filak 1c1276
index 3f1f419..0ff9fe0 100644
Jakub Filak 1c1276
--- a/src/plugins/abrt-dump-journal-oops.c
Jakub Filak 1c1276
+++ b/src/plugins/abrt-dump-journal-oops.c
Jakub Filak 1c1276
@@ -38,8 +38,8 @@ static GList* abrt_journal_extract_kernel_oops(abrt_journal_t *journal)
Jakub Filak 1c1276
 
Jakub Filak 1c1276
     do
Jakub Filak 1c1276
     {
Jakub Filak 1c1276
-        const char *line = NULL;
Jakub Filak 1c1276
-        if (abrt_journal_get_log_line(journal, &line) < 0)
Jakub Filak 1c1276
+        char *line = abrt_journal_get_log_line(journal);
Jakub Filak 1c1276
+        if (line == NULL)
Jakub Filak 1c1276
             error_msg_and_die(_("Cannot read journal data."));
Jakub Filak 1c1276
 
Jakub Filak 1c1276
         if (lines_info_count == lines_info_size)
Jakub Filak 1c1276
@@ -48,10 +48,13 @@ static GList* abrt_journal_extract_kernel_oops(abrt_journal_t *journal)
Jakub Filak 1c1276
             lines_info = xrealloc(lines_info, lines_info_size * sizeof(lines_info[0]));
Jakub Filak 1c1276
         }
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-        lines_info[lines_info_count].level = koops_line_skip_level(&line);
Jakub Filak 1c1276
-        koops_line_skip_jiffies(&line);
Jakub Filak 1c1276
+        char *orig_line = line;
Jakub Filak 1c1276
+        lines_info[lines_info_count].level = koops_line_skip_level((const char **)&line);
Jakub Filak 1c1276
+        koops_line_skip_jiffies((const char **)&line);
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-        lines_info[lines_info_count].ptr = xstrdup(line);
Jakub Filak 1c1276
+        memmove(orig_line, line, strlen(line) + 1);
Jakub Filak 1c1276
+
Jakub Filak 1c1276
+        lines_info[lines_info_count].ptr = orig_line;
Jakub Filak 1c1276
 
Jakub Filak 1c1276
         ++lines_info_count;
Jakub Filak 1c1276
     }
Jakub Filak 1c1276
diff --git a/src/plugins/abrt-journal.c b/src/plugins/abrt-journal.c
Jakub Filak 1c1276
index 89c8393..e0ae159 100644
Jakub Filak 1c1276
--- a/src/plugins/abrt-journal.c
Jakub Filak 1c1276
+++ b/src/plugins/abrt-journal.c
Jakub Filak 1c1276
@@ -23,6 +23,12 @@
Jakub Filak 1c1276
 
Jakub Filak 1c1276
 #include <systemd/sd-journal.h>
Jakub Filak 1c1276
 
Jakub Filak 1c1276
+/*
Jakub Filak 1c1276
+ * http://www.freedesktop.org/software/systemd/man/sd_journal_get_data.html
Jakub Filak 1c1276
+ * sd_journal_set_data_threshold() : This threshold defaults to 64K by default.
Jakub Filak 1c1276
+ */
Jakub Filak 1c1276
+#define JOURNALD_MAX_FIELD_SIZE (64*1024)
Jakub Filak 1c1276
+
Jakub Filak 1c1276
 
Jakub Filak 1c1276
 struct abrt_journal
Jakub Filak 1c1276
 {
Jakub Filak 1c1276
@@ -84,33 +90,38 @@ int abrt_journal_get_field(abrt_journal_t *journal, const char *field, const voi
Jakub Filak 1c1276
     return 0;
Jakub Filak 1c1276
 }
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-int abrt_journal_get_string_field(abrt_journal_t *journal, const char *field, const char **value)
Jakub Filak 1c1276
+char *abrt_journal_get_string_field(abrt_journal_t *journal, const char *field, char *value)
Jakub Filak 1c1276
 {
Jakub Filak 1c1276
-    size_t value_len;
Jakub Filak 1c1276
-    const int r = abrt_journal_get_field(journal, field, (const void **)value, &value_len);
Jakub Filak 1c1276
+    size_t data_len;
Jakub Filak 1c1276
+    const char *data;
Jakub Filak 1c1276
+    const int r = abrt_journal_get_field(journal, field, (const void **)&data, &data_len);
Jakub Filak 1c1276
     if (r < 0)
Jakub Filak 1c1276
     {
Jakub Filak 1c1276
-        return r;
Jakub Filak 1c1276
+        log_notice("Cannot read journal data");
Jakub Filak 1c1276
+        return NULL;
Jakub Filak 1c1276
     }
Jakub Filak 1c1276
 
Jakub Filak 1c1276
     const size_t pfx_len = strlen(field) + 1;
Jakub Filak 1c1276
-    if (value_len < pfx_len)
Jakub Filak 1c1276
+    if (data_len < pfx_len)
Jakub Filak 1c1276
     {
Jakub Filak 1c1276
         error_msg("Invalid data format from journal: field data are not prefixed with field name");
Jakub Filak 1c1276
-        return -EBADMSG;
Jakub Filak 1c1276
+        return NULL;
Jakub Filak 1c1276
     }
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-    *value += pfx_len;
Jakub Filak 1c1276
-    return 0;
Jakub Filak 1c1276
+    const size_t len = data_len - pfx_len;
Jakub Filak 1c1276
+    if (value == NULL)
Jakub Filak 1c1276
+        return xstrndup(data + pfx_len, len);
Jakub Filak 1c1276
+    /*else*/
Jakub Filak 1c1276
+
Jakub Filak 1c1276
+    strncpy(value, data + pfx_len, len);
Jakub Filak 1c1276
+    /* journal data are not NULL terminated strings, so terminate the string */
Jakub Filak 1c1276
+    value[len] = '\0';
Jakub Filak 1c1276
+    return value;
Jakub Filak 1c1276
 }
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-int abrt_journal_get_log_line(abrt_journal_t *journal, const char **line)
Jakub Filak 1c1276
+char *abrt_journal_get_log_line(abrt_journal_t *journal)
Jakub Filak 1c1276
 {
Jakub Filak 1c1276
-    const int r = abrt_journal_get_string_field(journal, "MESSAGE", line);
Jakub Filak 1c1276
-    if (r < 0)
Jakub Filak 1c1276
-        log_notice("Cannot read journal data. Exiting");
Jakub Filak 1c1276
-
Jakub Filak 1c1276
-    return r;
Jakub Filak 1c1276
+    return abrt_journal_get_string_field(journal, "MESSAGE", NULL);
Jakub Filak 1c1276
 }
Jakub Filak 1c1276
 
Jakub Filak 1c1276
 int abrt_journal_get_cursor(abrt_journal_t *journal, char **cursor)
Jakub Filak 1c1276
@@ -272,9 +283,9 @@ void abrt_journal_watch_notify_strings(abrt_journal_watch_t *watch, void *data)
Jakub Filak 1c1276
 {
Jakub Filak 1c1276
     struct abrt_journal_watch_notify_strings *conf = (struct abrt_journal_watch_notify_strings *)data;
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-    const char *message = NULL;
Jakub Filak 1c1276
+    char message[JOURNALD_MAX_FIELD_SIZE + 1];
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-    if (abrt_journal_get_string_field(abrt_journal_watch_get_journal(watch), "MESSAGE", &message) < 0)
Jakub Filak 1c1276
+    if (abrt_journal_get_string_field(abrt_journal_watch_get_journal(watch), "MESSAGE", (char *)message) == NULL)
Jakub Filak 1c1276
         error_msg_and_die("Cannot read journal data.");
Jakub Filak 1c1276
 
Jakub Filak 1c1276
     GList *cur = conf->strings;
Jakub Filak 1c1276
diff --git a/src/plugins/abrt-journal.h b/src/plugins/abrt-journal.h
Jakub Filak 1c1276
index 219cf60..d509d96 100644
Jakub Filak 1c1276
--- a/src/plugins/abrt-journal.h
Jakub Filak 1c1276
+++ b/src/plugins/abrt-journal.h
Jakub Filak 1c1276
@@ -40,11 +40,13 @@ int abrt_journal_get_field(abrt_journal_t *journal,
Jakub Filak 1c1276
                            const void **value,
Jakub Filak 1c1276
                            size_t *value_len);
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-int abrt_journal_get_string_field(abrt_journal_t *journal,
Jakub Filak 1c1276
+/* Returns allocated memory if value is NULL; otherwise makes copy of journald
Jakub Filak 1c1276
+ * field to memory pointed by value arg. */
Jakub Filak 1c1276
+char *abrt_journal_get_string_field(abrt_journal_t *journal,
Jakub Filak 1c1276
                                   const char *field,
Jakub Filak 1c1276
-                                  const char **value);
Jakub Filak 1c1276
+                                  char *value);
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-int abrt_journal_get_log_line(abrt_journal_t *journal, const char **line);
Jakub Filak 1c1276
+char *abrt_journal_get_log_line(abrt_journal_t *journal);
Jakub Filak 1c1276
 
Jakub Filak 1c1276
 int abrt_journal_get_cursor(abrt_journal_t *journal, char **cursor);
Jakub Filak 1c1276
 
Jakub Filak 1c1276
-- 
Jakub Filak 1c1276
2.1.0
Jakub Filak 1c1276