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