Blame 0021-journal-oops-use-the-length-result-of-sd_journal_get.patch

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