From: Alan T. DeKok Date: Tue, 22 Nov 2022 13:37:23 +0000 (-0500) Subject: add tmpl_attr_unspec X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1eedcb4de8403ab3fc372c97792d55f82767c3b;p=thirdparty%2Ffreeradius-server.git add tmpl_attr_unspec 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" --- diff --git a/src/lib/server/tmpl_eval.c b/src/lib/server/tmpl_eval.c index 2eb6bee0f18..deb1bb85a20 100644 --- a/src/lib/server/tmpl_eval.c +++ b/src/lib/server/tmpl_eval.c @@ -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); } diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index 7ab992fa476..fbd41863ebf 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -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 "