From: Arran Cudbard-Bell Date: Wed, 17 Mar 2021 16:04:51 +0000 (+0000) Subject: Various fixes X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4dee69641344d74767c1dec5b00182eb00b0f476;p=thirdparty%2Ffreeradius-server.git Various fixes --- diff --git a/src/lib/server/tmpl_eval.c b/src/lib/server/tmpl_eval.c index 74e5b4c43dd..3de06213cf2 100644 --- a/src/lib/server/tmpl_eval.c +++ b/src/lib/server/tmpl_eval.c @@ -557,7 +557,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out, xlat_escape_legacy_t escape, void const *escape_ctx, fr_type_t dst_type) { - fr_value_box_t const *to_cast = NULL; + fr_value_box_t *to_cast = NULL; fr_value_box_t from_cast; fr_pair_t *vp = NULL; @@ -687,7 +687,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out, { RDEBUG4("EXPAND TMPL DATA"); - to_cast = tmpl_value(vpt); + to_cast = UNCONST(fr_value_box_t *, tmpl_value(vpt)); switch (to_cast->type) { case FR_TYPE_STRING: case FR_TYPE_OCTETS: diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 4738e1688d7..de97d672aee 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -1827,16 +1827,16 @@ static xlat_action_t xlat_func_bin(TALLOC_CTX *ctx, fr_dcursor_t *out, uint8_t *bin; size_t len, outlen; fr_sbuff_parse_error_t err; - fr_value_box_t *in_head; + fr_value_box_t *hex; - in_head = fr_dlist_head(in); - len = in_head->vb_length; + hex = fr_dlist_head(in); + len = hex->vb_length; if ((len > 1) && (len & 0x01)) { REDEBUG("Input data length must be >1 and even, got %zu", len); return XLAT_ACTION_FAIL; } - p = in_head->vb_strvalue; + p = hex->vb_strvalue; end = p + len; /* @@ -1940,24 +1940,30 @@ static xlat_arg_parser_t const xlat_func_hex_arg = { * * @ingroup xlat_functions */ -static xlat_action_t xlat_func_hex(TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request, +static xlat_action_t xlat_func_hex(UNUSED TALLOC_CTX *ctx, fr_dcursor_t *out, UNUSED request_t *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, fr_value_box_list_t *in) { - char *p; - fr_value_box_t* vb; - fr_value_box_t* in_head; - - in_head = fr_dlist_head(in); + char *new_buff; + fr_value_box_t *bin = fr_dlist_pop_head(in); /* First argument */ - MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false)); - vb->vb_length = (in_head->vb_length * 2); - vb->vb_strvalue = p = talloc_zero_array(vb, char, vb->vb_length + 1); - if (in_head->vb_length) { - fr_bin2hex(&FR_SBUFF_OUT(p, talloc_array_length(p)), &FR_DBUFF_TMP(in_head->vb_octets, in_head->vb_length), SIZE_MAX); + /* + * Use existing box, but with new buffer + */ + MEM(new_buff = talloc_zero_array(bin, char, (bin->vb_length * 2) + 1)); + if (bin->vb_length) { + fr_bin2hex(&FR_SBUFF_OUT(new_buff, (bin->vb_length * 2) + 1), + &FR_DBUFF_TMP(bin->vb_octets, bin->vb_length), SIZE_MAX); + fr_value_box_clear_value(bin); + fr_value_box_strdup_shallow(bin, NULL, new_buff, bin->tainted); + /* + * Zero length binary > zero length hex string + */ + } else { + fr_value_box_clear_value(bin); + fr_value_box_strdup(bin, bin, NULL, "", bin->tainted); } - - fr_dcursor_append(out, vb); + fr_dcursor_append(out, bin); return XLAT_ACTION_DONE; } diff --git a/src/lib/unlang/xlat_eval.c b/src/lib/unlang/xlat_eval.c index 41f569ca6cf..6c0eb55d89e 100644 --- a/src/lib/unlang/xlat_eval.c +++ b/src/lib/unlang/xlat_eval.c @@ -1037,25 +1037,27 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_thread_inst_t *thread_inst; fr_value_box_list_t result_copy; - fr_value_box_list_init(&result_copy); thread_inst = xlat_thread_instance_find(node); XLAT_DEBUG("** [%i] %s(func-async) - %%{%s:%pM}", unlang_interpret_stack_depth(request), __FUNCTION__, node->fmt, result); + VALUE_BOX_LIST_VERIFY(result); /* * Need to copy the input list in case * the async function mucks with it. */ - if (RDEBUG_ENABLED2) fr_value_box_list_acopy(NULL, &result_copy, result); - - VALUE_BOX_LIST_VERIFY(result); + if (RDEBUG_ENABLED2) { + fr_value_box_list_init(&result_copy); + fr_value_box_list_acopy(NULL, &result_copy, result); + } xa = xlat_process_args(ctx, result, request, node->call.func->input_type, node->call.func->args); if (xa == XLAT_ACTION_FAIL) { if (RDEBUG_ENABLED2) fr_dlist_talloc_free(&result_copy); return xa; } + VALUE_BOX_LIST_VERIFY(result); xa = node->call.func->func.async(ctx, out, request, node->call.inst->data, thread_inst->data, result); @@ -1170,6 +1172,8 @@ xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_debug_log_expansion(request, *in, NULL); xlat_debug_log_result(request, value); + VALUE_BOX_VERIFY(value); + fr_dcursor_insert(out, value); } break; @@ -1228,6 +1232,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t con for (node = *in; node; node = (*in)->next) { *in = node; /* Update node in our caller */ fr_dcursor_tail(out); /* Needed for debugging */ + VALUE_BOX_LIST_VERIFY(out->dlist); switch (node->type) { case XLAT_LITERAL: @@ -1380,6 +1385,7 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t con } finish: + VALUE_BOX_LIST_VERIFY(out->dlist); XLAT_DEBUG("** [%i] %s << %s", unlang_interpret_stack_depth(request), __FUNCTION__, fr_table_str_by_value(xlat_action_table, xa, "")); diff --git a/src/lib/util/dlist.h b/src/lib/util/dlist.h index bb1889e4e71..d0de511a2ed 100644 --- a/src/lib/util/dlist.h +++ b/src/lib/util/dlist.h @@ -565,7 +565,7 @@ static inline void *fr_dlist_replace(fr_dlist_head_t *list_head, void *item, voi * Does nothing if the list was not initialised with #fr_dlist_talloc_init. */ #ifndef TALLOC_GET_TYPE_ABORT_NOOP -static inline CC_HINT(nonnull) void fr_dlist_verify(char const *file, int line, fr_dlist_head_t *list_head) +static inline CC_HINT(nonnull) void fr_dlist_verify(char const *file, int line, fr_dlist_head_t const *list_head) { void *item; diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 6a0a325ac60..073fc858e8a 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -492,6 +492,15 @@ static inline void fr_value_box_copy_meta(fr_value_box_t *dst, fr_value_box_t co case FR_TYPE_VARIABLE_SIZE: dst->vb_length = src->vb_length; break; + /* + * Not 100% sure this should be done here + * but if the intent is to make a null + * box usable, then we need to do this + * somewhere. + */ + case FR_TYPE_GROUP: + fr_value_box_list_init(&dst->vb_group); + break; default: break; @@ -3148,7 +3157,7 @@ void fr_value_box_clear_value(fr_value_box_t *data) talloc_free(data->datum.ptr); break; - case FR_TYPE_STRUCTURAL: + case FR_TYPE_GROUP: /* * Depth first freeing of children * @@ -3158,7 +3167,7 @@ void fr_value_box_clear_value(fr_value_box_t *data) { fr_value_box_t *vb = NULL; - while ((vb = fr_dlist_next(&data->datum.children, vb))) { + while ((vb = fr_dlist_next(&data->vb_group, vb))) { fr_value_box_clear_value(vb); talloc_free(vb); } @@ -3207,6 +3216,7 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t memcpy(((uint8_t *)dst) + fr_value_box_offsets[src->type], ((uint8_t const *)src) + fr_value_box_offsets[src->type], fr_value_box_field_sizes[src->type]); + fr_value_box_copy_meta(dst, src); break; case FR_TYPE_STRING: @@ -3222,6 +3232,7 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t return -1; } dst->vb_strvalue = str; + fr_value_box_copy_meta(dst, src); } break; @@ -3238,11 +3249,41 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t talloc_set_type(bin, uint8_t); } dst->vb_octets = bin; + fr_value_box_copy_meta(dst, src); } break; - } - fr_value_box_copy_meta(dst, src); + case FR_TYPE_GROUP: + { + fr_value_box_t *child; + + fr_value_box_copy_meta(dst, src); /* Initialises group child dlist */ + + while ((child = fr_dlist_next(&src->vb_group, child))) { + fr_value_box_t *new; + + /* + * Build out the child + */ + new = fr_value_box_alloc_null(ctx); + if (unlikely(!new)) { + group_error: + fr_strerror_const("Failed duplicating group child"); + fr_dlist_talloc_free(&dst->vb_group); + return -1; + } + + /* + * Populate it with the + * data from the original + * child. + */ + if (unlikely(fr_value_box_copy(new, new, child) < 0)) goto group_error; + fr_dlist_insert_tail(&dst->vb_group, new); + } + } + break; + } return 0; } @@ -3282,7 +3323,7 @@ void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_bo * - 0 on success. * - -1 on failure. */ -int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src) +int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t *src) { if (!fr_cond_assert(src->type != FR_TYPE_NULL)) return -1; @@ -3302,6 +3343,7 @@ int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons talloc_set_type(str, char); dst->vb_strvalue = str; fr_value_box_copy_meta(dst, src); + memset(&src->datum, 0, sizeof(src->datum)); } return 0; @@ -3318,6 +3360,22 @@ int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons dst->vb_octets = bin; fr_value_box_copy_meta(dst, src); + memset(&src->datum, 0, sizeof(src->datum)); + } + return 0; + + case FR_TYPE_GROUP: + { + fr_value_box_t *child; + + while ((child = fr_dlist_pop_head(&src->vb_group))) { + child = talloc_steal(ctx, child); + if (unlikely(!child)) { + fr_strerror_const("Failed stealing child"); + return -1; + } + fr_dlist_insert_tail(&dst->vb_group, child); + } } return 0; } @@ -5213,9 +5271,9 @@ void value_box_verify(char const *file, int line, fr_value_box_t const *vb) void value_box_list_verify(char const *file, int line, fr_value_box_list_t const *list) { - fr_value_box_t const *vb; + fr_value_box_t const *vb = NULL; FR_DLIST_VERIFY(list); - while ((vb = fr_dlist_next(list, vb))) value_box_verify(file, line, list); + while ((vb = fr_dlist_next(list, vb))) value_box_verify(file, line, vb); } diff --git a/src/lib/util/value.h b/src/lib/util/value.h index 466fce1d4b8..feb84d336dd 100644 --- a/src/lib/util/value.h +++ b/src/lib/util/value.h @@ -314,7 +314,7 @@ static inline bool fr_value_box_list_len_min(fr_value_box_list_t const *list, si */ static inline void fr_value_box_list_init(fr_value_box_list_t *list) { - fr_dlist_talloc_init(list, fr_value_box_t, entry); + fr_dlist_init(list, fr_value_box_t, entry); /* Not always talloced */ } /** @} */ @@ -623,7 +623,7 @@ int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_ void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src); -int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *src); +int fr_value_box_steal(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t *src); /** @} */ /** @name Assign and manipulate binary-unsafe C strings