Просмотр исходного кода

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 лет назад
Родитель
Сommit
f3a519f8bd
2 измененных файлов с 16 добавлено и 18 удалено
  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);