소스 검색

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 년 전
부모
커밋
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);