]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add and use FR_VALUE_BOX_SAFE_FOR_ANY
authorAlan T. DeKok <aland@freeradius.org>
Mon, 10 Mar 2025 12:31:03 +0000 (08:31 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 27 Mar 2025 18:56:05 +0000 (14:56 -0400)
which lets us *not* escape data which is taken from the
configuration files

disable the regex escape test for now.  We don't want a regex.safe()
function.  We want a "escape this string, even tho it's value is safe"
function

src/lib/server/cf_file.c
src/lib/server/cf_parse.c
src/lib/server/users_file.c
src/lib/server/virtual_servers.c
src/lib/unlang/xlat_builtin.c
src/lib/util/value.c
src/lib/util/value.h
src/modules/rlm_linelog/rlm_linelog.c
src/modules/rlm_radius/rlm_radius.c
src/tests/keywords/regex-escape.ignore [moved from src/tests/keywords/regex-escape with 100% similarity]
src/tests/keywords/regex-lhs

index 32adc935a19bc43e4cfe003f22cbf348331ea5ba..2a8a7ca88030b16ea9e6cdc594f3dc613b1660b4 100644 (file)
@@ -1543,7 +1543,8 @@ static CONF_ITEM *process_if(cf_stack_t *stack)
                        .list_def = request_attr_request,
                        .allow_unresolved = true,
                        .allow_unknown = true
-               }
+               },
+               .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
        };
 
        /*
index 13d917df95f1982cfa7e57af6967f365394d633e..1854df4ed559acb05606d332e63ac91073979cbf 100644 (file)
@@ -220,7 +220,8 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM
                                                        .allow_unknown = true,
                                                        .allow_unresolved = true,
                                                        .allow_foreign = true,
-                                               }
+                                               },
+                                               .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
                                        };
                fr_sbuff_t              sbuff = FR_SBUFF_IN(cp->value, strlen(cp->value));
 
index a769b8579b76bfc7a97b09749ddfd86978cbf1aa..9f6345918a66b9242386c16045243c277dfcacc7 100644 (file)
@@ -273,7 +273,9 @@ static int pairlist_read_internal(TALLOC_CTX *ctx, fr_dict_t const *dict, char c
                        .prefix = TMPL_ATTR_REF_PREFIX_AUTO,
                        .list_def = request_attr_request,
                        .list_presence = TMPL_ATTR_LIST_ALLOW,
-               }
+               },
+               .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
+
        };
        rhs_rules = (tmpl_rules_t) {
                .attr = {
@@ -282,7 +284,8 @@ static int pairlist_read_internal(TALLOC_CTX *ctx, fr_dict_t const *dict, char c
                        .list_def = request_attr_request,
                        .list_presence = TMPL_ATTR_LIST_ALLOW,
                        .bare_word_enum = v3_compat,
-               }
+               },
+               .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
        };
 
        while (true) {
index 4cf8d2fc1cb6226b19b9122d8d70c48c3baed8a8..578f0203c28c76d7de5fe6645281f0ea987ec7cc 100644 (file)
@@ -1619,6 +1619,8 @@ int virtual_servers_instantiate(void)
                                        .dict_def = dict,
                                        .list_def = request_attr_request,
                                },
+
+                               .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
                        };
 
                        fr_assert(parse_rules.attr.dict_def != NULL);
index 0e9f9fc023a161da1958b383f9b80f0adf5804aa..38574f58fb011d4c9604104a7914efafc49e77b0 100644 (file)
@@ -758,6 +758,7 @@ static xlat_action_t xlat_func_taint(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out,
 
                while ((child = fr_value_box_list_pop_head(&vb->vb_group)) != NULL) {
                        child->tainted = true;
+                       fr_value_box_mark_unsafe(child);
 
                        fr_dcursor_append(out, child);
                }
index a71d38778ad4dd93c7c5786d321d36f4885d242a..0b380a198e5ab75905b00d247b9b8ac5a9409f6e 100644 (file)
@@ -6358,6 +6358,16 @@ void fr_value_box_list_verify(char const *file, int line, fr_value_box_list_t co
  */
 void _fr_value_box_mark_safe_for(fr_value_box_t *vb, fr_value_box_safe_for_t safe_for)
 {
+       /*
+        *      Don't over-ride value-boxes which are already safe, unless we want to mark them as being
+        *      completely unsafe.
+        */
+       if ((vb->safe_for == FR_VALUE_BOX_SAFE_FOR_ANY) &&
+           (safe_for != FR_VALUE_BOX_SAFE_FOR_NONE)) {
+               fr_assert(!vb->tainted);
+               return;
+       }
+
        vb->safe_for = safe_for;
 }
 
