Browse Source

check_http segmentation fault

Fix for issue https://github.com/nagios-plugins/nagios-plugins/issues/172

My fix for issue #42 broke this guy's checks. It looks to me like the
server he was connecting to was sending '\n' instead of '\r\n' for and
after the headers. Technically, that breaks the protocol, but I reworked
my prior fix and allowed '\n' in the headers.
John C. Frickson 9 years ago
parent
commit
f3a519f8bd
2 changed files with 16 additions and 18 deletions
  1. 2 0
      NEWS
  2. 14 18
      plugins/check_http.c

+ 2 - 0
NEWS

@@ -7,6 +7,8 @@ This file documents the major additions and syntax changes between releases.
 	check_ping: ping runs 30 times when host is down
 	check_icmp: does not have the -p argument in the help
 	check_dns: Segfaulting with timeout > 26 sec
+	check_disk: missing -lrt on Solaris
+	check_http: segmentation fault
 
 
 2.1.4 2016-11-17

+ 14 - 18
plugins/check_http.c

@@ -983,6 +983,7 @@ check_http (void)
   int result = STATE_OK;
   char *force_host_header = NULL;
 	int bad_response = FALSE;
+	char save_char;
 
   /* try to connect to the host at the given port number */
   gettimeofday (&tv_temp, NULL);
@@ -1180,7 +1181,7 @@ check_http (void)
   elapsed_time = (double)microsec / 1.0e6;
 
   /* leave full_page untouched so we can free it later */
-  page = full_page;
+  pos = page = full_page;
 
   if (verbose)
     printf ("%s://%s:%d%s is %d characters\n",
@@ -1188,36 +1189,29 @@ check_http (void)
       server_port, server_url, (int)pagesize);
 
   /* find status line and null-terminate it */
-  status_line = page;
-  page = strstr(page, "\r\n");
-  page += 2;
-/*  page += (size_t) strcspn (page, "\r\n"); */
-/*  page += (size_t) strspn (page, "\r\n"); */
+  page += (size_t) strcspn (page, "\r\n");
+	save_char = *page;
+	*page = '\0';
+	status_line = strdup(pos);
+	*page = save_char;
   pos = page;
 
-  status_line[strcspn(status_line, "\r\n")] = 0;
   strip (status_line);
   if (verbose)
     printf ("STATUS: %s\n", status_line);
 
   /* find header info and null-terminate it */
   header = page;
-/*  while (strcspn (page, "\r\n") > 0) { */
-  while (page[0] != '\r' || page[1] != '\n') {
+	for (;;) {
+		if (!strncmp(page, "\r\n\r\n", 4) || !strncmp(page, "\n\n", 2))
+		 break;
+		while (*page == '\r' || *page == '\n') { ++page; }
     page += (size_t) strcspn (page, "\r\n");
     pos = page;
-    if ((strspn (page, "\r") == 1 && strspn (page, "\r\n") >= 2) ||
-        (strspn (page, "\n") == 1 && strspn (page, "\r\n") >= 2)) {
-      page += (size_t) 2;
-      pos += (size_t) 2;
-    }
-    else {
-      page += (size_t) 1;
-      pos += (size_t) 1;
-    }
   }
   page += (size_t) strspn (page, "\r\n");
   header[pos - header] = 0;
+	while (*header == '\r' || *header == '\n') { ++header; }
 
   if (chunked_transfer_encoding(header) && *page)
     page = decode_chunked_page(page, page);
@@ -1290,6 +1284,8 @@ check_http (void)
     xasprintf (&msg, _("%s%s - "), msg, status_line);
   }
 
+	free(status_line);
+
   if (bad_response) 
     die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);