From: Alan T. DeKok Date: Wed, 10 Dec 2025 04:14:25 +0000 (-0500) Subject: enable encoder in fuzzers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a420a09953992d1a45916a703a6088495a3fc6a;p=thirdparty%2Ffreeradius-server.git enable encoder in fuzzers now that we've fixed many (most?) issues with the code, we can start to automatically test the encoders. Instead of having a separate fuzzer test for the encoders, we just use the fuzzer input to decode attributes, and then call the encoder with the attributes we just found. This should be a reasonable test of all kinds of odd behavior --- diff --git a/src/bin/fuzzer.c b/src/bin/fuzzer.c index 2fdafeb3b51..a60cc26a92a 100644 --- a/src/bin/fuzzer.c +++ b/src/bin/fuzzer.c @@ -47,6 +47,7 @@ static TALLOC_CTX *autofree = NULL; static fr_dict_t *dict = NULL; extern fr_test_point_proto_decode_t XX_PROTOCOL_XX_tp_decode_proto; +extern fr_test_point_proto_encode_t XX_PROTOCOL_XX_tp_encode_proto; int LLVMFuzzerInitialize(int *argc, char ***argv); int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len); @@ -254,25 +255,45 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) return 1; } +static uint8_t encoded_data[65536]; + int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { TALLOC_CTX * ctx = talloc_init_const("fuzzer"); fr_pair_list_t vps; void *decode_ctx = NULL; - fr_test_point_proto_decode_t *tp = &XX_PROTOCOL_XX_tp_decode_proto; + void *encode_ctx = NULL; + fr_test_point_proto_decode_t *tp_decode = &XX_PROTOCOL_XX_tp_decode_proto; + fr_test_point_proto_encode_t *tp_encode = &XX_PROTOCOL_XX_tp_encode_proto; fr_pair_list_init(&vps); if (!init) LLVMFuzzerInitialize(NULL, NULL); - if (tp->test_ctx && (tp->test_ctx(&decode_ctx, NULL, dict, NULL) < 0)) { + if (tp_decode->test_ctx && (tp_decode->test_ctx(&decode_ctx, NULL, dict, NULL) < 0)) { fr_perror("fuzzer: Failed initializing test point decode_ctx"); fr_exit_now(EXIT_FAILURE); } - tp->func(ctx, &vps, buf, len, decode_ctx); - if (fr_debug_lvl > 3) fr_pair_list_debug(stderr, &vps); + if (tp_encode->test_ctx && (tp_encode->test_ctx(&encode_ctx, NULL, dict, NULL) < 0)) { + fr_perror("fuzzer: Failed initializing test point encode_ctx"); + fr_exit_now(EXIT_FAILURE); + } + + /* + * Decode the input, and print the resulting data if we + * decoded it successfully. + * + * If we have successfully decoded the data, then encode + * it again, too. + */ + if (tp_decode->func(ctx, &vps, buf, len, decode_ctx) > 0) { + if (fr_debug_lvl > 3) fr_pair_list_debug(stderr, &vps); + + (void) tp_encode->func(ctx, &vps, encoded_data, sizeof(encoded_data), encode_ctx); + } talloc_free(decode_ctx); + talloc_free(encode_ctx); talloc_free(ctx); /* diff --git a/src/lib/util/fuzzer.c b/src/lib/util/fuzzer.c index fb8d615b2d3..d090423f2a0 100644 --- a/src/lib/util/fuzzer.c +++ b/src/lib/util/fuzzer.c @@ -62,8 +62,20 @@ static ssize_t util_decode_proto(TALLOC_CTX *ctx, UNUSED fr_pair_list_t *out, ui return rcode; } +static ssize_t util_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, UNUSED void *proto_ctx) +{ + return fr_pair_list_print(&FR_SBUFF_OUT((char *) data, data_len), NULL, vps); +} + + extern fr_test_point_proto_decode_t util_tp_decode_proto; fr_test_point_proto_decode_t util_tp_decode_proto = { .test_ctx = decode_test_ctx, .func = util_decode_proto }; + +extern fr_test_point_proto_encode_t util_tp_encode_proto; +fr_test_point_proto_encode_t util_tp_encode_proto = { + .test_ctx = decode_test_ctx, + .func = util_encode_proto +};