]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add tmpl_attr_unspec
authorAlan T. DeKok <aland@freeradius.org>
Tue, 22 Nov 2022 13:37:23 +0000 (08:37 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 22 Nov 2022 13:37:23 +0000 (08:37 -0500)
because otherwise tmpl_attr_tail_da() returns NULL when we have
constructs like %{control.[*]}.  And there are just too many
places in the code which do things like:

tmpl_attr_tail_da()->type

All of those are potential crash points if that function returns
NULL.

Instead, we add a canonical "unspec" attribute.  It has no name,
numbered zero, is "unknown", and is of FR_TYPE_NULL.  This allows
it to pass all of the derefencing code with "it will never match"

src/lib/server/tmpl_eval.c
src/lib/server/tmpl_tokenize.c

index 2eb6bee0f18931876fc08da897fcffada96e136d..deb1bb85a2029176f5ab659e00705ac5c56ae7f8 100644 (file)
@@ -62,6 +62,7 @@ static fr_dict_attr_t const *attr_packet_authentication_vector;
 static fr_dict_attr_t const *attr_request_processing_stage;
 static fr_dict_attr_t const *attr_virtual_server;
 static fr_dict_attr_t const *attr_module_return_code;
+fr_dict_attr_t const *tmpl_attr_unspec;
 
 static fr_dict_attr_autoload_t tmpl_dict_attr[] = {
        { .out = &attr_client_ip_address, .name = "Client-IP-Address", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_freeradius },
@@ -1612,6 +1613,8 @@ int tmpl_eval_cast(TALLOC_CTX *ctx, FR_DLIST_HEAD(fr_value_box_list) *list, tmpl
 
 int tmpl_global_init(void)
 {
+       fr_dict_attr_t *da;
+
        if (fr_dict_autoload(tmpl_dict) < 0) {
                PERROR("%s", __FUNCTION__);
                return -1;
@@ -1622,10 +1625,18 @@ int tmpl_global_init(void)
                return -1;
        }
 
+       da = fr_dict_unknown_attr_afrom_num(NULL, fr_dict_root(dict_freeradius), 0);
+       fr_assert(da != NULL);
+
+       da->type = FR_TYPE_NULL;
+       tmpl_attr_unspec = da;
+
        return 0;
 }
 
 void tmpl_global_free(void)
 {
        fr_dict_autofree(tmpl_dict);
+
+       fr_dict_unknown_free(&tmpl_attr_unspec);
 }
index 7ab992fa4762860fceed7af4ee28e46f390a0924..fbd41863ebf35af538fe9ddf858518f76b199320 100644 (file)
@@ -1397,6 +1397,8 @@ static fr_slen_t tmpl_attr_parse_filter(tmpl_attr_error_t *err, tmpl_attr_t *ar,
        FR_SBUFF_SET_RETURN(name, &our_name);
 }
 
+extern fr_dict_attr_t const *tmpl_attr_unspec;
+
 static inline CC_HINT(nonnull(3,4))
 fr_slen_t tmpl_attr_ref_from_unspecified_substr(tmpl_attr_t *ar, tmpl_attr_error_t *err,
                                                tmpl_t *vpt,
@@ -1407,6 +1409,7 @@ fr_slen_t tmpl_attr_ref_from_unspecified_substr(tmpl_attr_t *ar, tmpl_attr_error
        *ar = (tmpl_attr_t){
                .ar_num = NUM_UNSPEC,   /* May be changed by tmpl_attr_parse_filter */
                .ar_type = TMPL_ATTR_TYPE_UNSPEC,
+               .ar_da = tmpl_attr_unspec,
        };
 
        slen = tmpl_attr_parse_filter(err, ar, name, t_rules);
@@ -4915,6 +4918,11 @@ void tmpl_verify(char const *file, int line, tmpl_t const *vpt)
                                             file, line);
                }
 
+               if (tmpl_attr_tail_da(vpt) == tmpl_attr_unspec) {
+                       fr_assert(vpt->rules.cast == FR_TYPE_NULL);
+                       break;
+               }
+
                if (tmpl_attr_tail_da(vpt)->flags.is_unknown) {
                        if (tmpl_attr_tail_da(vpt) != tmpl_attr_tail_unknown(vpt)) {
                                fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_ATTR "