[monitoring-plugins] check_curl: Prevent buffer overflow
Lorenz Kästle
git at monitoring-plugins.org
Sun Jul 26 11:10:13 CEST 2026
Module: monitoring-plugins
Branch: master
Commit: 8db98f4044b28bc880edcf44b4432c40865c04c1
Author: Lorenz Kästle <lorenz at vulgrim.de>
Date: Fri Jul 17 15:13:02 2026 +0200
URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=8db98f40
check_curl: Prevent buffer overflow
---
plugins/check_curl.c | 74 ++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 58 insertions(+), 16 deletions(-)
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index adafc620..5ff2106a 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -683,14 +683,33 @@ int uri_strcmp(const UriTextRangeA range, const char *stringToCompare) {
min((size_t)(range.afterLast - range.first), strlen(stringToCompare)));
}
-char *uri_string(const UriTextRangeA range, char *buf, size_t buflen) {
+typedef struct {
+ char *uri_string;
+ int errorcode;
+} uri_string_wrapper;
+uri_string_wrapper uri_string(const UriTextRangeA range, char *buf, size_t buflen) {
+ uri_string_wrapper result = {
+ .uri_string = NULL,
+ .errorcode = 0,
+ };
+
if (!range.first) {
- return "(null)";
+ result.errorcode = 1;
+ return result;
}
- strncpy(buf, range.first, max(buflen - 1, (size_t)(range.afterLast - range.first)));
- buf[max(buflen - 1, (size_t)(range.afterLast - range.first))] = '\0';
+
+ size_t copy_size = range.afterLast - range.first;
+ if (copy_size > buflen - 1) {
+ result.errorcode = 2;
+ return result;
+ }
+
+ strncpy(buf, range.first, copy_size);
+ buf[copy_size] = '\0';
buf[range.afterLast - range.first] = '\0';
- return buf;
+ result.uri_string = buf;
+
+ return result;
}
redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config config,
@@ -738,9 +757,9 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
char ipstr[INET_ADDR_MAX_SIZE];
char buf[DEFAULT_BUFFER_SIZE];
if (verbose >= 2) {
- printf(_("** scheme: %s\n"), uri_string(uri.scheme, buf, DEFAULT_BUFFER_SIZE));
- printf(_("** host: %s\n"), uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE));
- printf(_("** port: %s\n"), uri_string(uri.portText, buf, DEFAULT_BUFFER_SIZE));
+ printf(_("** scheme: %s\n"), uri_string(uri.scheme, buf, DEFAULT_BUFFER_SIZE).uri_string);
+ printf(_("** host: %s\n"), uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE).uri_string);
+ printf(_("** port: %s\n"), uri_string(uri.portText, buf, DEFAULT_BUFFER_SIZE).uri_string);
if (uri.hostData.ip4) {
inet_ntop(AF_INET, uri.hostData.ip4->data, ipstr, sizeof(ipstr));
printf(_("** IPv4: %s\n"), ipstr);
@@ -753,15 +772,16 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
printf(_("** path: "));
for (UriPathSegmentA *path_segment = uri.pathHead; path_segment;
path_segment = path_segment->next) {
- printf("/%s", uri_string(path_segment->text, buf, DEFAULT_BUFFER_SIZE));
+ printf("/%s", uri_string(path_segment->text, buf, DEFAULT_BUFFER_SIZE).uri_string);
}
puts("");
}
if (uri.query.first) {
- printf(_("** query: %s\n"), uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE));
+ printf(_("** query: %s\n"), uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE).uri_string);
}
if (uri.fragment.first) {
- printf(_("** fragment: %s\n"), uri_string(uri.fragment, buf, DEFAULT_BUFFER_SIZE));
+ printf(_("** fragment: %s\n"),
+ uri_string(uri.fragment, buf, DEFAULT_BUFFER_SIZE).uri_string);
}
}
@@ -774,7 +794,14 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
*/
int new_port;
if (uri.portText.first) {
- new_port = atoi(uri_string(uri.portText, buf, DEFAULT_BUFFER_SIZE));
+ uri_string_wrapper port_copy = uri_string(uri.portText, buf, DEFAULT_BUFFER_SIZE);
+
+ if (port_copy.errorcode != 0) {
+ die(STATE_UNKNOWN,
+ _("HTTP UNKNOWN - Error while parsing the new port from redirection\n"));
+ }
+
+ new_port = atoi(port_copy.uri_string);
} else {
new_port = HTTP_PORT;
if (working_state.use_ssl) {
@@ -798,7 +825,11 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
uri_string(uri.scheme, "https", DEFAULT_BUFFER_SIZE);
}
} else {
- new_host = strdup(uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE));
+ uri_string_wrapper new_host_parse = uri_string(uri.hostText, buf, DEFAULT_BUFFER_SIZE);
+ if (new_host_parse.errorcode != 0) {
+ die(STATE_UNKNOWN, _("HTTP UNKNOWN - Error while parsing new host in redir\n"));
+ }
+ new_host = strdup(new_host_parse.uri_string);
}
/* compose new path */
@@ -808,8 +839,14 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
for (UriPathSegmentA *pathSegment = uri.pathHead; pathSegment;
pathSegment = pathSegment->next) {
strncat(new_url, "/", DEFAULT_BUFFER_SIZE);
- strncat(new_url, uri_string(pathSegment->text, buf, DEFAULT_BUFFER_SIZE),
- DEFAULT_BUFFER_SIZE - 1);
+
+ uri_string_wrapper new_url_copy =
+ uri_string(pathSegment->text, buf, DEFAULT_BUFFER_SIZE);
+ if (new_url_copy.errorcode != 0) {
+ die(STATE_UNKNOWN, _("HTTP UNKNOWN - Error while parsing new url in redir\n"));
+ }
+
+ strncat(new_url, new_url_copy.uri_string, DEFAULT_BUFFER_SIZE - 1);
}
}
@@ -822,7 +859,12 @@ redir_wrapper redir(curlhelp_write_curlbuf *header_buf, const check_curl_config
size_t current_len = strlen(new_url);
size_t remaining_space = DEFAULT_BUFFER_SIZE - current_len - 1;
- const char *query_str = uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE);
+ uri_string_wrapper query_string_copy = uri_string(uri.query, buf, DEFAULT_BUFFER_SIZE);
+ if (query_string_copy.errorcode != 0) {
+ die(STATE_UNKNOWN, _("HTTP UNKNOWN - Error while parsing redir url stuff"));
+ }
+
+ const char *query_str = query_string_copy.uri_string;
size_t query_str_len = strlen(query_str);
if (remaining_space >= query_str_len + 1) {
More information about the Commits
mailing list