From 32121e0b0939d5d6d62bcf5dd861e6b30cc2d19e Mon Sep 17 00:00:00 2001 From: Reid Wahl Date: Fri, 27 Mar 2026 22:08:41 -0700 Subject: [PATCH 1/2] Refactor: libcrmcommon: Drop NULL check in parse_time() There is only one call site, and it NULL-checks the argument before the call. Signed-off-by: Reid Wahl --- lib/common/iso8601.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/lib/common/iso8601.c b/lib/common/iso8601.c index e9bd9efdac9..97c65a9d745 100644 --- a/lib/common/iso8601.c +++ b/lib/common/iso8601.c @@ -334,24 +334,22 @@ parse_time(const char *time_str, crm_time_t *a_time) tzset(); - if (time_str != NULL) { - if (!parse_hms(time_str, &(a_time->seconds))) { - return false; - } + if (!parse_hms(time_str, &(a_time->seconds))) { + return false; + } - offset_s = strchr(time_str, 'Z'); + offset_s = strchr(time_str, 'Z'); - /* @COMPAT: Spaces between the time and the offset are not supported - * by the standard according to section 3.4.1 and 4.2.5.2. - */ - if (offset_s == NULL) { - offset_s = strpbrk(time_str, " +-"); - } + /* @COMPAT: Spaces between the time and the offset are not supported by the + * standard according to section 3.4.1 and 4.2.5.2. + */ + if (offset_s == NULL) { + offset_s = strpbrk(time_str, " +-"); + } - if (offset_s != NULL) { - while (isspace(*offset_s)) { - offset_s++; - } + if (offset_s != NULL) { + while (isspace(*offset_s)) { + offset_s++; } } From b3311ce0e8543606b1dc78f7178d423d139e0e6e Mon Sep 17 00:00:00 2001 From: Reid Wahl Date: Fri, 27 Mar 2026 22:23:09 -0700 Subject: [PATCH 2/2] Low: libcrmcommon: Ignore empty time spec OSS Fuzz found an overflow in crm_time_subtract(), when crm_time_parse_period() was called with the argument "P2752S-596524H-22Y/T". The "T" after the slash was treated as a time spec. However, with nothing after the "T", this is malformed per the ISO 8601 specification. Pacemaker's time parsing code set the number of seconds to INT_MIN at some point and then tried to negate that value. The fuzzer detected this as potential underflow. We can avoid this by rejecting a time spec in parse_hms() if we cannot parse at least one field from it using sscanf(). The "rc == 0" test was failing because sscanf() returns EOF (a negative integer) when given the empty string after the "T" character. So, we simply check whether rc is less than 1. Fixes https://issues.oss-fuzz.com/u/1/issues/473156224 Signed-off-by: Reid Wahl --- lib/common/iso8601.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/iso8601.c b/lib/common/iso8601.c index 97c65a9d745..8c9d25d5acb 100644 --- a/lib/common/iso8601.c +++ b/lib/common/iso8601.c @@ -218,8 +218,8 @@ parse_hms(const char *time_str, int *result) rc = sscanf(time_str, "%2" SCNu32 "%2" SCNu32 "%2" SCNu32, &hour, &minute, &second); } - if (rc == 0) { - pcmk__err("%s is not a valid ISO 8601 time specification", time_str); + if (rc < 1) { + pcmk__err("'%s' is not a valid ISO 8601 time specification", time_str); return false; }