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]