diff options
author | Hitendra Prajapati <hprajapati@mvista.com> | 2023-03-31 10:17:32 +0530 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2023-04-06 07:32:11 -0400 |
commit | 94b30b7d85c5fb862b36dd66e8dca09cd940f13b (patch) | |
tree | 2bd689b953e396c4e2ecf54d76b06ced19812b9c | |
parent | f1d4acc09de9bd8e5e18f45f1e7efadece527195 (diff) | |
download | meta-openembedded-94b30b7d85c5fb862b36dd66e8dca09cd940f13b.tar.gz |
syslog-ng: CVE-2022-38725 An integer overflow in the RFC3164 parser
Upstream-Status: Backport from https://github.com/syslog-ng/syslog-ng/commit/b5a060f2ebb8d794f508436a12e4d4163f94b1b8 && https://github.com/syslog-ng/syslog-ng/commit/81a07263f1e522a376d3a30f96f51df3f2879f8a && https://github.com/syslog-ng/syslog-ng/commit/4b8dc56ca8eaeac4c8751a305eb7eeefab8dc89d && https://github.com/syslog-ng/syslog-ng/commit/73b5c300b8fde5e7a4824baa83a04931279abb37 && https://github.com/syslog-ng/syslog-ng/commit/45f051239312e43bd4f92b9339fe67c6798a0321 && https://github.com/syslog-ng/syslog-ng/commit/09f489c89c826293ff8cbd282cfc866ab56054c4 && https://github.com/syslog-ng/syslog-ng/commit/8c6e2c1c41b0fcc5fbd464c35f4dac7102235396 && https://github.com/syslog-ng/syslog-ng/commit/56f881c5eaa3d8c02c96607c4b9e4eaf959a044d
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r-- | meta-oe/recipes-support/syslog-ng/files/CVE-2022-38725.patch | 629 | ||||
-rw-r--r-- | meta-oe/recipes-support/syslog-ng/syslog-ng_3.24.1.bb | 1 |
2 files changed, 630 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/syslog-ng/files/CVE-2022-38725.patch b/meta-oe/recipes-support/syslog-ng/files/CVE-2022-38725.patch new file mode 100644 index 0000000000..4a09c8c7fa --- /dev/null +++ b/meta-oe/recipes-support/syslog-ng/files/CVE-2022-38725.patch | |||
@@ -0,0 +1,629 @@ | |||
1 | From 73b5c300b8fde5e7a4824baa83a04931279abb37 Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?L=C3=A1szl=C3=B3=20V=C3=A1rady?= | ||
3 | <laszlo.varady@protonmail.com> | ||
4 | Date: Sat, 20 Aug 2022 12:42:38 +0200 | ||
5 | Subject: [PATCH] CVE-2022-38725 | ||
6 | MIME-Version: 1.0 | ||
7 | Content-Type: text/plain; charset=UTF-8 | ||
8 | Content-Transfer-Encoding: 8bit | ||
9 | |||
10 | Signed-off-by: László Várady <laszlo.varady@protonmail.com> | ||
11 | Signed-off-by: Balazs Scheidler <bazsi77@gmail.com> | ||
12 | |||
13 | Upstream-Status: Backport from [https://github.com/syslog-ng/syslog-ng/commit/b5a060f2ebb8d794f508436a12e4d4163f94b1b8 && https://github.com/syslog-ng/syslog-ng/commit/81a07263f1e522a376d3a30f96f51df3f2879f8a && https://github.com/syslog-ng/syslog-ng/commit/4b8dc56ca8eaeac4c8751a305eb7eeefab8dc89d && https://github.com/syslog-ng/syslog-ng/commit/73b5c300b8fde5e7a4824baa83a04931279abb37 && https://github.com/syslog-ng/syslog-ng/commit/45f051239312e43bd4f92b9339fe67c6798a0321 && https://github.com/syslog-ng/syslog-ng/commit/09f489c89c826293ff8cbd282cfc866ab56054c4 && https://github.com/syslog-ng/syslog-ng/commit/8c6e2c1c41b0fcc5fbd464c35f4dac7102235396 && https://github.com/syslog-ng/syslog-ng/commit/56f881c5eaa3d8c02c96607c4b9e4eaf959a044d] | ||
14 | CVE: CVE-2022-38725 | ||
15 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
16 | --- | ||
17 | lib/timeutils/scan-timestamp.c | 68 +++++---- | ||
18 | lib/timeutils/tests/test_scan-timestamp.c | 133 ++++++++++++++++-- | ||
19 | modules/syslogformat/CMakeLists.txt | 2 + | ||
20 | modules/syslogformat/Makefile.am | 2 + | ||
21 | modules/syslogformat/syslog-format.c | 12 +- | ||
22 | modules/syslogformat/tests/CMakeLists.txt | 1 + | ||
23 | modules/syslogformat/tests/Makefile.am | 9 ++ | ||
24 | .../syslogformat/tests/test_syslog_format.c | 104 ++++++++++++++ | ||
25 | 8 files changed, 284 insertions(+), 47 deletions(-) | ||
26 | create mode 100644 modules/syslogformat/tests/CMakeLists.txt | ||
27 | create mode 100644 modules/syslogformat/tests/Makefile.am | ||
28 | create mode 100644 modules/syslogformat/tests/test_syslog_format.c | ||
29 | |||
30 | diff --git a/lib/timeutils/scan-timestamp.c b/lib/timeutils/scan-timestamp.c | ||
31 | index 41ead1a..ec9746b 100644 | ||
32 | --- a/lib/timeutils/scan-timestamp.c | ||
33 | +++ b/lib/timeutils/scan-timestamp.c | ||
34 | @@ -34,41 +34,43 @@ scan_day_abbrev(const gchar **buf, gint *left, gint *wday) | ||
35 | { | ||
36 | *wday = -1; | ||
37 | |||
38 | - if (*left < 3) | ||
39 | + const gsize abbrev_length = 3; | ||
40 | + | ||
41 | + if (*left < abbrev_length) | ||
42 | return FALSE; | ||
43 | |||
44 | switch (**buf) | ||
45 | { | ||
46 | case 'S': | ||
47 | - if (strncasecmp(*buf, "Sun", 3) == 0) | ||
48 | + if (strncasecmp(*buf, "Sun", abbrev_length) == 0) | ||
49 | *wday = 0; | ||
50 | - else if (strncasecmp(*buf, "Sat", 3) == 0) | ||
51 | + else if (strncasecmp(*buf, "Sat", abbrev_length) == 0) | ||
52 | *wday = 6; | ||
53 | break; | ||
54 | case 'M': | ||
55 | - if (strncasecmp(*buf, "Mon", 3) == 0) | ||
56 | + if (strncasecmp(*buf, "Mon", abbrev_length) == 0) | ||
57 | *wday = 1; | ||
58 | break; | ||
59 | case 'T': | ||
60 | - if (strncasecmp(*buf, "Tue", 3) == 0) | ||
61 | + if (strncasecmp(*buf, "Tue", abbrev_length) == 0) | ||
62 | *wday = 2; | ||
63 | - else if (strncasecmp(*buf, "Thu", 3) == 0) | ||
64 | + else if (strncasecmp(*buf, "Thu", abbrev_length) == 0) | ||
65 | *wday = 4; | ||
66 | break; | ||
67 | case 'W': | ||
68 | - if (strncasecmp(*buf, "Wed", 3) == 0) | ||
69 | + if (strncasecmp(*buf, "Wed", abbrev_length) == 0) | ||
70 | *wday = 3; | ||
71 | break; | ||
72 | case 'F': | ||
73 | - if (strncasecmp(*buf, "Fri", 3) == 0) | ||
74 | + if (strncasecmp(*buf, "Fri", abbrev_length) == 0) | ||
75 | *wday = 5; | ||
76 | break; | ||
77 | default: | ||
78 | return FALSE; | ||
79 | } | ||
80 | |||
81 | - (*buf) += 3; | ||
82 | - (*left) -= 3; | ||
83 | + (*buf) += abbrev_length; | ||
84 | + (*left) -= abbrev_length; | ||
85 | return TRUE; | ||
86 | } | ||
87 | |||
88 | @@ -77,57 +79,59 @@ scan_month_abbrev(const gchar **buf, gint *left, gint *mon) | ||
89 | { | ||
90 | *mon = -1; | ||
91 | |||
92 | - if (*left < 3) | ||
93 | + const gsize abbrev_length = 3; | ||
94 | + | ||
95 | + if (*left < abbrev_length) | ||
96 | return FALSE; | ||
97 | |||
98 | switch (**buf) | ||
99 | { | ||
100 | case 'J': | ||
101 | - if (strncasecmp(*buf, "Jan", 3) == 0) | ||
102 | + if (strncasecmp(*buf, "Jan", abbrev_length) == 0) | ||
103 | *mon = 0; | ||
104 | - else if (strncasecmp(*buf, "Jun", 3) == 0) | ||
105 | + else if (strncasecmp(*buf, "Jun", abbrev_length) == 0) | ||
106 | *mon = 5; | ||
107 | - else if (strncasecmp(*buf, "Jul", 3) == 0) | ||
108 | + else if (strncasecmp(*buf, "Jul", abbrev_length) == 0) | ||
109 | *mon = 6; | ||
110 | break; | ||
111 | case 'F': | ||
112 | - if (strncasecmp(*buf, "Feb", 3) == 0) | ||
113 | + if (strncasecmp(*buf, "Feb", abbrev_length) == 0) | ||
114 | *mon = 1; | ||
115 | break; | ||
116 | case 'M': | ||
117 | - if (strncasecmp(*buf, "Mar", 3) == 0) | ||
118 | + if (strncasecmp(*buf, "Mar", abbrev_length) == 0) | ||
119 | *mon = 2; | ||
120 | - else if (strncasecmp(*buf, "May", 3) == 0) | ||
121 | + else if (strncasecmp(*buf, "May", abbrev_length) == 0) | ||
122 | *mon = 4; | ||
123 | break; | ||
124 | case 'A': | ||
125 | - if (strncasecmp(*buf, "Apr", 3) == 0) | ||
126 | + if (strncasecmp(*buf, "Apr", abbrev_length) == 0) | ||
127 | *mon = 3; | ||
128 | - else if (strncasecmp(*buf, "Aug", 3) == 0) | ||
129 | + else if (strncasecmp(*buf, "Aug", abbrev_length) == 0) | ||
130 | *mon = 7; | ||
131 | break; | ||
132 | case 'S': | ||
133 | - if (strncasecmp(*buf, "Sep", 3) == 0) | ||
134 | + if (strncasecmp(*buf, "Sep", abbrev_length) == 0) | ||
135 | *mon = 8; | ||
136 | break; | ||
137 | case 'O': | ||
138 | - if (strncasecmp(*buf, "Oct", 3) == 0) | ||
139 | + if (strncasecmp(*buf, "Oct", abbrev_length) == 0) | ||
140 | *mon = 9; | ||
141 | break; | ||
142 | case 'N': | ||
143 | - if (strncasecmp(*buf, "Nov", 3) == 0) | ||
144 | + if (strncasecmp(*buf, "Nov", abbrev_length) == 0) | ||
145 | *mon = 10; | ||
146 | break; | ||
147 | case 'D': | ||
148 | - if (strncasecmp(*buf, "Dec", 3) == 0) | ||
149 | + if (strncasecmp(*buf, "Dec", abbrev_length) == 0) | ||
150 | *mon = 11; | ||
151 | break; | ||
152 | default: | ||
153 | return FALSE; | ||
154 | } | ||
155 | |||
156 | - (*buf) += 3; | ||
157 | - (*left) -= 3; | ||
158 | + (*buf) += abbrev_length; | ||
159 | + (*left) -= abbrev_length; | ||
160 | return TRUE; | ||
161 | } | ||
162 | |||
163 | @@ -302,7 +306,7 @@ __parse_usec(const guchar **data, gint *length) | ||
164 | src++; | ||
165 | (*length)--; | ||
166 | } | ||
167 | - while (isdigit(*src)) | ||
168 | + while (*length > 0 && isdigit(*src)) | ||
169 | { | ||
170 | src++; | ||
171 | (*length)--; | ||
172 | @@ -316,19 +320,21 @@ __parse_usec(const guchar **data, gint *length) | ||
173 | static gboolean | ||
174 | __has_iso_timezone(const guchar *src, gint length) | ||
175 | { | ||
176 | - return (length >= 5) && | ||
177 | + return (length >= 6) && | ||
178 | (*src == '+' || *src == '-') && | ||
179 | isdigit(*(src+1)) && | ||
180 | isdigit(*(src+2)) && | ||
181 | *(src+3) == ':' && | ||
182 | isdigit(*(src+4)) && | ||
183 | isdigit(*(src+5)) && | ||
184 | - !isdigit(*(src+6)); | ||
185 | + (length < 7 || !isdigit(*(src+6))); | ||
186 | } | ||
187 | |||
188 | static guint32 | ||
189 | __parse_iso_timezone(const guchar **data, gint *length) | ||
190 | { | ||
191 | + g_assert(*length >= 6); | ||
192 | + | ||
193 | gint hours, mins; | ||
194 | const guchar *src = *data; | ||
195 | guint32 tz = 0; | ||
196 | @@ -338,8 +344,10 @@ __parse_iso_timezone(const guchar **data, gint *length) | ||
197 | hours = (*(src + 1) - '0') * 10 + *(src + 2) - '0'; | ||
198 | mins = (*(src + 4) - '0') * 10 + *(src + 5) - '0'; | ||
199 | tz = sign * (hours * 3600 + mins * 60); | ||
200 | + | ||
201 | src += 6; | ||
202 | (*length) -= 6; | ||
203 | + | ||
204 | *data = src; | ||
205 | return tz; | ||
206 | } | ||
207 | @@ -393,7 +401,7 @@ __parse_bsd_timestamp(const guchar **data, gint *length, WallClockTime *wct) | ||
208 | if (!scan_pix_timestamp((const gchar **) &src, &left, wct)) | ||
209 | return FALSE; | ||
210 | |||
211 | - if (*src == ':') | ||
212 | + if (left && *src == ':') | ||
213 | { | ||
214 | src++; | ||
215 | left--; | ||
216 | @@ -444,7 +452,7 @@ scan_rfc3164_timestamp(const guchar **data, gint *length, WallClockTime *wct) | ||
217 | * looking at you, skip that as well, so we can reliably detect IPv6 | ||
218 | * addresses as hostnames, which would be using ":" as well. */ | ||
219 | |||
220 | - if (*src == ':') | ||
221 | + if (left && *src == ':') | ||
222 | { | ||
223 | ++src; | ||
224 | --left; | ||
225 | diff --git a/lib/timeutils/tests/test_scan-timestamp.c b/lib/timeutils/tests/test_scan-timestamp.c | ||
226 | index 4508139..ad657c6 100644 | ||
227 | --- a/lib/timeutils/tests/test_scan-timestamp.c | ||
228 | +++ b/lib/timeutils/tests/test_scan-timestamp.c | ||
229 | @@ -49,17 +49,21 @@ fake_time_add(time_t diff) | ||
230 | } | ||
231 | |||
232 | static gboolean | ||
233 | -_parse_rfc3164(const gchar *ts, gchar isotimestamp[32]) | ||
234 | +_parse_rfc3164(const gchar *ts, gint len, gchar isotimestamp[32]) | ||
235 | { | ||
236 | UnixTime stamp; | ||
237 | - const guchar *data = (const guchar *) ts; | ||
238 | - gint length = strlen(ts); | ||
239 | + const guchar *tsu = (const guchar *) ts; | ||
240 | + gint tsu_len = len < 0 ? strlen(ts) : len; | ||
241 | GString *result = g_string_new(""); | ||
242 | WallClockTime wct = WALL_CLOCK_TIME_INIT; | ||
243 | |||
244 | - | ||
245 | + const guchar *data = tsu; | ||
246 | + gint length = tsu_len; | ||
247 | gboolean success = scan_rfc3164_timestamp(&data, &length, &wct); | ||
248 | |||
249 | + cr_assert(length >= 0); | ||
250 | + cr_assert(data == &tsu[tsu_len - length]); | ||
251 | + | ||
252 | unix_time_unset(&stamp); | ||
253 | convert_wall_clock_time_to_unix_time(&wct, &stamp); | ||
254 | |||
255 | @@ -70,16 +74,21 @@ _parse_rfc3164(const gchar *ts, gchar isotimestamp[32]) | ||
256 | } | ||
257 | |||
258 | static gboolean | ||
259 | -_parse_rfc5424(const gchar *ts, gchar isotimestamp[32]) | ||
260 | +_parse_rfc5424(const gchar *ts, gint len, gchar isotimestamp[32]) | ||
261 | { | ||
262 | UnixTime stamp; | ||
263 | - const guchar *data = (const guchar *) ts; | ||
264 | - gint length = strlen(ts); | ||
265 | + const guchar *tsu = (const guchar *) ts; | ||
266 | + gint tsu_len = len < 0 ? strlen(ts) : len; | ||
267 | GString *result = g_string_new(""); | ||
268 | WallClockTime wct = WALL_CLOCK_TIME_INIT; | ||
269 | |||
270 | + const guchar *data = tsu; | ||
271 | + gint length = tsu_len; | ||
272 | gboolean success = scan_rfc5424_timestamp(&data, &length, &wct); | ||
273 | |||
274 | + cr_assert(length >= 0); | ||
275 | + cr_assert(data == &tsu[tsu_len - length]); | ||
276 | + | ||
277 | unix_time_unset(&stamp); | ||
278 | convert_wall_clock_time_to_unix_time(&wct, &stamp); | ||
279 | |||
280 | @@ -90,31 +99,60 @@ _parse_rfc5424(const gchar *ts, gchar isotimestamp[32]) | ||
281 | } | ||
282 | |||
283 | static gboolean | ||
284 | -_rfc3164_timestamp_eq(const gchar *ts, const gchar *expected, gchar converted[32]) | ||
285 | +_rfc3164_timestamp_eq(const gchar *ts, gint len, const gchar *expected, gchar converted[32]) | ||
286 | { | ||
287 | - cr_assert(_parse_rfc3164(ts, converted)); | ||
288 | + cr_assert(_parse_rfc3164(ts, len, converted)); | ||
289 | return strcmp(converted, expected) == 0; | ||
290 | } | ||
291 | |||
292 | static gboolean | ||
293 | -_rfc5424_timestamp_eq(const gchar *ts, const gchar *expected, gchar converted[32]) | ||
294 | +_rfc5424_timestamp_eq(const gchar *ts, gint len, const gchar *expected, gchar converted[32]) | ||
295 | { | ||
296 | - cr_assert(_parse_rfc5424(ts, converted)); | ||
297 | + cr_assert(_parse_rfc5424(ts, len, converted)); | ||
298 | return strcmp(converted, expected) == 0; | ||
299 | } | ||
300 | |||
301 | #define _expect_rfc3164_timestamp_eq(ts, expected) \ | ||
302 | ({ \ | ||
303 | gchar converted[32]; \ | ||
304 | - cr_expect(_rfc3164_timestamp_eq(ts, expected, converted), "Parsed RFC3164 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \ | ||
305 | + 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); \ | ||
306 | + }) | ||
307 | + | ||
308 | +#define _expect_rfc3164_timestamp_len_eq(ts, len, expected) \ | ||
309 | + ({ \ | ||
310 | + gchar converted[32]; \ | ||
311 | + 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); \ | ||
312 | + }) | ||
313 | + | ||
314 | +#define _expect_rfc3164_fails(ts, len) \ | ||
315 | + ({ \ | ||
316 | + WallClockTime wct = WALL_CLOCK_TIME_INIT; \ | ||
317 | + const guchar *data = (guchar *) ts; \ | ||
318 | + gint length = len < 0 ? strlen(ts) : len; \ | ||
319 | + cr_assert_not(scan_rfc3164_timestamp(&data, &length, &wct)); \ | ||
320 | }) | ||
321 | |||
322 | #define _expect_rfc5424_timestamp_eq(ts, expected) \ | ||
323 | ({ \ | ||
324 | gchar converted[32]; \ | ||
325 | - cr_expect(_rfc5424_timestamp_eq(ts, expected, converted), "Parsed RFC5424 timestamp does not equal expected, ts=%s, converted=%s, expected=%s", ts, converted, expected); \ | ||
326 | + 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); \ | ||
327 | + }) | ||
328 | + | ||
329 | +#define _expect_rfc5424_timestamp_len_eq(ts, len, expected) \ | ||
330 | + ({ \ | ||
331 | + gchar converted[32]; \ | ||
332 | + 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); \ | ||
333 | }) | ||
334 | |||
335 | +#define _expect_rfc5424_fails(ts, len) \ | ||
336 | + ({ \ | ||
337 | + WallClockTime wct = WALL_CLOCK_TIME_INIT; \ | ||
338 | + const guchar *data = (guchar *) ts; \ | ||
339 | + gint length = len < 0 ? strlen(ts) : len; \ | ||
340 | + cr_assert_not(scan_rfc5424_timestamp(&data, &length, &wct)); \ | ||
341 | + }) | ||
342 | + | ||
343 | + | ||
344 | Test(parse_timestamp, standard_bsd_format) | ||
345 | { | ||
346 | _expect_rfc3164_timestamp_eq("Oct 1 17:46:12", "2017-10-01T17:46:12.000+02:00"); | ||
347 | @@ -148,6 +186,75 @@ Test(parse_timestamp, standard_bsd_format_year_in_the_past) | ||
348 | _expect_rfc3164_timestamp_eq("Dec 31 17:46:12", "2017-12-31T17:46:12.000+01:00"); | ||
349 | } | ||
350 | |||
351 | +Test(parse_timestamp, non_zero_terminated_rfc3164_iso_input_is_handled_properly) | ||
352 | +{ | ||
353 | + gchar *ts = "2022-08-17T05:02:28.417Z whatever"; | ||
354 | + gint ts_len = 24; | ||
355 | + | ||
356 | + _expect_rfc3164_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.417+00:00"); | ||
357 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.417+00:00"); | ||
358 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.417+00:00"); | ||
359 | + | ||
360 | + /* no "Z" parsed, timezone defaults to local, forced CET */ | ||
361 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len - 1, "2022-08-17T05:02:28.417+02:00"); | ||
362 | + | ||
363 | + /* msec is partially parsed as we trim the string from the right */ | ||
364 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len - 2, "2022-08-17T05:02:28.410+02:00"); | ||
365 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len - 3, "2022-08-17T05:02:28.400+02:00"); | ||
366 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len - 4, "2022-08-17T05:02:28.000+02:00"); | ||
367 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len - 5, "2022-08-17T05:02:28.000+02:00"); | ||
368 | + | ||
369 | + for (gint i = 6; i < ts_len; i++) | ||
370 | + _expect_rfc3164_fails(ts, ts_len - i); | ||
371 | + | ||
372 | +} | ||
373 | + | ||
374 | +Test(parse_timestamp, non_zero_terminated_rfc3164_bsd_pix_or_asa_input_is_handled_properly) | ||
375 | +{ | ||
376 | + gchar *ts = "Aug 17 2022 05:02:28: whatever"; | ||
377 | + gint ts_len = 21; | ||
378 | + | ||
379 | + _expect_rfc3164_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.000+02:00"); | ||
380 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.000+02:00"); | ||
381 | + _expect_rfc3164_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.000+02:00"); | ||
382 | + | ||
383 | + /* no ":" at the end, that's a problem, unrecognized */ | ||
384 | + _expect_rfc3164_fails(ts, ts_len - 1); | ||
385 | + | ||
386 | + for (gint i = 1; i < ts_len; i++) | ||
387 | + _expect_rfc3164_fails(ts, ts_len - i); | ||
388 | +} | ||
389 | + | ||
390 | +Test(parse_timestamp, non_zero_terminated_rfc5424_input_is_handled_properly) | ||
391 | +{ | ||
392 | + gchar *ts = "2022-08-17T05:02:28.417Z whatever"; | ||
393 | + gint ts_len = 24; | ||
394 | + | ||
395 | + _expect_rfc5424_timestamp_len_eq(ts, strlen(ts), "2022-08-17T05:02:28.417+00:00"); | ||
396 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len + 5, "2022-08-17T05:02:28.417+00:00"); | ||
397 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len, "2022-08-17T05:02:28.417+00:00"); | ||
398 | + | ||
399 | + /* no "Z" parsed, timezone defaults to local, forced CET */ | ||
400 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len - 1, "2022-08-17T05:02:28.417+02:00"); | ||
401 | + | ||
402 | + /* msec is partially parsed as we trim the string from the right */ | ||
403 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len - 2, "2022-08-17T05:02:28.410+02:00"); | ||
404 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len - 3, "2022-08-17T05:02:28.400+02:00"); | ||
405 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len - 4, "2022-08-17T05:02:28.000+02:00"); | ||
406 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len - 5, "2022-08-17T05:02:28.000+02:00"); | ||
407 | + | ||
408 | + for (gint i = 6; i < ts_len; i++) | ||
409 | + _expect_rfc5424_fails(ts, ts_len - i); | ||
410 | + | ||
411 | +} | ||
412 | + | ||
413 | +Test(parse_timestamp, non_zero_terminated_rfc5424_timestamp_only) | ||
414 | +{ | ||
415 | + const gchar *ts = "2022-08-17T05:02:28.417+03:00"; | ||
416 | + gint ts_len = strlen(ts); | ||
417 | + _expect_rfc5424_timestamp_len_eq(ts, ts_len, ts); | ||
418 | +} | ||
419 | + | ||
420 | |||
421 | Test(parse_timestamp, daylight_saving_behavior_at_spring_with_explicit_timezones) | ||
422 | { | ||
423 | diff --git a/modules/syslogformat/CMakeLists.txt b/modules/syslogformat/CMakeLists.txt | ||
424 | index fb55ea4..a2a92bb 100644 | ||
425 | --- a/modules/syslogformat/CMakeLists.txt | ||
426 | +++ b/modules/syslogformat/CMakeLists.txt | ||
427 | @@ -24,4 +24,6 @@ target_include_directories(syslogformat | ||
428 | ) | ||
429 | target_link_libraries(syslogformat PRIVATE syslog-ng) | ||
430 | |||
431 | +add_test_subdirectory(tests) | ||
432 | + | ||
433 | install(TARGETS syslogformat LIBRARY DESTINATION lib/syslog-ng/) | ||
434 | diff --git a/modules/syslogformat/Makefile.am b/modules/syslogformat/Makefile.am | ||
435 | index f13f88c..14cdf58 100644 | ||
436 | --- a/modules/syslogformat/Makefile.am | ||
437 | +++ b/modules/syslogformat/Makefile.am | ||
438 | @@ -31,3 +31,5 @@ modules_syslogformat_libsyslogformat_la_DEPENDENCIES = \ | ||
439 | modules/syslogformat modules/syslogformat/ mod-syslogformat: \ | ||
440 | modules/syslogformat/libsyslogformat.la | ||
441 | .PHONY: modules/syslogformat/ mod-syslogformat | ||
442 | + | ||
443 | +include modules/syslogformat/tests/Makefile.am | ||
444 | diff --git a/modules/syslogformat/syslog-format.c b/modules/syslogformat/syslog-format.c | ||
445 | index 6d53a32..a69f39f 100644 | ||
446 | --- a/modules/syslogformat/syslog-format.c | ||
447 | +++ b/modules/syslogformat/syslog-format.c | ||
448 | @@ -200,7 +200,7 @@ log_msg_parse_cisco_sequence_id(LogMessage *self, const guchar **data, gint *len | ||
449 | |||
450 | /* if the next char is not space, then we may try to read a date */ | ||
451 | |||
452 | - if (*src != ' ') | ||
453 | + if (!left || *src != ' ') | ||
454 | return; | ||
455 | |||
456 | log_msg_set_value(self, handles.cisco_seqid, (gchar *) *data, *length - left - 1); | ||
457 | @@ -216,6 +216,9 @@ log_msg_parse_cisco_timestamp_attributes(LogMessage *self, const guchar **data, | ||
458 | const guchar *src = *data; | ||
459 | gint left = *length; | ||
460 | |||
461 | + if (!left) | ||
462 | + return; | ||
463 | + | ||
464 | /* Cisco timestamp extensions, the first '*' indicates that the clock is | ||
465 | * unsynced, '.' if it is known to be synced */ | ||
466 | if (G_UNLIKELY(src[0] == '*')) | ||
467 | @@ -564,7 +567,7 @@ log_msg_parse_sd(LogMessage *self, const guchar **data, gint *length, const MsgF | ||
468 | open_sd++; | ||
469 | do | ||
470 | { | ||
471 | - if (!isascii(*src) || *src == '=' || *src == ' ' || *src == ']' || *src == '"') | ||
472 | + if (!left || !isascii(*src) || *src == '=' || *src == ' ' || *src == ']' || *src == '"') | ||
473 | goto error; | ||
474 | /* read sd_id */ | ||
475 | pos = 0; | ||
476 | @@ -598,7 +601,8 @@ log_msg_parse_sd(LogMessage *self, const guchar **data, gint *length, const MsgF | ||
477 | strcpy(sd_value_name, logmsg_sd_prefix); | ||
478 | /* this strcat is safe, as sd_id_name is at most 32 chars */ | ||
479 | strncpy(sd_value_name + logmsg_sd_prefix_len, sd_id_name, sizeof(sd_value_name) - logmsg_sd_prefix_len); | ||
480 | - if (*src == ']') | ||
481 | + | ||
482 | + if (left && *src == ']') | ||
483 | { | ||
484 | log_msg_set_value_by_name(self, sd_value_name, "", 0); | ||
485 | } | ||
486 | @@ -615,7 +619,7 @@ log_msg_parse_sd(LogMessage *self, const guchar **data, gint *length, const MsgF | ||
487 | else | ||
488 | goto error; | ||
489 | |||
490 | - if (!isascii(*src) || *src == '=' || *src == ' ' || *src == ']' || *src == '"') | ||
491 | + if (!left || !isascii(*src) || *src == '=' || *src == ' ' || *src == ']' || *src == '"') | ||
492 | goto error; | ||
493 | |||
494 | /* read sd-param */ | ||
495 | diff --git a/modules/syslogformat/tests/CMakeLists.txt b/modules/syslogformat/tests/CMakeLists.txt | ||
496 | new file mode 100644 | ||
497 | index 0000000..2e45b71 | ||
498 | --- /dev/null | ||
499 | +++ b/modules/syslogformat/tests/CMakeLists.txt | ||
500 | @@ -0,0 +1 @@ | ||
501 | +add_unit_test(CRITERION TARGET test_syslog_format DEPENDS syslogformat) | ||
502 | diff --git a/modules/syslogformat/tests/Makefile.am b/modules/syslogformat/tests/Makefile.am | ||
503 | new file mode 100644 | ||
504 | index 0000000..7ee66a5 | ||
505 | --- /dev/null | ||
506 | +++ b/modules/syslogformat/tests/Makefile.am | ||
507 | @@ -0,0 +1,9 @@ | ||
508 | +modules_syslogformat_tests_TESTS = \ | ||
509 | + modules/syslogformat/tests/test_syslog_format | ||
510 | + | ||
511 | +check_PROGRAMS += ${modules_syslogformat_tests_TESTS} | ||
512 | + | ||
513 | +EXTRA_DIST += modules/syslogformat/tests/CMakeLists.txt | ||
514 | + | ||
515 | +modules_syslogformat_tests_test_syslog_format_CFLAGS = $(TEST_CFLAGS) -I$(top_srcdir)/modules/syslogformat | ||
516 | +modules_syslogformat_tests_test_syslog_format_LDADD = $(TEST_LDADD) $(PREOPEN_SYSLOGFORMAT) | ||
517 | diff --git a/modules/syslogformat/tests/test_syslog_format.c b/modules/syslogformat/tests/test_syslog_format.c | ||
518 | new file mode 100644 | ||
519 | index 0000000..d0f5b40 | ||
520 | --- /dev/null | ||
521 | +++ b/modules/syslogformat/tests/test_syslog_format.c | ||
522 | @@ -0,0 +1,104 @@ | ||
523 | +/* | ||
524 | + * Copyright (c) 2022 One Identity | ||
525 | + * Copyright (c) 2022 László Várady | ||
526 | + * | ||
527 | + * This program is free software; you can redistribute it and/or modify it | ||
528 | + * under the terms of the GNU General Public License version 2 as published | ||
529 | + * by the Free Software Foundation, or (at your option) any later version. | ||
530 | + * | ||
531 | + * This program is distributed in the hope that it will be useful, | ||
532 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
533 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
534 | + * GNU General Public License for more details. | ||
535 | + * | ||
536 | + * You should have received a copy of the GNU General Public License | ||
537 | + * along with this program; if not, write to the Free Software | ||
538 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
539 | + * | ||
540 | + * As an additional exemption you are allowed to compile & link against the | ||
541 | + * OpenSSL libraries as published by the OpenSSL project. See the file | ||
542 | + * COPYING for details. | ||
543 | + * | ||
544 | + */ | ||
545 | + | ||
546 | +#include <criterion/criterion.h> | ||
547 | + | ||
548 | +#include "apphook.h" | ||
549 | +#include "cfg.h" | ||
550 | +#include "syslog-format.h" | ||
551 | +#include "logmsg/logmsg.h" | ||
552 | +#include "msg-format.h" | ||
553 | +#include "scratch-buffers.h" | ||
554 | + | ||
555 | +#include <string.h> | ||
556 | + | ||
557 | +GlobalConfig *cfg; | ||
558 | +MsgFormatOptions parse_options; | ||
559 | + | ||
560 | +static void | ||
561 | +setup(void) | ||
562 | +{ | ||
563 | + app_startup(); | ||
564 | + syslog_format_init(); | ||
565 | + | ||
566 | + cfg = cfg_new_snippet(); | ||
567 | + msg_format_options_defaults(&parse_options); | ||
568 | +} | ||
569 | + | ||
570 | +static void | ||
571 | +teardown(void) | ||
572 | +{ | ||
573 | + scratch_buffers_explicit_gc(); | ||
574 | + app_shutdown(); | ||
575 | + cfg_free(cfg); | ||
576 | +} | ||
577 | + | ||
578 | +TestSuite(syslog_format, .init = setup, .fini = teardown); | ||
579 | + | ||
580 | +Test(syslog_format, parser_should_not_spin_on_non_zero_terminated_input, .timeout = 10) | ||
581 | +{ | ||
582 | + const gchar *data = "<182>2022-08-17T05:02:28.217 mymachine su: 'su root' failed for lonvick on /dev/pts/8"; | ||
583 | + /* chosen carefully to reproduce a bug */ | ||
584 | + gsize data_length = 27; | ||
585 | + | ||
586 | + msg_format_options_init(&parse_options, cfg); | ||
587 | + LogMessage *msg = msg_format_construct_message(&parse_options, (const guchar *) data, data_length); | ||
588 | + | ||
589 | + gsize problem_position; | ||
590 | + cr_assert(syslog_format_handler(&parse_options, msg, (const guchar *) data, data_length, &problem_position)); | ||
591 | + | ||
592 | + msg_format_options_destroy(&parse_options); | ||
593 | + log_msg_unref(msg); | ||
594 | +} | ||
595 | + | ||
596 | +Test(syslog_format, cisco_sequence_id_non_zero_termination) | ||
597 | +{ | ||
598 | + const gchar *data = "<189>65536: "; | ||
599 | + gsize data_length = strlen(data); | ||
600 | + | ||
601 | + msg_format_options_init(&parse_options, cfg); | ||
602 | + LogMessage *msg = msg_format_construct_message(&parse_options, (const guchar *) data, data_length); | ||
603 | + | ||
604 | + gsize problem_position; | ||
605 | + cr_assert(syslog_format_handler(&parse_options, msg, (const guchar *) data, data_length, &problem_position)); | ||
606 | + cr_assert_str_eq(log_msg_get_value_by_name(msg, ".SDATA.meta.sequenceId", NULL), "65536"); | ||
607 | + | ||
608 | + msg_format_options_destroy(&parse_options); | ||
609 | + log_msg_unref(msg); | ||
610 | +} | ||
611 | + | ||
612 | +Test(syslog_format, minimal_non_zero_terminated_numeric_message_is_parsed_as_program_name) | ||
613 | +{ | ||
614 | + const gchar *data = "<189>65536"; | ||
615 | + gsize data_length = strlen(data); | ||
616 | + | ||
617 | + msg_format_options_init(&parse_options, cfg); | ||
618 | + LogMessage *msg = msg_format_construct_message(&parse_options, (const guchar *) data, data_length); | ||
619 | + | ||
620 | + gsize problem_position; | ||
621 | + cr_assert(syslog_format_handler(&parse_options, msg, (const guchar *) data, data_length, &problem_position)); | ||
622 | + cr_assert_str_eq(log_msg_get_value_by_name(msg, "PROGRAM", NULL), "65536"); | ||
623 | + | ||
624 | + msg_format_options_destroy(&parse_options); | ||
625 | + log_msg_unref(msg); | ||
626 | +} | ||
627 | -- | ||
628 | 2.25.1 | ||
629 | |||
diff --git a/meta-oe/recipes-support/syslog-ng/syslog-ng_3.24.1.bb b/meta-oe/recipes-support/syslog-ng/syslog-ng_3.24.1.bb index 10bf00fdce..6e90dabd14 100644 --- a/meta-oe/recipes-support/syslog-ng/syslog-ng_3.24.1.bb +++ b/meta-oe/recipes-support/syslog-ng/syslog-ng_3.24.1.bb | |||
@@ -9,6 +9,7 @@ SRC_URI += " \ | |||
9 | file://0001-syslog-ng-fix-segment-fault-during-service-start.patch \ | 9 | file://0001-syslog-ng-fix-segment-fault-during-service-start.patch \ |
10 | file://shebang.patch \ | 10 | file://shebang.patch \ |
11 | file://syslog-ng-tmp.conf \ | 11 | file://syslog-ng-tmp.conf \ |
12 | file://CVE-2022-38725.patch \ | ||
12 | " | 13 | " |
13 | 14 | ||
14 | SRC_URI[md5sum] = "ef9de066793f7358af7312b964ac0450" | 15 | SRC_URI[md5sum] = "ef9de066793f7358af7312b964ac0450" |