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