syslog: fix segfault in syslog_parse_priority()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 8 Aug 2018 09:27:15 +0000 (18:27 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 8 Aug 2018 09:27:15 +0000 (18:27 +0900)
src/basic/syslog-util.c
src/journal/test-journal-syslog.c

index 21461fa..fe12948 100644 (file)
@@ -10,7 +10,8 @@
 
 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
         int a = 0, b = 0, c = 0;
-        int k;
+        const char *end;
+        size_t k;
 
         assert(p);
         assert(*p);
@@ -19,21 +20,22 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
         if ((*p)[0] != '<')
                 return 0;
 
-        if (!strchr(*p, '>'))
+        end = strchr(*p, '>');
+        if (!end)
                 return 0;
 
-        if ((*p)[2] == '>') {
+        k = end - *p;
+        assert(k > 0);
+
+        if (k == 2)
                 c = undecchar((*p)[1]);
-                k = 3;
-        } else if ((*p)[3] == '>') {
+        else if (k == 3) {
                 b = undecchar((*p)[1]);
                 c = undecchar((*p)[2]);
-                k = 4;
-        } else if ((*p)[4] == '>') {
+        } else if (k == 4) {
                 a = undecchar((*p)[1]);
                 b = undecchar((*p)[2]);
                 c = undecchar((*p)[3]);
-                k = 5;
         } else
                 return 0;
 
@@ -46,7 +48,7 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
         else
                 *priority = (*priority & LOG_FACMASK) | c;
 
-        *p += k;
+        *p += k + 1;
         return 1;
 }
 
index 05f7598..07b6cea 100644 (file)
@@ -4,6 +4,7 @@
 #include "journald-syslog.h"
 #include "macro.h"
 #include "string-util.h"
+#include "syslog-util.h"
 
 static void test_syslog_parse_identifier(const char *str,
                                          const char *ident, const char *pid, int ret) {
@@ -18,6 +19,17 @@ static void test_syslog_parse_identifier(const char *str,
         assert_se(pid == pid2 || streq_ptr(pid, pid2));
 }
 
+static void test_syslog_parse_priority(const char *str, int priority, int ret) {
+        const char *buf = str;
+        int priority2, ret2;
+
+        ret2 = syslog_parse_priority(&buf, &priority2, false);
+
+        assert_se(ret == ret2);
+        if (ret2 == 1)
+                assert_se(priority == priority2);
+}
+
 int main(void) {
         test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11);
         test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6);
@@ -29,5 +41,13 @@ int main(void) {
         test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6);
         test_syslog_parse_identifier("pidu : ", NULL, NULL, 0);
 
+        test_syslog_parse_priority("<>", 0, 0);
+        test_syslog_parse_priority("<>aaa", 0, 0);
+        test_syslog_parse_priority("<aaaa>", 0, 0);
+        test_syslog_parse_priority("<aaaa>aaa", 0, 0);
+        test_syslog_parse_priority(" <aaaa>", 0, 0);
+        test_syslog_parse_priority(" <aaaa>aaa", 0, 0);
+        /* TODO: add test cases of valid priorities */
+
         return 0;
 }