[monitoring-plugins] check_icmp: Fix parsing of single-char threshold
Holger Weiss
git at monitoring-plugins.org
Wed Jul 1 13:20:13 CEST 2026
Module: monitoring-plugins
Branch: master
Commit: a675995b19a6315f1b033a7c1ca980b5fbdc408d
Author: Holger Weiss <holger at zedat.fu-berlin.de>
Date: Tue Jun 30 15:58:09 2026 +0200
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=a675995b
check_icmp: Fix parsing of single-char threshold
The threshold parser starts a pointer at the last character of the
string and walks it backwards until it reaches the second character.
This assumes the string is at least two characters long. For a
single-character threshold such as "-w 1" or "-c 1", the pointer
underflows past the start of the string and keeps dereferencing memory
out of bounds.
Beyond the out-of-bounds reads, an out-of-bounds write can occur if a
stray '%' or ',' byte happens to turn up while scanning backwards. In
that case, the parser writes a NUL byte at that out-of-bounds address
(the ',' case additionally re-reads forward from there via strtoul(3)).
Only run the descending scan when the string has at least two
characters, leaving the behaviour for all valid thresholds unchanged.
Reported-by: Christopher Kreft <Email at ChristopherKreft.de>
---
plugins-root/check_icmp.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index f3c83ee0..8f5c1fe4 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -1926,18 +1926,21 @@ static get_threshold_wrapper get_threshold(char *str, check_icmp_threshold thres
}
/* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */
- bool is_at_last_char = false;
- char *tmp = &str[strlen(str) - 1];
- while (tmp != &str[1]) {
- if (*tmp == '%') {
- *tmp = '\0';
- } else if (*tmp == ',' && is_at_last_char) {
- *tmp = '\0'; /* reset it so get_timevar(str) works nicely later */
- result.threshold.pl = (unsigned char)strtoul(tmp + 1, NULL, 0);
- break;
+ size_t len = strlen(str);
+ if (len >= 2) {
+ bool is_at_last_char = false;
+ char *tmp = &str[len - 1];
+ while (tmp != &str[1]) {
+ if (*tmp == '%') {
+ *tmp = '\0';
+ } else if (*tmp == ',' && is_at_last_char) {
+ *tmp = '\0'; /* reset it so get_timevar(str) works nicely later */
+ result.threshold.pl = (unsigned char)strtoul(tmp + 1, NULL, 0);
+ break;
+ }
+ is_at_last_char = true;
+ tmp--;
}
- is_at_last_char = true;
- tmp--;
}
get_timevar_wrapper parsed_time = get_timevar(str);
More information about the Commits
mailing list