From: Joe Orton Date: Fri, 8 May 2009 14:13:15 +0000 (+0000) Subject: Security fix for CVE-2009-1195: fix Options handling such that X-Git-Tag: 2.3.3~635 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=489bc420ddbbb3ba7bd6f4b8b8e44fc4183deaf0;p=thirdparty%2Fapache%2Fhttpd.git Security fix for CVE-2009-1195: fix Options handling such that 'AllowOverride Options=IncludesNoExec' does not permit Includes with exec= enabled to be configured in an .htaccess file: * include/http_core.h: Change semantics of Includes/IncludeNoExec options bits to be additive; OPT_INCLUDES now means SSI is enabled without exec=. OPT_INCLUDES|OPT_INC_WITH_EXEC means SSI is enabled with exec=. * server/core.c (create_core_dir_config): Remove defunct OPT_INCNOEXEC from default override_opts; no functional change. (merge_core_dir_configs): Update logic to ensure that exec= is disabled in a context where IncludesNoexec is configured, even if Includes-with-exec is permitted in the inherited options set. (set_allow_opts, set_options): Update to reflect new semantics of OPT_INCLUDES, OPT_INC_WITH_EXEC. * server/config.c: Update to remove OPT_INCNOEXEC from default override_opts; no functional change. * modules/filters/mod_include.c (includes_filter): Update to reflect new options semantics - disable exec= support if the OPT_INC_WITH_EXEC bit is not set. Submitted by: Jonathan Peatfield , jorton Thanks to: Vincent Danon git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@772997 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/http_core.h b/include/http_core.h index 1c34c783a42..da4b8e6c80f 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -68,7 +68,7 @@ extern "C" { #define OPT_NONE 0 /** Indexes directive */ #define OPT_INDEXES 1 -/** Includes directive */ +/** SSI is enabled without exec= permission */ #define OPT_INCLUDES 2 /** FollowSymLinks directive */ #define OPT_SYM_LINKS 4 @@ -76,14 +76,14 @@ extern "C" { #define OPT_EXECCGI 8 /** directive unset */ #define OPT_UNSET 16 -/** IncludesNOEXEC directive */ -#define OPT_INCNOEXEC 32 +/** SSI exec= permission is permitted, iff OPT_INCLUDES is also set */ +#define OPT_INC_WITH_EXEC 32 /** SymLinksIfOwnerMatch directive */ #define OPT_SYM_OWNER 64 /** MultiViews directive */ #define OPT_MULTI 128 /** All directives */ -#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_SYM_LINKS|OPT_EXECCGI) +#define OPT_ALL (OPT_INDEXES|OPT_INCLUDES|OPT_INC_WITH_EXEC|OPT_SYM_LINKS|OPT_EXECCGI) /** @} */ /** diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index 623c74a0cd9..63637e35961 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -2946,7 +2946,7 @@ static apr_status_t includes_filter(ap_filter_t *f, apr_bucket_brigade *b) intern->seen_eos = 0; intern->state = PARSE_PRE_HEAD; ctx->flags = (SSI_FLAG_PRINTING | SSI_FLAG_COND_TRUE); - if (ap_allow_options(r) & OPT_INCNOEXEC) { + if ((ap_allow_options(r) & OPT_INC_WITH_EXEC) == 0) { ctx->flags |= SSI_FLAG_NO_EXEC; } intern->access_func = conf->accessenable ? ssi_access : NULL; diff --git a/server/config.c b/server/config.c index fa14cf614fc..01fb76a1ea2 100644 --- a/server/config.c +++ b/server/config.c @@ -1524,7 +1524,7 @@ static const char *process_command_config(server_rec *s, parms.temp_pool = ptemp; parms.server = s; parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); - parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; + parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; parms.config_file = ap_pcfg_open_custom(p, "-c/-C directives", &arr_parms, NULL, @@ -1631,7 +1631,7 @@ static const char *process_resource_config_nofnmatch(server_rec *s, parms.temp_pool = ptemp; parms.server = s; parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); - parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; + parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; rv = ap_pcfg_openfile(&cfp, p, fname); if (rv != APR_SUCCESS) { @@ -1769,7 +1769,7 @@ AP_DECLARE(int) ap_process_config_tree(server_rec *s, parms.temp_pool = ptemp; parms.server = s; parms.override = (RSRC_CONF | OR_ALL) & ~(OR_AUTHCFG | OR_LIMIT); - parms.override_opts = OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER | OPT_MULTI; + parms.override_opts = OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; parms.limited = -1; errmsg = ap_walk_config(conftree, &parms, s->lookup_defaults); diff --git a/server/core.c b/server/core.c index b9deb75da0a..ad6494ff772 100644 --- a/server/core.c +++ b/server/core.c @@ -108,8 +108,7 @@ static void *create_core_dir_config(apr_pool_t *a, char *dir) conf->opts = dir ? OPT_UNSET : OPT_UNSET|OPT_ALL; conf->opts_add = conf->opts_remove = OPT_NONE; conf->override = dir ? OR_UNSET : OR_UNSET|OR_ALL; - conf->override_opts = OPT_UNSET | OPT_ALL | OPT_INCNOEXEC | OPT_SYM_OWNER - | OPT_MULTI; + conf->override_opts = OPT_UNSET | OPT_ALL | OPT_SYM_OWNER | OPT_MULTI; conf->content_md5 = 2; conf->accept_path_info = 3; @@ -239,8 +238,13 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv) conf->opts_remove = (conf->opts_remove & ~new->opts_add) | new->opts_remove; conf->opts = (conf->opts & ~conf->opts_remove) | conf->opts_add; - if ((base->opts & OPT_INCNOEXEC) && (new->opts & OPT_INCLUDES)) { - conf->opts = (conf->opts & ~OPT_INCNOEXEC) | OPT_INCLUDES; + + /* if Includes was enabled without exec in the new config, but + * was enabled with exec in the base, then disable exec in the + * resulting options. */ + if ((base->opts & OPT_INC_WITH_EXEC) + && (new->opts & OPT_INC_WITH_EXEC) == 0) { + conf->opts &= ~OPT_INC_WITH_EXEC; } } else { @@ -1287,10 +1291,12 @@ static const char *set_allow_opts(cmd_parms *cmd, allow_options_t *opts, opt = OPT_INDEXES; } else if (!strcasecmp(w, "Includes")) { - opt = OPT_INCLUDES; + /* If Includes is permitted, both Includes and + * IncludesNOEXEC may be changed. */ + opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC); } else if (!strcasecmp(w, "IncludesNOEXEC")) { - opt = (OPT_INCLUDES | OPT_INCNOEXEC); + opt = OPT_INCLUDES; } else if (!strcasecmp(w, "FollowSymLinks")) { opt = OPT_SYM_LINKS; @@ -1406,10 +1412,10 @@ static const char *set_options(cmd_parms *cmd, void *d_, const char *l) opt = OPT_INDEXES; } else if (!strcasecmp(w, "Includes")) { - opt = OPT_INCLUDES; + opt = (OPT_INCLUDES | OPT_INC_WITH_EXEC); } else if (!strcasecmp(w, "IncludesNOEXEC")) { - opt = (OPT_INCLUDES | OPT_INCNOEXEC); + opt = OPT_INCLUDES; } else if (!strcasecmp(w, "FollowSymLinks")) { opt = OPT_SYM_LINKS;