2025-05-10 21:58:58 +08:00

212 lines
8.1 KiB
Diff

From 45f051239312e43bd4f92b9339fe67c6798a0321 Mon Sep 17 00:00:00 2001
From: Balazs Scheidler <bazsi77@gmail.com>
Date: Sat, 20 Aug 2022 12:43:42 +0200
Subject: [PATCH 5/8] timeutils: add tests for non-zero terminated inputs
CVE: CVE-2022-38725
Upstream-Status: Backport
[https://github.com/syslog-ng/syslog-ng/commit/45f051239312e43bd4f92b9339fe67c6798a0321]
Signed-off-by: Balazs Scheidler <bazsi77@gmail.com>
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
lib/timeutils/tests/test_scan-timestamp.c | 126 +++++++++++++++++++---
1 file changed, 113 insertions(+), 13 deletions(-)
diff --git a/lib/timeutils/tests/test_scan-timestamp.c b/lib/timeutils/tests/test_scan-timestamp.c
index 27b76f12d..468bbf779 100644
--- a/lib/timeutils/tests/test_scan-timestamp.c
+++ b/lib/timeutils/tests/test_scan-timestamp.c
@@ -50,17 +50,21 @@ fake_time_add(time_t diff)
}
static gboolean
-_parse_rfc3164(const gchar *ts, gchar isotimestamp[32])
+_parse_rfc3164(const gchar *ts, gint len, gchar isotimestamp[32])
{
UnixTime stamp;
- const guchar *data = (const guchar *) ts;
- gint length = strlen(ts);
+ const guchar *tsu = (const guchar *) ts;
+ gint tsu_len = len < 0 ? strlen(ts) : len;
GString *result = g_string_new("");
WallClockTime wct = WALL_CLOCK_TIME_INIT;
-
+ const guchar *data = tsu;
+ gint length = tsu_len;
gboolean success = scan_rfc3164_timestamp(&data, &length, &wct);
+ cr_assert(length >= 0);
+ cr_assert(data == &tsu[tsu_len - length]);
+
unix_time_unset(&stamp);
convert_wall_clock_time_to_unix_time(&wct, &stamp);
@@ -71,16 +75,21 @@ _parse_rfc3164(const gchar *ts, gchar isotimestamp[32])
}
static gboolean
-_parse_rfc5424(const gchar *ts, gchar isotimestamp[32])
+_parse_rfc5424(const gchar *ts, gint len, gchar isotimestamp[32])
{
UnixTime stamp;
- const guchar *data = (const guchar *) ts;
- gint length = strlen(ts);
+ const guchar *tsu = (const guchar *) ts;
+ gint tsu_len = len < 0 ? strlen(ts) : len;
GString *result = g_string_new("");
WallClockTime wct = WALL_CLOCK_TIME_INIT;
+ const guchar *data = tsu;
+ gint length = tsu_len;
gboolean success = scan_rfc5424_timestamp(&data, &length, &wct);
+ cr_assert(length >= 0);
+ cr_assert(data == &tsu[tsu_len - length]);
+
unix_time_unset(&stamp);
convert_wall_clock_time_to_unix_time(&wct, &stamp);
@@ -91,31 +100,60 @@ _parse_rfc5424(const gchar *ts, gchar isotimestamp[32])
}
static gboolean
-_rfc3164_timestamp_eq(const gchar *ts, const gchar *expected, gchar converted[32])
+_rfc3164_timestamp_eq(const gchar *ts, gint len, const gchar *expected, gchar converted[32])
{
- cr_assert(_parse_rfc3164(ts, converted));
+ cr_assert(_parse_rfc3164(ts, len, converted));
return strcmp(converted, expected) == 0;
}
static gboolean
-_rfc5424_timestamp_eq(const gchar *ts, const gchar *expected, gchar converted[32])
+_rfc5424_timestamp_eq(const gchar *ts, gint len, const gchar *expected, gchar converted[32])
{
- cr_assert(_parse_rfc5424(ts, converted));
+ cr_assert(_parse_rfc5424(ts, len, converted));
return strcmp(converted, expected) == 0;
}
#define _expect_rfc3164_timestamp_eq(ts, expected) \
({ \
gchar converted[32]; \
- cr_expect(_rfc3164_timestamp_eq(ts, expected, converted), "Parsed RFC3164 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \
+ cr_expect(_rfc3164_timestamp_eq(ts, -1, expected, converted), "Parsed RFC3164 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \
+ })
+
+#define _expect_rfc3164_timestamp_len_eq(ts, len, expected) \
+ ({ \
+ gchar converted[32]; \
+ cr_expect(_rfc3164_timestamp_eq(ts, len, expected, converted), "Parsed RFC3164 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \
+ })
+
+#define _expect_rfc3164_fails(ts, len) \
+ ({ \
+ WallClockTime wct = WALL_CLOCK_TIME_INIT; \
+ const guchar *data = (guchar *) ts; \
+ gint length = len < 0 ? strlen(ts) : len; \
+ cr_assert_not(scan_rfc3164_timestamp(&data, &length, &wct)); \
})
#define _expect_rfc5424_timestamp_eq(ts, expected) \
({ \
gchar converted[32]; \
- cr_expect(_rfc5424_timestamp_eq(ts, expected, converted), "Parsed RFC5424 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \
+ cr_expect(_rfc5424_timestamp_eq(ts, -1, expected, converted), "Parsed RFC5424 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \
+ })
+
+#define _expect_rfc5424_timestamp_len_eq(ts, len, expected) \
+ ({ \
+ gchar converted[32]; \
+ cr_expect(_rfc5424_timestamp_eq(ts, len, expected, converted), "Parsed RFC5424 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \
+ })
+
+#define _expect_rfc5424_fails(ts, len) \
+ ({ \
+ WallClockTime wct = WALL_CLOCK_TIME_INIT; \
+ const guchar *data = (guchar *) ts; \
+ gint length = len < 0 ? strlen(ts) : len; \
+ cr_assert_not(scan_rfc5424_timestamp(&data, &length, &wct)); \
})
+
Test(parse_timestamp, standard_bsd_format)
{
_expect_rfc3164_timestamp_eq("Oct 1 17:46:12", "2017-10-01T17:46:12.000+02:00");
@@ -164,6 +202,68 @@ Test(parse_timestamp, standard_bsd_format_year_in_the_past)
_expect_rfc3164_timestamp_eq("Dec 31 17:46:12", "2017-12-31T17:46:12.000+01:00");
}
+Test(parse_timestamp, non_zero_terminated_rfc3164_iso_input_is_handled_properly)
+{
+ gchar *ts = "2022-08-17T05:02:28.417Z whatever";
+ gint ts_len = 24;
+
+ _expect_rfc3164_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.417+00:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.417+00:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.417+00:00");
+
+ /* no "Z" parsed, timezone defaults to local, forced CET */
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 1, "2022-08-17T05:02:28.417+02:00");
+
+ /* msec is partially parsed as we trim the string from the right */
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 2, "2022-08-17T05:02:28.410+02:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 3, "2022-08-17T05:02:28.400+02:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 4, "2022-08-17T05:02:28.000+02:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 5, "2022-08-17T05:02:28.000+02:00");
+
+ for (gint i = 6; i < ts_len; i++)
+ _expect_rfc3164_fails(ts, ts_len - i);
+
+}
+
+Test(parse_timestamp, non_zero_terminated_rfc3164_bsd_pix_or_asa_input_is_handled_properly)
+{
+ gchar *ts = "Aug 17 2022 05:02:28: whatever";
+ gint ts_len = 21;
+
+ _expect_rfc3164_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.000+02:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.000+02:00");
+ _expect_rfc3164_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.000+02:00");
+
+ /* no ":" at the end, that's a problem, unrecognized */
+ _expect_rfc3164_fails(ts, ts_len - 1);
+
+ for (gint i = 1; i < ts_len; i++)
+ _expect_rfc3164_fails(ts, ts_len - i);
+}
+
+Test(parse_timestamp, non_zero_terminated_rfc5424_input_is_handled_properly)
+{
+ gchar *ts = "2022-08-17T05:02:28.417Z whatever";
+ gint ts_len = 24;
+
+ _expect_rfc5424_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.417+00:00");
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.417+00:00");
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.417+00:00");
+
+ /* no "Z" parsed, timezone defaults to local, forced CET */
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 1, "2022-08-17T05:02:28.417+02:00");
+
+ /* msec is partially parsed as we trim the string from the right */
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 2, "2022-08-17T05:02:28.410+02:00");
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 3, "2022-08-17T05:02:28.400+02:00");
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 4, "2022-08-17T05:02:28.000+02:00");
+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 5, "2022-08-17T05:02:28.000+02:00");
+
+ for (gint i = 6; i < ts_len; i++)
+ _expect_rfc5424_fails(ts, ts_len - i);
+
+}
+
Test(parse_timestamp, daylight_saving_behavior_at_spring_with_explicit_timezones)
{
--
2.34.1