]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
logger: make sure structured data are escaped
authorKarel Zak <kzak@redhat.com>
Mon, 2 May 2022 13:30:26 +0000 (15:30 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 2 May 2022 13:30:26 +0000 (15:30 +0200)
For the option --sd-param all formatting chars (" \ and ]) has to be
escaped by \. This patch also allow escape [ to make it more user
friendly.

For example

$ logger --rfc5424 --sd-id zoo@123 --sd-param 'foo="b\"A\"r"' --no-act --stderr "this is message"
<13>1 2022-05-02T15:35:00.342141+02:00 ws.net.home kzak - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="45291"][zoo@123 foo="b\"A\"r"] this is message

Reported-by: Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/logger.c

index 50ae211056a953820384e8e97cfe1f41707dded5..bec684f15b7862cdc8f0c7629f5d110569bc82bf 100644 (file)
@@ -684,13 +684,37 @@ static char *get_structured_data_string(struct logger_ctl *ctl)
 
 static int valid_structured_data_param(const char *str)
 {
+       char *s;
        char *eq  = strchr(str, '='),
             *qm1 = strchr(str, '"'),
-            *qm2 = qm1 ? strchr(qm1 + 1, '"') : NULL;
+            *qm2 = qm1 ? ul_strchr_escaped(qm1 + 1, '"') : NULL;
 
-       if (!eq || !qm1 || !qm2)                /* something is missing */
+       /* something is missing */
+       if (!eq || !qm1 || !qm2)
                return 0;
 
+       /* ']' need to be escaped */
+       for (s = qm1 + 1; s && *s; ) {
+               char *p = strchr(s, ']');
+               if (!p)
+                       break;
+               if (p > qm2 || p == ul_strchr_escaped(s, ']'))
+                       return 0;
+               s = p + 1;
+       }
+
+       /* '\' is allowed only before '[]"\' chars */
+       for (s = qm1 + 1; s && *s; ) {
+               char *p = strchr(s, '\\');
+               if (!p)
+                       break;
+               if (!strchr("[]\"\\", *(p + 1)))
+                       return 0;
+               s = p + 1;
+               if (*s == '\\')
+                       s++;
+       }
+
        /* foo="bar" */
        return eq > str && eq < qm1 && eq + 1 == qm1 && qm1 < qm2 && *(qm2 + 1) == '\0';
 }