diff options
| -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" |
