Pārlūkot izejas kodu

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 gadi atpakaļ
vecāks
revīzija
f3a519f8bd
2 mainītis faili ar 16 papildinājumiem un 18 dzēšanām
  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_ping: ping runs 30 times when host is down
 	check_icmp: does not have the -p argument in the help
 	check_icmp: does not have the -p argument in the help
 	check_dns: Segfaulting with timeout > 26 sec
 	check_dns: Segfaulting with timeout > 26 sec
+	check_disk: missing -lrt on Solaris
+	check_http: segmentation fault
 
 
 
 
 2.1.4 2016-11-17
 2.1.4 2016-11-17

+ 14 - 18
plugins/check_http.c

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