diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2011-02-10 21:32:00 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2011-02-10 21:32:00 +0000 |
commit | baeeb41ea912884bc9edd4d9948fecf4fce85798 (patch) | |
tree | eda0d1412f66a812dc115947bf62de208b2293d5 /lib/libc | |
parent | 1621b63b7d6f8b26cd58be84a18ca219b2ed981d (diff) |
Put a limit on recursion during matching, and reject input of size greater
or equal PATH_MAX. Based on similar fix made in NetBSD.
ok miod@ millert@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/fnmatch.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index 2388f826382..a005013aab6 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fnmatch.c,v 1.14 2008/10/01 23:04:13 millert Exp $ */ +/* $OpenBSD: fnmatch.c,v 1.15 2011/02/10 21:31:59 stsp Exp $ */ /* * Copyright (c) 1989, 1993, 1994 @@ -41,6 +41,7 @@ #include <stdio.h> #include <string.h> #include <fnmatch.h> +#include <limits.h> #include "charclass.h" @@ -50,15 +51,38 @@ #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) +/* Limit of recursion during matching attempts. */ +#define __FNM_MAX_RECUR 64 + static int rangematch(const char *, char, int, char **); static int classmatch(const char *, char, int, const char **); +static int __fnmatch(const char *, const char *, int, int); int fnmatch(const char *pattern, const char *string, int flags) { + int e; + + if (strnlen(pattern, PATH_MAX) == PATH_MAX || + strnlen(string, PATH_MAX) == PATH_MAX) + return (FNM_NOMATCH); + + e = __fnmatch(pattern, string, flags, __FNM_MAX_RECUR); + if (e == -1) + e = FNM_NOMATCH; + return (e); +} + +static int +__fnmatch(const char *pattern, const char *string, int flags, int recur) +{ const char *stringstart; char *newp; char c, test; + int e; + + if (recur-- == 0) + return (-1); for (stringstart = string;;) switch (c = *pattern++) { @@ -104,8 +128,10 @@ fnmatch(const char *pattern, const char *string, int flags) /* General case, use recursion. */ while ((test = *string) != EOS) { - if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) - return (0); + e = __fnmatch(pattern, string, + flags & ~FNM_PERIOD, recur); + if (e != FNM_NOMATCH) + return (e); if (test == '/' && (flags & FNM_PATHNAME)) break; ++string; |