Package: nagios-plugins-basic
Version: 1.4.5-1etch1
Severity: normal
Tags: patch


problem can usually (depending on network config) be reproduced by:
check_ping -H [invalid-ipv6-address] -w 5000,100% -c 5000,100% -p 1

Debian's ping6 may produce output in the following format:

3 packets transmitted, 0 received, +3 errors, 100% packet loss, time
2009ms

There's a corresponding pattern in check_ping.c:450:

"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss"

but the pattern in check_ping.c:448 matches first:

"%*d packets transmitted, %*d received, %d%% loss, time"

because sscanf interprets "+3" as a match for "%d". Although the rest
of the pattern doesn't match, the number of successful assignments
(and thus the return value of sscanf) is still 1.

A simple way to make sure the whole pattern matches is to add a "%n"
specifier at the end, which will assign the number of characters
matched by that point. (The same trick is used in check_http.c.)
There seems to be some confusion whether "%n" affects the return value
of sscanf, so it's safer to check the assigned number of characters.

A bug was reported a year ago to the upstream
http://sourceforge.net/tracker/index.php?func=detail&aid=1894850&group_id=29880&atid=397597
but it seems to be dead.

Patch to fix it attached.


-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.24-etchnhalf.1-amd64
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages nagios-plugins-basic depends on:
ii  iputils-ping           3:20020927-6      Tools to test the reachability of 
ii  libc6                  2.3.6.ds1-13etch8 GNU C Library: Shared libraries
ii  libssl0.9.8            0.9.8c-4etch4     SSL shared libraries
ii  procps                 1:3.2.7-3         /proc file system utilities
ii  ucf                    2.0020            Update Configuration File: preserv

nagios-plugins-basic recommends no packages.

-- no debconf information
--- plugins/check_ping.c~
+++ plugins/check_ping.c
@@ -424,6 +424,7 @@
 {
 	char buf[MAX_INPUT_BUFFER];
 	int result = STATE_UNKNOWN;
+	int match;
 
 	if ((child_process = spopen (cmd)) == NULL)
 		die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
@@ -440,28 +441,29 @@
 		result = max_state (result, error_scan (buf, addr));
 
 		/* get the percent loss statistics */
-		if(sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss",&pl)==1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss", &pl) == 1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss", &pl) == 1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% packet loss",&pl)==1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% loss, time",&pl)==1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time", &pl)==1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d received, %d%% packet loss, time", &pl)==1 ||
-			 sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss", &pl) == 1 ||
-			 sscanf(buf,"%*d packets transmitted %*d received, +%*d errors, %d%% packet loss", &pl) == 1
+		match = 0;
+		if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% packet loss%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% loss, time%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d received, %d%% packet loss, time%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) ||
+			 (sscanf(buf,"%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n",&pl,&match) && match)
 			 )
 			continue;
 
 		/* get the round trip average */
 		else
-			if(sscanf(buf,"round-trip min/avg/max = %*f/%f/%*f",&rta)==1 ||
-				 sscanf(buf,"round-trip min/avg/max/mdev = %*f/%f/%*f/%*f",&rta)==1 ||
-				 sscanf(buf,"round-trip min/avg/max/sdev = %*f/%f/%*f/%*f",&rta)==1 ||
-				 sscanf(buf,"round-trip min/avg/max/stddev = %*f/%f/%*f/%*f",&rta)==1 ||
-				 sscanf(buf,"round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f",&rta)==1 ||
-				 sscanf(buf,"round-trip (ms) min/avg/max = %*f/%f/%*f",&rta)==1 ||
-				 sscanf(buf,"round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f",&rta)==1 ||
-				 sscanf(buf,"rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms",&rta)==1)
+			if((sscanf(buf,"round-trip min/avg/max = %*f/%f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"round-trip (ms) min/avg/max = %*f/%f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n",&rta,&match) && match) ||
+				 (sscanf(buf,"rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n",&rta,&match) && match))
 			continue;
 	}
 

Reply via email to