Package: samba
Version: 2.2.3a-14.2

Hi,

Unfortunately, todays 2.2.3a-14.2 samba update for stable did not fix
the DOS attack described in:

 http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0930

and

 http://us4.samba.org/samba/news/#security_3.0.8

This bothered me a little, so I came up with the appended patch which
fixed the problem for me.  It is not a backport of the 3.x patch but
seems simple enough.

Regards,
Wolfram.

--- samba-2.2.3a/source/lib/ms_fnmatch.c        Fri Jul  6 04:01:32 2001
+++ samba-2.2.3a-wg/source/lib/ms_fnmatch.c     Fri Apr  1 18:43:52 2005
@@ -26,15 +26,20 @@
 
 #include "includes.h"
 
+#define MAX_DEPTH 800
+
 /* 
    bugger. we need a separate wildcard routine for older versions
    of the protocol. This is not yet perfect, but its a lot
    better thaan what we had */
-static int ms_fnmatch_lanman_core(const char *pattern, const char *string)
+static int ms_fnmatch_lanman_core(const char *pattern, const char *string,
+                                 int *depth)
 {
        const char *p = pattern, *n = string;
        char c;
 
+       if (++(*depth) > MAX_DEPTH)
+           goto nomatch;
        if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match;
 
        while ((c = *p++)) {
@@ -55,8 +60,8 @@
                case '>':
                        if (! *n) goto next;
                        if (n[0] == '.') {
-                               if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 
0) goto match;
-                               if (ms_fnmatch_lanman_core(p, n) == 0) goto 
match;
+                               if (! n[1] && ms_fnmatch_lanman_core(p, n+1, 
depth) == 0) goto match;
+                               if (ms_fnmatch_lanman_core(p, n, depth) == 0) 
goto match;
                                goto nomatch;
                        }
                        n++;
@@ -66,13 +71,13 @@
                        if (! *n) goto next;
                        if (! *p) goto match;
                        for (; *n; n++) {
-                               if (ms_fnmatch_lanman_core(p, n) == 0) goto 
match;
+                               if (ms_fnmatch_lanman_core(p, n, depth) == 0) 
goto match;
                        }
                        break;
 
                case '<':
                        for (; *n; n++) {
-                               if (ms_fnmatch_lanman_core(p, n) == 0) goto 
match;
+                               if (ms_fnmatch_lanman_core(p, n, depth) == 0) 
goto match;
                                if (*n == '.' && !strchr(n+1,'.')) {
                                        n++;
                                        break;
@@ -81,7 +86,7 @@
                        break;
 
                case '"':
-                       if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto 
match;
+                       if (*n == 0 && ms_fnmatch_lanman_core(p, n, depth) == 
0) goto match;
                        if (*n != '.') goto nomatch;
                        n++;
                        break;
@@ -101,7 +106,7 @@
        return -1;
 
 next:
-       if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
+       if (ms_fnmatch_lanman_core(p, n, depth) == 0) goto match;
         goto nomatch;
 
  match:
@@ -113,17 +118,19 @@
 
 static int ms_fnmatch_lanman1(const char *pattern, const char *string)
 {
+       int depth = 0;
+
        if (!strpbrk(pattern, "?*<>\"")) {
                if (strcmp(string,"..") == 0) string = ".";
                return strcasecmp(pattern, string);
        }
 
        if (strcmp(string,"..") == 0 || strcmp(string,".") == 0) {
-               return ms_fnmatch_lanman_core(pattern, "..") &&
-                       ms_fnmatch_lanman_core(pattern, ".");
+               return ms_fnmatch_lanman_core(pattern, "..", &depth) &&
+                       ms_fnmatch_lanman_core(pattern, ".", &depth);
        }
 
-       return ms_fnmatch_lanman_core(pattern, string);
+       return ms_fnmatch_lanman_core(pattern, string, &depth);
 }
 
 
@@ -135,16 +142,13 @@
 
    Returns 0 on match, -1 on fail.
 */
-int ms_fnmatch(const char *pattern, const char *string)
+static int ms_fnmatch_depth(const char *pattern, const char *string, int 
*depth)
 {
        const char *p = pattern, *n = string;
        char c;
-       extern int Protocol;
-
-       if (Protocol <= PROTOCOL_LANMAN2) {
-               return ms_fnmatch_lanman1(pattern, string);
-       }
 
+       if (++(*depth) > MAX_DEPTH)
+           return -1;
        while ((c = *p++)) {
                switch (c) {
                case '?':
@@ -154,23 +158,23 @@
 
                case '>':
                        if (n[0] == '.') {
-                               if (! n[1] && ms_fnmatch(p, n+1) == 0) return 0;
-                               if (ms_fnmatch(p, n) == 0) return 0;
+                               if (! n[1] && ms_fnmatch_depth(p, n+1, depth) 
== 0) return 0;
+                               if (ms_fnmatch_depth(p, n, depth) == 0) return 
0;
                                return -1;
                        }
-                       if (! *n) return ms_fnmatch(p, n);
+                       if (! *n) return ms_fnmatch_depth(p, n, depth);
                        n++;
                        break;
 
                case '*':
                        for (; *n; n++) {
-                               if (ms_fnmatch(p, n) == 0) return 0;
+                               if (ms_fnmatch_depth(p, n, depth) == 0) return 
0;
                        }
                        break;
 
                case '<':
                        for (; *n; n++) {
-                               if (ms_fnmatch(p, n) == 0) return 0;
+                               if (ms_fnmatch_depth(p, n, depth) == 0) return 
0;
                                if (*n == '.' && !strchr(n+1,'.')) {
                                        n++;
                                        break;
@@ -179,7 +183,7 @@
                        break;
 
                case '"':
-                       if (*n == 0 && ms_fnmatch(p, n) == 0) return 0;
+                       if (*n == 0 && ms_fnmatch_depth(p, n, depth) == 0) 
return 0;
                        if (*n != '.') return -1;
                        n++;
                        break;
@@ -193,4 +197,16 @@
        if (! *n) return 0;
        
        return -1;
+}
+
+int ms_fnmatch(const char *pattern, const char *string)
+{
+       extern int Protocol;
+       int depth = 0;
+
+       /*printf("MATCH   pattern=[%s] string=[%s]\n", pattern, string);*/
+       if (Protocol <= PROTOCOL_LANMAN2) {
+               return ms_fnmatch_lanman1(pattern, string);
+       }
+       return ms_fnmatch_depth(pattern, string, &depth);
 }


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to