]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Security fix for CVE-2009-1195: fix Options handling such that
authorJoe Orton <jorton@apache.org>
Fri, 8 May 2009 14:13:15 +0000 (14:13 +0000)
committerJoe Orton <jorton@apache.org>
Fri, 8 May 2009 14:13:15 +0000 (14:13 +0000)
'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 <j.s.peatfield damtp.cam.ac.uk>,
          jorton
Thanks to: Vincent Danon <vdanon redhat.com>

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@772997 13f79535-47bb-0310-9956-ffa450edef68

include/http_core.h
modules/filters/mod_include.c
server/config.c
server/core.c

index 1c34c783a42343c0ef4e2a73d8dfc00dd67fa20a..da4b8e6c80fc1239e0f7a7a62ddaaa708e456353 100644 (file)
@@ -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)
 /** @} */
 
 /**
index 623c74a0cd9e01efd7128d55b84f000efb5a1fc9..63637e35961897b9b6106b5e3553d15dc0a60ea3 100644 (file)
@@ -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;
index fa14cf614fc317e47f23167f8355ab1bf0a0dc26..01fb76a1ea289235c0ad5b90dc67be532f3870cc 100644 (file)
@@ -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);
index b9deb75da0a2d1440f480eb61d0527d3142c72c0..ad6494ff77236e449f0d59382e6f3f88b5474373 100644 (file)
@@ -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;