From 7a51a3d41ae7d7723bbc4017b3ac64620c7877c4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Malo?= Date: Thu, 7 Aug 2003 16:38:19 +0000 Subject: [PATCH] split ap_process_resource_config into two functions (since we don't wanna change the api). Only the first one (the ap_ entry point) now checks for fnmatch and the second one will be called for every file/directory included. This, however, avoids infinite recursions, if a filename contains wildcard characters. PR: 22194 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@100931 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++ server/config.c | 165 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 115 insertions(+), 54 deletions(-) diff --git a/CHANGES b/CHANGES index bf1985e16f..d23ffce1c3 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.1.0-dev [Remove entries to the current 2.0 section below, when backported] + *) Avoid an infinite recursion, which occured if the name of an included + config file or directory contained a wildcard character. PR 22194. + [André Malo] + *) mod_dav: Use bucket brigades when reading PUT data. This avoids problems if the data stream is modified by an input filter. PR 22104. [Tim Robbins , André Malo] diff --git a/server/config.c b/server/config.c index 3be4368841..86daeeb666 100644 --- a/server/config.c +++ b/server/config.c @@ -1442,64 +1442,23 @@ static int fname_alphasort(const void *fn1, const void *fn2) return strcmp(f1->fname,f2->fname); } -AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, - ap_directive_t **conftree, - apr_pool_t *p, - apr_pool_t *ptemp) +static void process_resource_config_nofnmatch(server_rec *s, const char *fname, + ap_directive_t **conftree, + apr_pool_t *p, + apr_pool_t *ptemp) { cmd_parms parms; - apr_finfo_t finfo; - const char *errmsg; ap_configfile_t *cfp; - int ispatt; - - /* XXX: lstat() won't work on the wildcard pattern... - */ - - /* don't require conf/httpd.conf if we have a -C or -c switch */ - if ((ap_server_pre_read_config->nelts - || ap_server_post_read_config->nelts) - && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) { - if (apr_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS) - return; - } + const char *errmsg; - ispatt = apr_fnmatch_test(fname); - if (ispatt || ap_is_rdirectory(p, fname)) { + if (ap_is_rdirectory(p, fname)) { apr_dir_t *dirp; apr_finfo_t dirent; int current; apr_array_header_t *candidates = NULL; fnames *fnew; apr_status_t rv; - char errmsg[120], *path = apr_pstrdup(p, fname), *pattern = NULL; - - if (ispatt) { - pattern = ap_strrchr(path, '/'); - - AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */ - - *pattern++ = '\0'; - - if (apr_fnmatch_test(path)) { - fprintf(stderr, "%s: wildcard patterns not allowed in Include " - "%s\n", ap_server_argv0, fname); - exit(1); - } - - if (!ap_is_rdirectory(p, path)){ - fprintf(stderr, "%s: Include directory '%s' not found", - ap_server_argv0, path); - exit(1); - } - - if (!apr_fnmatch_test(pattern)) { - fprintf(stderr, "%s: must include a wildcard pattern " - "for Include %s\n", ap_server_argv0, fname); - exit(1); - } - - } + char errmsg[120], *path = apr_pstrdup(p, fname); /* * first course of business is to grok all the directory @@ -1518,10 +1477,7 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { /* strip out '.' and '..' */ if (strcmp(dirent.name, ".") - && strcmp(dirent.name, "..") - && (!ispatt || - apr_fnmatch(pattern, dirent.name, - FNM_PERIOD) == APR_SUCCESS)) { + && strcmp(dirent.name, "..")) { fnew = (fnames *) apr_array_push(candidates); fnew->fname = ap_make_full_path(p, path, dirent.name); } @@ -1538,7 +1494,8 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, */ for (current = 0; current < candidates->nelts; ++current) { fnew = &((fnames *) candidates->elts)[current]; - ap_process_resource_config(s, fnew->fname, conftree, p, ptemp); + process_resource_config_nofnmatch(s, fnew->fname, conftree, p, + ptemp); } } @@ -1546,7 +1503,6 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, } /* GCC's initialization extensions are soooo nice here... */ - parms = default_parms; parms.pool = p; parms.temp_pool = ptemp; @@ -1575,6 +1531,107 @@ AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, } ap_cfg_closefile(cfp); + + return; +} + +AP_DECLARE(void) ap_process_resource_config(server_rec *s, const char *fname, + ap_directive_t **conftree, + apr_pool_t *p, + apr_pool_t *ptemp) +{ + /* XXX: lstat() won't work on the wildcard pattern... + */ + + /* don't require conf/httpd.conf if we have a -C or -c switch */ + if ((ap_server_pre_read_config->nelts + || ap_server_post_read_config->nelts) + && !(strcmp(fname, ap_server_root_relative(p, SERVER_CONFIG_FILE)))) { + apr_finfo_t finfo; + + if (apr_lstat(&finfo, fname, APR_FINFO_TYPE, p) != APR_SUCCESS) + return; + } + + if (!apr_fnmatch_test(fname)) { + process_resource_config_nofnmatch(s, fname, conftree, p, ptemp); + } + else { + apr_dir_t *dirp; + apr_finfo_t dirent; + int current; + apr_array_header_t *candidates = NULL; + fnames *fnew; + apr_status_t rv; + char errmsg[120], *path = apr_pstrdup(p, fname), *pattern = NULL; + + pattern = ap_strrchr(path, '/'); + + AP_DEBUG_ASSERT(pattern != NULL); /* path must be absolute. */ + + *pattern++ = '\0'; + + if (apr_fnmatch_test(path)) { + fprintf(stderr, "%s: wildcard patterns not allowed in Include " + "%s\n", ap_server_argv0, fname); + exit(1); + } + + if (!ap_is_rdirectory(p, path)){ + fprintf(stderr, "%s: Include directory '%s' not found", + ap_server_argv0, path); + exit(1); + } + + if (!apr_fnmatch_test(pattern)) { + fprintf(stderr, "%s: must include a wildcard pattern " + "for Include %s\n", ap_server_argv0, fname); + exit(1); + } + + /* + * first course of business is to grok all the directory + * entries here and store 'em away. Recall we need full pathnames + * for this. + */ + rv = apr_dir_open(&dirp, path, p); + if (rv != APR_SUCCESS) { + fprintf(stderr, "%s: could not open config directory %s: %s\n", + ap_server_argv0, path, + apr_strerror(rv, errmsg, sizeof errmsg)); + exit(1); + } + + candidates = apr_array_make(p, 1, sizeof(fnames)); + while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { + /* strip out '.' and '..' */ + if (strcmp(dirent.name, ".") + && strcmp(dirent.name, "..") + && (apr_fnmatch(pattern, dirent.name, + FNM_PERIOD) == APR_SUCCESS)) { + fnew = (fnames *) apr_array_push(candidates); + fnew->fname = ap_make_full_path(p, path, dirent.name); + } + } + + apr_dir_close(dirp); + if (candidates->nelts != 0) { + qsort((void *) candidates->elts, candidates->nelts, + sizeof(fnames), fname_alphasort); + + /* + * Now recurse these... we handle errors and subdirectories + * via the recursion, which is nice + */ + for (current = 0; current < candidates->nelts; ++current) { + fnew = &((fnames *) candidates->elts)[current]; + process_resource_config_nofnmatch(s, fnew->fname, conftree, p, + ptemp); + } + } + } + + return; } AP_DECLARE(int) ap_process_config_tree(server_rec *s, -- 2.50.1