From: Alan T. DeKok Date: Wed, 22 Apr 2020 15:54:48 +0000 (-0400) Subject: allow for truncation of output buffers X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c4243db673ce2823ea6cec971643d6f7ef66b633;p=thirdparty%2Ffreeradius-server.git allow for truncation of output buffers and test for it --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 8e33b195dd9..b295768371d 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -221,6 +221,7 @@ static ssize_t xlat_test(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED size_ static char proto_name_prev[128]; static dl_t *dl; static dl_loader_t *dl_loader; +static size_t max_packet_size = 0; size_t process_line(command_result_t *result, command_ctx_t *cc, char *data, size_t data_used, char *in, size_t inlen); static int process_file(bool *exit_now, TALLOC_CTX *ctx, @@ -1478,7 +1479,7 @@ static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc, char *p = in; uint8_t encoded[(COMMAND_OUTPUT_MAX / 2) - 1]; - uint8_t *enc_p = encoded, *enc_end = enc_p + sizeof(encoded); + uint8_t *enc_p = encoded, *enc_end; VALUE_PAIR *head = NULL, *vp; slen = load_test_point_by_command((void **)&tp, p, "tp_encode_pair"); @@ -1501,6 +1502,11 @@ static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc, RETURN_OK_WITH_ERROR(); } + enc_end = enc_p + sizeof(encoded); + if (max_packet_size && (max_packet_size < sizeof(encoded))) { + enc_end = enc_p + max_packet_size; + } + for (vp = fr_cursor_talloc_iter_init(&cursor, &head, tp->next_encodable ? tp->next_encodable : fr_proto_next_encodable, cc->active_dict ? cc->active_dict : cc->config->dict, VALUE_PAIR); vp; @@ -1563,8 +1569,9 @@ static size_t command_encode_proto(command_result_t *result, command_ctx_t *cc, ssize_t slen; char *p = in; - uint8_t encoded[(COMMAND_OUTPUT_MAX / 2) - 1]; VALUE_PAIR *head = NULL; + size_t encoded_len; + uint8_t encoded[(COMMAND_OUTPUT_MAX / 2) - 1]; slen = load_test_point_by_command((void **)&tp, p, "tp_encode_proto"); if (!tp) { @@ -1586,7 +1593,15 @@ static size_t command_encode_proto(command_result_t *result, command_ctx_t *cc, RETURN_OK_WITH_ERROR(); } - slen = tp->func(cc->tmp_ctx, head, encoded, sizeof(encoded), encoder_ctx); + /* + * Artificially limit the maximum packet size. + */ + encoded_len = sizeof(encoded); + if (max_packet_size && (max_packet_size < encoded_len)) { + encoded_len = max_packet_size; + } + + slen = tp->func(cc->tmp_ctx, head, encoded, encoded_len, encoder_ctx); fr_pair_list_free(&head); cc->last_ret = slen; if (slen < 0) { @@ -1675,6 +1690,25 @@ static size_t command_match_regex(command_result_t *result, command_ctx_t *cc, } } +/** Artificially limit the maximum packet size. + * + */ +static size_t command_max_packet_size(command_result_t *result, UNUSED command_ctx_t *cc, + char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen) +{ + unsigned long size; + char *end; + + size = strtoul(in, &end, 10); + if ((size == ULONG_MAX) || *end || (size >= 65536)) { + fr_strerror_printf_push("Invalid integer"); + RETURN_COMMAND_ERROR(); + } + + max_packet_size = size; + RETURN_OK(snprintf(data, COMMAND_OUTPUT_MAX, "%ld", max_packet_size)); +} + /** Skip the test file if we're missing a particular feature * */ @@ -2121,6 +2155,11 @@ static fr_table_ptr_sorted_t commands[] = { .usage = "match-regex ", .description = "Compare the contents of the data buffer with a regular expression" }}, + { "max_packet_size", &(command_entry_t){ + .func = command_max_packet_size, + .usage = "max_packet_size ", + .description = "Limit the maximum packet size for encode-proto" + }}, { "need-feature ", &(command_entry_t){ .func = command_need_feature, .usage = "need-feature ", diff --git a/src/tests/unit/protocols/radius/truncate.txt b/src/tests/unit/protocols/radius/truncate.txt new file mode 100644 index 00000000000..9296ee95947 --- /dev/null +++ b/src/tests/unit/protocols/radius/truncate.txt @@ -0,0 +1,23 @@ +# +# Correctly truncate encoded attributes / packets +# +proto radius +proto-dictionary radius + +max_packet_size 32 +match 32 + +encode-pair User-Name = "0123456789a123456789b123456789c123456789d123456789e123456789f" +match 01 20 30 31 32 33 34 35 36 37 38 39 61 31 32 33 34 35 36 37 38 39 62 31 32 33 34 35 36 37 38 39 + +decode-pair - +match User-Name = "0123456789a123456789b123456789" + +encode-pair User-Password = "0123456789a123456789b123456789c123456789d123456789e123456789f" +match 02 20 a6 df 3b f9 40 c8 4c 2d 28 7f 66 15 32 27 b6 be dc 8f f1 2a 7f cc b6 58 f9 d1 08 64 6b d2 + +decode-pair - +match User-Password = "0123456789a123456789b123456789" + +count +match 12