]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
enable encoder in fuzzers
authorAlan T. DeKok <aland@freeradius.org>
Wed, 10 Dec 2025 04:14:25 +0000 (23:14 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 10 Dec 2025 19:28:00 +0000 (14:28 -0500)
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

src/bin/fuzzer.c
src/lib/util/fuzzer.c

index 2fdafeb3b51305e1e8ff14d52d26c25e9f02bc3d..a60cc26a92ab4dece0ed4d3bb7b21da8f68bcd1f 100644 (file)
@@ -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);
 
        /*
index fb8d615b2d3ce920132915bf1fe4384b97ae0e74..d090423f2a0c3d26361d4a5c9ab7c7261ebbc6a1 100644 (file)
@@ -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
+};