@@ -6367,7 +6377,7 @@ void _fr_value_box_mark_safe_for(fr_value_box_t *vb, fr_value_box_safe_for_t saf
  */
 void fr_value_box_mark_unsafe(fr_value_box_t *vb)
 {
-       vb->safe_for = 0;
+       vb->safe_for = FR_VALUE_BOX_SAFE_FOR_NONE;
 }
 
 /** Set the escaped flag for all value boxes in a list
@@ -6379,7 +6389,17 @@ void fr_value_box_mark_unsafe(fr_value_box_t *vb)
  */
 void fr_value_box_list_mark_safe_for(fr_value_box_list_t *list, fr_value_box_safe_for_t safe_for)
 {
-       fr_value_box_list_foreach(list, vb) vb->safe_for = safe_for;
+       fr_value_box_list_foreach(list, vb) {
+               /*
+                *      Don't over-ride value-boxes which are already safe.
+                */
+               if (vb->safe_for == FR_VALUE_BOX_SAFE_FOR_ANY) {
+                       fr_assert(!vb->tainted);
+
+               } else {
+                       vb->safe_for = safe_for;
+               }
+       }
 }
 
 /** Check truthiness of values.
index 208084ca8f3681eb26891d412ffa8b5e1fa2e776..0bdc37cb24234669032f4676d58eb6b6e81ec3e7 100644 (file)
@@ -154,6 +154,17 @@ typedef union {
  */
 typedef uintptr_t fr_value_box_safe_for_t;
 
+/*
+ *     The default value of "completely unsafe" is zero.  That way any initialization routines will default
+ *     to marking the data as unsafe.
+ *
+ *     The only data which should be marked as being completely safe is data taken from the configuration
+ *     files which are managed by the administrator.  Data create by end users (e.g. passwords) should always
+ *     be marked as unsafe.
+ */
+#define FR_VALUE_BOX_SAFE_FOR_NONE ((uintptr_t) 0)
+#define FR_VALUE_BOX_SAFE_FOR_ANY (~((uintptr_t) 0))
+
 /** Union containing all data types supported by the server
  *
  * This union contains all data types that can be represented by fr_pair_ts. It may also be used in other parts
@@ -1052,7 +1063,7 @@ void              _fr_value_box_mark_safe_for(fr_value_box_t *box, fr_value_box_safe_for_t s
 void           fr_value_box_mark_unsafe(fr_value_box_t *box)
                CC_HINT(nonnull);
 
-#define                fr_value_box_is_safe_for(_box, _safe_for) (_box->safe_for == (fr_value_box_safe_for_t)_safe_for)
+#define                fr_value_box_is_safe_for(_box, _safe_for) ((_box->safe_for == (fr_value_box_safe_for_t)_safe_for) || (_box->safe_for == FR_VALUE_BOX_SAFE_FOR_ANY))
 
 void           fr_value_box_list_mark_safe_for(fr_value_box_list_t *list, fr_value_box_safe_for_t safe_for);
 
index 8c14898f0dbdffd8bded94313b48aa8009ff6f2d..212b45cc154282ae575e8854c8c0e44af9d95fef 100644 (file)
@@ -767,7 +767,8 @@ static unlang_action_t CC_HINT(nonnull) mod_do_linelog(rlm_rcode_t *p_result, mo
                                                .xlat = {
                                                        .runtime_el = unlang_interpret_event_list(request),
                                                },
-                                               .at_runtime = true
+                                               .at_runtime = true,
+                                               .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
                                         });
                if (!vpt) {
                        REMARKER(tmpl_str, -slen, "%s", fr_strerror());
index 2176b3a9d084f1328e62a10b1e61f80724a432f4..fa7bd460d17a8c3e3598699b46b7de57909c5762 100644 (file)
@@ -498,7 +498,8 @@ static int status_check_update_parse(TALLOC_CTX *ctx, void *out, void *parent,
                                .list_def = request_attr_request,
                                .list_presence = TMPL_ATTR_LIST_FORBID,
                                .prefix = TMPL_ATTR_REF_PREFIX_AUTO,
-                       }
+                       },
+                       .literals_safe_for = FR_VALUE_BOX_SAFE_FOR_ANY,
                };
 
                rcode = map_afrom_cs(ctx, head, cs, &parse_rules, &parse_rules, status_check_verify, parent, 128);
index d52a3a6ea09c84e1ac1c4723f7471357c2f39d79..179589ec1d128ce3f308f4d9fb85b34cce8b9c9b 100644 (file)
@@ -1,5 +1,5 @@
 #
-#  PRE: if regex-escape
+#  PRE: if
 #
 string test_string1
 string test_string2