svn commit: r1935017 - in httpd/httpd/branches/2.4.x: . include modules/mappers modules/metadata modules/proxy server

[email protected] Fri, 05 Jun 2026 10:28:53 -0000
Newsgroups gmane.comp.apache.cvs
Message-ID <178065533339.3081346.1182214834425408212@svn03-he-fi>
Author: covener
Date: Fri Jun  5 10:28:53 2026
New Revision: 1935017

Log:
Merge r1935016 from trunk:

restrict per-dir file funcs centrally

Reviewed By: covener, jorton, jfclere

Modified:
   httpd/httpd/branches/2.4.x/   (props changed)
   httpd/httpd/branches/2.4.x/include/ap_expr.h
   httpd/httpd/branches/2.4.x/modules/mappers/mod_rewrite.c
   httpd/httpd/branches/2.4.x/modules/metadata/mod_setenvif.c
   httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_fcgi.c
   httpd/httpd/branches/2.4.x/server/util_expr_eval.c

Modified: httpd/httpd/branches/2.4.x/include/ap_expr.h
==============================================================================
--- httpd/httpd/branches/2.4.x/include/ap_expr.h	Fri Jun  5 10:27:34 2026	(r1935016)
+++ httpd/httpd/branches/2.4.x/include/ap_expr.h	Fri Jun  5 10:28:53 2026	(r1935017)
@@ -66,6 +66,8 @@ typedef struct {
 #define AP_EXPR_FLAG_RESTRICTED            4
 /** Expression evaluates to a string, not to a bool */
 #define AP_EXPR_FLAG_STRING_RESULT         8
+/** Don't allow functions/vars that expose content from the filesystem. */
+#define AP_EXPR_FLAG_RESTRICTED_FILE_FUNC   16
 
 
 /**

Modified: httpd/httpd/branches/2.4.x/modules/mappers/mod_rewrite.c
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/mappers/mod_rewrite.c	Fri Jun  5 10:27:34 2026	(r1935016)
+++ httpd/httpd/branches/2.4.x/modules/mappers/mod_rewrite.c	Fri Jun  5 10:28:53 2026	(r1935017)
@@ -3682,8 +3682,6 @@ static const char *cmd_rewritecond(cmd_p
         int in_htaccess = cmd->pool == cmd->temp_pool;
         unsigned int flags = newcond->flags & CONDFLAG_NOVARY ?
                              AP_EXPR_FLAG_DONT_VARY : 0;
-        /* Use restricted ap_expr() parser in htaccess context. */
-        if (in_htaccess) flags |= AP_EXPR_FLAG_RESTRICTED;
         newcond->expr = ap_expr_parse_cmd(cmd, a2, flags, &err, NULL);
         if (err)
             return apr_psprintf(cmd->pool, "RewriteCond: cannot compile "

Modified: httpd/httpd/branches/2.4.x/modules/metadata/mod_setenvif.c
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/metadata/mod_setenvif.c	Fri Jun  5 10:27:34 2026	(r1935016)
+++ httpd/httpd/branches/2.4.x/modules/metadata/mod_setenvif.c	Fri Jun  5 10:28:53 2026	(r1935017)
@@ -424,11 +424,6 @@ static const char *add_setenvifexpr(cmd_
     const char *err;
     unsigned int flags = 0;
 
-    /* Use restricted ap_expr() parser in htaccess context. */
-    if (cmd->pool == cmd->temp_pool) {
-        flags |= AP_EXPR_FLAG_RESTRICTED;
-    }
-
     /*
      * Determine from our context into which record to put the entry.
      * cmd->path == NULL means we're in server-wide context; otherwise,

Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_fcgi.c
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_fcgi.c	Fri Jun  5 10:27:34 2026	(r1935016)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_fcgi.c	Fri Jun  5 10:28:53 2026	(r1935017)
@@ -1340,11 +1340,6 @@ static const char *cmd_setenv(cmd_parms
     const char *envvar = arg2;
     unsigned int flags = 0;
 
-    /* Use restricted ap_expr() parser in htaccess context. */
-    if (cmd->pool == cmd->temp_pool) {
-        flags |= AP_EXPR_FLAG_RESTRICTED;
-    }
-
     new = apr_array_push(dconf->env_fixups);
     new->cond = ap_expr_parse_cmd(cmd, arg1, flags, &err, NULL);
     if (err) {

Modified: httpd/httpd/branches/2.4.x/server/util_expr_eval.c
==============================================================================
--- httpd/httpd/branches/2.4.x/server/util_expr_eval.c	Fri Jun  5 10:27:34 2026	(r1935016)
+++ httpd/httpd/branches/2.4.x/server/util_expr_eval.c	Fri Jun  5 10:28:53 2026	(r1935017)
@@ -437,6 +437,12 @@ AP_DECLARE(ap_expr_info_t*) ap_expr_pars
     info->line_number = cmd->directive->line_num;
     info->flags = flags;
     info->module_index = module_index;
+
+    /* Use restricted-contents ap_expr() parser in htaccess context. */
+    if (cmd->pool == cmd->temp_pool) {
+        info->flags |= AP_EXPR_FLAG_RESTRICTED_FILE_FUNC;
+    }
+
     *err = ap_expr_parse(cmd->pool, cmd->temp_pool, info, expr, lookup_fn);
 
     if (*err)
@@ -1661,11 +1667,15 @@ static int op_strcmatch(ap_expr_eval_ctx
     return (APR_SUCCESS == apr_fnmatch(arg2, arg1, APR_FNM_CASE_BLIND));
 }
 
+#define RESTRICTED_FILE_TEST 0x01
+#define RESTRICTED_FILE_FUNC 0x02
+#define RESTRICTED_ALL      (RESTRICTED_FILE_TEST | RESTRICTED_FILE_FUNC)
+
 struct expr_provider_single {
     const void *func;
     const char *name;
     ap_expr_lookup_fn_t *arg_parsing_func;
-    int restricted;
+    unsigned int restricted;
 };
 
 struct expr_provider_multi {
@@ -1695,8 +1705,8 @@ static const struct expr_provider_single
     { toupper_func,         "toupper",        NULL, 0 },
     { escape_func,          "escape",         NULL, 0 },
     { unescape_func,        "unescape",       NULL, 0 },
-    { file_func,            "file",           NULL, 1 },
-    { filesize_func,        "filesize",       NULL, 1 },
+    { file_func,            "file",           NULL, RESTRICTED_FILE_FUNC },
+    { filesize_func,        "filesize",       NULL, RESTRICTED_FILE_FUNC },
     { base64_func,          "base64",         NULL, 0 },
     { unbase64_func,        "unbase64",       NULL, 0 },
     { sha1_func,            "sha1",           NULL, 0 },
@@ -1712,13 +1722,13 @@ static const struct expr_provider_single
     { op_nz,        "z", NULL,             0 },
     { op_R,         "R", subnet_parse_arg, 0 },
     { op_T,         "T", NULL,             0 },
-    { op_file_min,  "d", NULL,             1 },
-    { op_file_min,  "e", NULL,             1 },
-    { op_file_min,  "f", NULL,             1 },
-    { op_file_min,  "s", NULL,             1 },
-    { op_file_link, "L", NULL,             1 },
-    { op_file_link, "h", NULL,             1 },
-    { op_file_xbit, "x", NULL,             1 },
+    { op_file_min,  "d", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_min,  "e", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_min,  "f", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_min,  "s", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_link, "L", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_link, "h", NULL,             RESTRICTED_FILE_TEST },
+    { op_file_xbit, "x", NULL,             RESTRICTED_FILE_TEST },
     { op_file_subr, "F", NULL,             0 },
     { op_url_subr,  "U", NULL,             0 },
     { op_url_subr,  "A", NULL,             0 },
@@ -1776,8 +1786,10 @@ static int core_expr_lookup(ap_expr_look
                 else
                     match = !ap_cstr_casecmp(prov->name, parms->name);
                 if (match) {
-                    if ((parms->flags & AP_EXPR_FLAG_RESTRICTED)
-                        && prov->restricted) {
+                    if (((parms->flags & AP_EXPR_FLAG_RESTRICTED)
+                         && (prov->restricted & RESTRICTED_ALL))
+                        || ((parms->flags & AP_EXPR_FLAG_RESTRICTED_FILE_FUNC)
+                            && (prov->restricted & RESTRICTED_FILE_FUNC))) {
                         *parms->err =
                             apr_psprintf(parms->ptemp,
                                          "%s%s not available in restricted context",