source: build-files/src-patches/1-SA-13:01.libc.patch @ 1620346

9.1-release9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 1620346 was 1620346, checked in by Kris Moore <kris@…>, 19 months ago

Initial import of PC-BSD /current/ SVN repo

  • Property mode set to 100644
File size: 6.8 KB
  • lib/libc/gen/glob.c

    __FBSDID("$FreeBSD$"); 
    9494 
    9595#include "collate.h" 
    9696 
     97/* 
     98 * glob(3) expansion limits. Stop the expansion if any of these limits 
     99 * is reached. This caps the runtime in the face of DoS attacks. See 
     100 * also CVE-2010-2632 
     101 */ 
     102#define GLOB_LIMIT_BRACE        128     /* number of brace calls */ 
     103#define GLOB_LIMIT_PATH         65536   /* number of path elements */ 
     104#define GLOB_LIMIT_READDIR      16384   /* number of readdirs */ 
     105#define GLOB_LIMIT_STAT         1024    /* number of stat system calls */ 
     106#define GLOB_LIMIT_STRING       ARG_MAX /* maximum total size for paths */ 
     107 
     108struct glob_limit { 
     109        size_t  l_brace_cnt; 
     110        size_t  l_path_lim; 
     111        size_t  l_readdir_cnt;   
     112        size_t  l_stat_cnt;      
     113        size_t  l_string_cnt; 
     114}; 
     115 
    97116#define DOLLAR          '$' 
    98117#define DOT             '.' 
    99118#define EOS             '\0' 
    static const Char *g_strchr(const Char *, wchar_t) 
    153172static Char     *g_strcat(Char *, const Char *); 
    154173#endif 
    155174static int       g_stat(Char *, struct stat *, glob_t *); 
    156 static int       glob0(const Char *, glob_t *, size_t *); 
    157 static int       glob1(Char *, glob_t *, size_t *); 
    158 static int       glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *); 
    159 static int       glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); 
    160 static int       globextend(const Char *, glob_t *, size_t *); 
    161 static const Char *      
     175static int       glob0(const Char *, glob_t *, struct glob_limit *); 
     176static int       glob1(Char *, glob_t *, struct glob_limit *); 
     177static int       glob2(Char *, Char *, Char *, Char *, glob_t *, 
     178    struct glob_limit *); 
     179static int       glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, 
     180    struct glob_limit *); 
     181static int       globextend(const Char *, glob_t *, struct glob_limit *); 
     182static const Char * 
    162183                 globtilde(const Char *, Char *, size_t, glob_t *); 
    163 static int       globexp1(const Char *, glob_t *, size_t *); 
    164 static int       globexp2(const Char *, const Char *, glob_t *, int *, size_t *); 
     184static int       globexp1(const Char *, glob_t *, struct glob_limit *); 
     185static int       globexp2(const Char *, const Char *, glob_t *, int *, 
     186    struct glob_limit *); 
    165187static int       match(Char *, Char *, Char *); 
    166188#ifdef DEBUG 
    167189static void      qprintf(const char *, Char *); 
    int 
    171193glob(const char * __restrict pattern, int flags, 
    172194         int (*errfunc)(const char *, int), glob_t * __restrict pglob) 
    173195{ 
     196        struct glob_limit limit = { 0, 0, 0, 0, 0 }; 
    174197        const char *patnext; 
    175         size_t limit; 
    176198        Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; 
    177199        mbstate_t mbs; 
    178200        wchar_t wc; 
    glob(const char * __restrict pattern, int flags, 
    186208                        pglob->gl_offs = 0; 
    187209        } 
    188210        if (flags & GLOB_LIMIT) { 
    189                 limit = pglob->gl_matchc; 
    190                 if (limit == 0) 
    191                         limit = ARG_MAX; 
    192         } else 
    193                 limit = 0; 
     211                limit.l_path_lim = pglob->gl_matchc; 
     212                if (limit.l_path_lim == 0) 
     213                        limit.l_path_lim = GLOB_LIMIT_PATH; 
     214        } 
    194215        pglob->gl_flags = flags & ~GLOB_MAGCHAR; 
    195216        pglob->gl_errfunc = errfunc; 
    196217        pglob->gl_matchc = 0; 
    glob(const char * __restrict pattern, int flags, 
    243264 * characters 
    244265 */ 
    245266static int 
    246 globexp1(const Char *pattern, glob_t *pglob, size_t *limit) 
     267globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit) 
    247268{ 
    248269        const Char* ptr = pattern; 
    249270        int rv; 
    250271 
     272        if ((pglob->gl_flags & GLOB_LIMIT) && 
     273            limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { 
     274                errno = 0; 
     275                return (GLOB_NOSPACE); 
     276        } 
     277 
    251278        /* Protect a single {}, for find(1), like csh */ 
    252279        if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) 
    253280                return glob0(pattern, pglob, limit); 
    static int 
    266293 * If it fails then it tries to glob the rest of the pattern and returns. 
    267294 */ 
    268295static int 
    269 globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, size_t *limit) 
     296globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, 
     297    struct glob_limit *limit) 
    270298{ 
    271299        int     i; 
    272300        Char   *lm, *ls; 
    globtilde(const Char *pattern, Char *patbuf, size_ 
    436464 * if things went well, nonzero if errors occurred. 
    437465 */ 
    438466static int 
    439 glob0(const Char *pattern, glob_t *pglob, size_t *limit) 
     467glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit) 
    440468{ 
    441469        const Char *qpatnext; 
    442470        int err; 
    compare(const void *p, const void *q) 
    529557} 
    530558 
    531559static int 
    532 glob1(Char *pattern, glob_t *pglob, size_t *limit) 
     560glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit) 
    533561{ 
    534562        Char pathbuf[MAXPATHLEN]; 
    535563 
    static int 
    547575 */ 
    548576static int 
    549577glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, 
    550       glob_t *pglob, size_t *limit) 
     578      glob_t *pglob, struct glob_limit *limit) 
    551579{ 
    552580        struct stat sb; 
    553581        Char *p, *q; 
    glob2(Char *pathbuf, Char *pathend, Char *pathend_ 
    563591                        if (g_lstat(pathbuf, &sb, pglob)) 
    564592                                return(0); 
    565593 
     594                        if ((pglob->gl_flags & GLOB_LIMIT) && 
     595                            limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) { 
     596                                errno = 0; 
     597                                if (pathend + 1 > pathend_last) 
     598                                        return (GLOB_ABORTED); 
     599                                *pathend++ = SEP; 
     600                                *pathend = EOS; 
     601                                return (GLOB_NOSPACE); 
     602                        } 
    566603                        if (((pglob->gl_flags & GLOB_MARK) && 
    567604                            pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) 
    568605                            || (S_ISLNK(sb.st_mode) && 
    glob2(Char *pathbuf, Char *pathend, Char *pathend_ 
    606643static int 
    607644glob3(Char *pathbuf, Char *pathend, Char *pathend_last, 
    608645      Char *pattern, Char *restpattern, 
    609       glob_t *pglob, size_t *limit) 
     646      glob_t *pglob, struct glob_limit *limit) 
    610647{ 
    611648        struct dirent *dp; 
    612649        DIR *dirp; 
    glob3(Char *pathbuf, Char *pathend, Char *pathend_ 
    652689                size_t clen; 
    653690                mbstate_t mbs; 
    654691 
     692                if ((pglob->gl_flags & GLOB_LIMIT) && 
     693                    limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) { 
     694                        errno = 0; 
     695                        if (pathend + 1 > pathend_last) 
     696                                err = GLOB_ABORTED; 
     697                        else { 
     698                                *pathend++ = SEP; 
     699                                *pathend = EOS; 
     700                                err = GLOB_NOSPACE; 
     701                        } 
     702                        break; 
     703                } 
     704 
    655705                /* Initial DOT must be matched literally. */ 
    656706                if (dp->d_name[0] == DOT && *pattern != DOT) 
    657707                        continue; 
    glob3(Char *pathbuf, Char *pathend, Char *pathend_ 
    702752 *      gl_pathv points to (gl_offs + gl_pathc + 1) items. 
    703753 */ 
    704754static int 
    705 globextend(const Char *path, glob_t *pglob, size_t *limit) 
     755globextend(const Char *path, glob_t *pglob, struct glob_limit *limit) 
    706756{ 
    707757        char **pathv; 
    708758        size_t i, newsize, len; 
    709759        char *copy; 
    710760        const Char *p; 
    711761 
    712         if (*limit && pglob->gl_pathc > *limit) { 
     762        if ((pglob->gl_flags & GLOB_LIMIT) && 
     763            pglob->gl_matchc > limit->l_path_lim) { 
    713764                errno = 0; 
    714765                return (GLOB_NOSPACE); 
    715766        } 
    static int 
    737788        for (p = path; *p++;) 
    738789                continue; 
    739790        len = MB_CUR_MAX * (size_t)(p - path);  /* XXX overallocation */ 
     791        limit->l_string_cnt += len; 
     792        if ((pglob->gl_flags & GLOB_LIMIT) && 
     793            limit->l_string_cnt >= GLOB_LIMIT_STRING) { 
     794                errno = 0; 
     795                return (GLOB_NOSPACE); 
     796        } 
    740797        if ((copy = malloc(len)) != NULL) { 
    741798                if (g_Ctoc(path, copy, len)) { 
    742799                        free(copy); 
Note: See TracBrowser for help on using the repository browser.