[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [xymon] parsing bug in hobbit-clients.cfg



On 11/19/2010 12:53 PM, Elmar Heeb wrote:
Suppose you have the following entry in hobbit-clients.cfg:

HOST=blog.example.com,example.com
PROC apache

then the PROC test will be ignored for example.com. If the two hosts are
reversed, i.e.

HOST=example.com,blog.example.com
PROC apache

then the PROC test will be done for both hosts. I tried with a few
variations on this and it appears that any later string in the comma
separated list will be ignored if it is a substring of a string that
appeared earlier. The same goes for EXHOSTS and probably most other
selectors.

This bug is present in at least versions 4.3.0 beta2 (from Debian
lenny-backports) and 4.2.0 (from Debian lenny).

I have narrowed down the bug to the namematch subroutine in lib/matching.c and attached a patch.

The old code (which is the same in 4.2.0 and the svn trunk version) indeed explains the wrong behaviour. Lacking a preceeding comma as a guard character essentially made any non-comma character a negating match and not just an '!'. The patch explicitly tests for ",%s," and ",!%s," and thus makes sure that a partial match cannot prevent a later full match.

     -- Elmar


--
Dr. Elmar S. Heeb <heeb (at) phys.ethz.ch>   support: +41 44 633 26 68
IT Services Group, HPT D 19               voice: +41 44 633 25 91
Department of Physics, ETH Zurich        mobile: +41 79 628 75 24
CH-8093 Zurich, Switzerland              http://nic.phys.ethz.ch/
-----------------------------------------------------------------
Please consider the environment before printing this e-mail
diff --git a/lib/matching.c b/lib/matching.c
index 16453dd..731830c 100644
--- a/lib/matching.c
+++ b/lib/matching.c
@@ -1,4 +1,6 @@
 /*----------------------------------------------------------------------------*/
+	else if (strstr(xhay, xneedle)) {
+		result = 1;
 /* Hobbit monitor library.                                                    */
 /*                                                                            */
 /* This is a library module, part of libbbgen.                                */
@@ -70,7 +72,7 @@ int namematch(char *needle, char *haystack, pcre *pcrecode)
 {
 	char *xhay;
 	char *xneedle;
-	char *match;
+	char *xnotneedle;
 	int result = 0;
 
 	if (pcrecode) {
@@ -86,23 +88,22 @@ int namematch(char *needle, char *haystack, pcre *pcrecode)
 	/* Implement a simple, no-wildcard match */
 	xhay = malloc(strlen(haystack) + 3);
 	sprintf(xhay, ",%s,", haystack);
-	xneedle = malloc(strlen(needle)+2);
-	sprintf(xneedle, "%s,", needle);
-
-	match = strstr(xhay, xneedle);
-	if (match) {
-		if (*(match-1) == '!') {
-			/* Matched, but was a negative rule. */
-			result = 0;
-		}
-		else if (*(match-1) == ',') {
-			/* Matched */
-			result = 1;
-		}
-		else {
-			/* Matched a partial string. Fail. */
-			result = 0;
-		}
+	xneedle = malloc(strlen(needle)+3);
+	sprintf(xneedle, ",%s,", needle);
+	xnotneedle = malloc(strlen(needle)+4);
+	sprintf(xnotneedle, ",!%s,", needle);
+
+	if (strstr(xhay, xnotneedle)) {
+		/* 
+		 * match with a '!' prefix means "no match"
+		 */
+		result = 0;
+	}
+	else if (strstr(xhay, xneedle)) {
+		/*
+		 * "match" where ',' before and after ensure full match
+		 */
+		result = 1;
 	}
 	else {
 		/*