1From 45f051239312e43bd4f92b9339fe67c6798a0321 Mon Sep 17 00:00:00 2001 2From: Balazs Scheidler <bazsi77@gmail.com> 3Date: Sat, 20 Aug 2022 12:43:42 +0200 4Subject: [PATCH 5/8] timeutils: add tests for non-zero terminated inputs 5 6CVE: CVE-2022-38725 7 8Upstream-Status: Backport 9[https://github.com/syslog-ng/syslog-ng/commit/45f051239312e43bd4f92b9339fe67c6798a0321] 10 11Signed-off-by: Balazs Scheidler <bazsi77@gmail.com> 12 13Signed-off-by: Yogita Urade <yogita.urade@windriver.com> 14--- 15 lib/timeutils/tests/test_scan-timestamp.c | 126 +++++++++++++++++++--- 16 1 file changed, 113 insertions(+), 13 deletions(-) 17 18diff --git a/lib/timeutils/tests/test_scan-timestamp.c b/lib/timeutils/tests/test_scan-timestamp.c 19index 27b76f12d..468bbf779 100644 20--- a/lib/timeutils/tests/test_scan-timestamp.c 21+++ b/lib/timeutils/tests/test_scan-timestamp.c 22@@ -50,17 +50,21 @@ fake_time_add(time_t diff) 23 } 24 25 static gboolean 26-_parse_rfc3164(const gchar *ts, gchar isotimestamp[32]) 27+_parse_rfc3164(const gchar *ts, gint len, gchar isotimestamp[32]) 28 { 29 UnixTime stamp; 30- const guchar *data = (const guchar *) ts; 31- gint length = strlen(ts); 32+ const guchar *tsu = (const guchar *) ts; 33+ gint tsu_len = len < 0 ? strlen(ts) : len; 34 GString *result = g_string_new(""); 35 WallClockTime wct = WALL_CLOCK_TIME_INIT; 36 37- 38+ const guchar *data = tsu; 39+ gint length = tsu_len; 40 gboolean success = scan_rfc3164_timestamp(&data, &length, &wct); 41 42+ cr_assert(length >= 0); 43+ cr_assert(data == &tsu[tsu_len - length]); 44+ 45 unix_time_unset(&stamp); 46 convert_wall_clock_time_to_unix_time(&wct, &stamp); 47 48@@ -71,16 +75,21 @@ _parse_rfc3164(const gchar *ts, gchar isotimestamp[32]) 49 } 50 51 static gboolean 52-_parse_rfc5424(const gchar *ts, gchar isotimestamp[32]) 53+_parse_rfc5424(const gchar *ts, gint len, gchar isotimestamp[32]) 54 { 55 UnixTime stamp; 56- const guchar *data = (const guchar *) ts; 57- gint length = strlen(ts); 58+ const guchar *tsu = (const guchar *) ts; 59+ gint tsu_len = len < 0 ? strlen(ts) : len; 60 GString *result = g_string_new(""); 61 WallClockTime wct = WALL_CLOCK_TIME_INIT; 62 63+ const guchar *data = tsu; 64+ gint length = tsu_len; 65 gboolean success = scan_rfc5424_timestamp(&data, &length, &wct); 66 67+ cr_assert(length >= 0); 68+ cr_assert(data == &tsu[tsu_len - length]); 69+ 70 unix_time_unset(&stamp); 71 convert_wall_clock_time_to_unix_time(&wct, &stamp); 72 73@@ -91,31 +100,60 @@ _parse_rfc5424(const gchar *ts, gchar isotimestamp[32]) 74 } 75 76 static gboolean 77-_rfc3164_timestamp_eq(const gchar *ts, const gchar *expected, gchar converted[32]) 78+_rfc3164_timestamp_eq(const gchar *ts, gint len, const gchar *expected, gchar converted[32]) 79 { 80- cr_assert(_parse_rfc3164(ts, converted)); 81+ cr_assert(_parse_rfc3164(ts, len, converted)); 82 return strcmp(converted, expected) == 0; 83 } 84 85 static gboolean 86-_rfc5424_timestamp_eq(const gchar *ts, const gchar *expected, gchar converted[32]) 87+_rfc5424_timestamp_eq(const gchar *ts, gint len, const gchar *expected, gchar converted[32]) 88 { 89- cr_assert(_parse_rfc5424(ts, converted)); 90+ cr_assert(_parse_rfc5424(ts, len, converted)); 91 return strcmp(converted, expected) == 0; 92 } 93 94 #define _expect_rfc3164_timestamp_eq(ts, expected) \ 95 ({ \ 96 gchar converted[32]; \ 97- cr_expect(_rfc3164_timestamp_eq(ts, expected, converted), "Parsed RFC3164 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \ 98+ 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); \ 99+ }) 100+ 101+#define _expect_rfc3164_timestamp_len_eq(ts, len, expected) \ 102+ ({ \ 103+ gchar converted[32]; \ 104+ 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); \ 105+ }) 106+ 107+#define _expect_rfc3164_fails(ts, len) \ 108+ ({ \ 109+ WallClockTime wct = WALL_CLOCK_TIME_INIT; \ 110+ const guchar *data = (guchar *) ts; \ 111+ gint length = len < 0 ? strlen(ts) : len; \ 112+ cr_assert_not(scan_rfc3164_timestamp(&data, &length, &wct)); \ 113 }) 114 115 #define _expect_rfc5424_timestamp_eq(ts, expected) \ 116 ({ \ 117 gchar converted[32]; \ 118- cr_expect(_rfc5424_timestamp_eq(ts, expected, converted), "Parsed RFC5424 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \ 119+ 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); \ 120+ }) 121+ 122+#define _expect_rfc5424_timestamp_len_eq(ts, len, expected) \ 123+ ({ \ 124+ gchar converted[32]; \ 125+ 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); \ 126+ }) 127+ 128+#define _expect_rfc5424_fails(ts, len) \ 129+ ({ \ 130+ WallClockTime wct = WALL_CLOCK_TIME_INIT; \ 131+ const guchar *data = (guchar *) ts; \ 132+ gint length = len < 0 ? strlen(ts) : len; \ 133+ cr_assert_not(scan_rfc5424_timestamp(&data, &length, &wct)); \ 134 }) 135 136+ 137 Test(parse_timestamp, standard_bsd_format) 138 { 139 _expect_rfc3164_timestamp_eq("Oct 1 17:46:12", "2017-10-01T17:46:12.000+02:00"); 140@@ -164,6 +202,68 @@ Test(parse_timestamp, standard_bsd_format_year_in_the_past) 141 _expect_rfc3164_timestamp_eq("Dec 31 17:46:12", "2017-12-31T17:46:12.000+01:00"); 142 } 143 144+Test(parse_timestamp, non_zero_terminated_rfc3164_iso_input_is_handled_properly) 145+{ 146+ gchar *ts = "2022-08-17T05:02:28.417Z whatever"; 147+ gint ts_len = 24; 148+ 149+ _expect_rfc3164_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.417+00:00"); 150+ _expect_rfc3164_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.417+00:00"); 151+ _expect_rfc3164_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.417+00:00"); 152+ 153+ /* no "Z" parsed, timezone defaults to local, forced CET */ 154+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 1, "2022-08-17T05:02:28.417+02:00"); 155+ 156+ /* msec is partially parsed as we trim the string from the right */ 157+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 2, "2022-08-17T05:02:28.410+02:00"); 158+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 3, "2022-08-17T05:02:28.400+02:00"); 159+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 4, "2022-08-17T05:02:28.000+02:00"); 160+ _expect_rfc3164_timestamp_len_eq(ts, ts_len - 5, "2022-08-17T05:02:28.000+02:00"); 161+ 162+ for (gint i = 6; i < ts_len; i++) 163+ _expect_rfc3164_fails(ts, ts_len - i); 164+ 165+} 166+ 167+Test(parse_timestamp, non_zero_terminated_rfc3164_bsd_pix_or_asa_input_is_handled_properly) 168+{ 169+ gchar *ts = "Aug 17 2022 05:02:28: whatever"; 170+ gint ts_len = 21; 171+ 172+ _expect_rfc3164_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.000+02:00"); 173+ _expect_rfc3164_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.000+02:00"); 174+ _expect_rfc3164_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.000+02:00"); 175+ 176+ /* no ":" at the end, that's a problem, unrecognized */ 177+ _expect_rfc3164_fails(ts, ts_len - 1); 178+ 179+ for (gint i = 1; i < ts_len; i++) 180+ _expect_rfc3164_fails(ts, ts_len - i); 181+} 182+ 183+Test(parse_timestamp, non_zero_terminated_rfc5424_input_is_handled_properly) 184+{ 185+ gchar *ts = "2022-08-17T05:02:28.417Z whatever"; 186+ gint ts_len = 24; 187+ 188+ _expect_rfc5424_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.417+00:00"); 189+ _expect_rfc5424_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.417+00:00"); 190+ _expect_rfc5424_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.417+00:00"); 191+ 192+ /* no "Z" parsed, timezone defaults to local, forced CET */ 193+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 1, "2022-08-17T05:02:28.417+02:00"); 194+ 195+ /* msec is partially parsed as we trim the string from the right */ 196+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 2, "2022-08-17T05:02:28.410+02:00"); 197+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 3, "2022-08-17T05:02:28.400+02:00"); 198+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 4, "2022-08-17T05:02:28.000+02:00"); 199+ _expect_rfc5424_timestamp_len_eq(ts, ts_len - 5, "2022-08-17T05:02:28.000+02:00"); 200+ 201+ for (gint i = 6; i < ts_len; i++) 202+ _expect_rfc5424_fails(ts, ts_len - i); 203+ 204+} 205+ 206 207 Test(parse_timestamp, daylight_saving_behavior_at_spring_with_explicit_timezones) 208 { 209-- 2102.34.1 211 212