]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Have the fuzzer search in its own symbols pace first before dynamically loading the...
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 22 Mar 2024 16:07:13 +0000 (12:07 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 22 Mar 2024 16:07:13 +0000 (12:07 -0400)
This allows the binary to be statically or dynamically linked to fuzzing targets, which may help producing accurate coverage stats.

src/bin/fuzzer.c

index 82f7b0ff1369cab864ab1ddc720a48a3e8d31d61..00d239e18b6b32dda6b22f460a680fe2bc97c124 100644 (file)
@@ -68,6 +68,31 @@ static void exitHandler(void)
        fr_atexit_global_trigger_all();
 }
 
+static inline
+fr_dict_protocol_t *fuzzer_dict_init(void *dl_handle, char const *proto)
+{
+       char                    buffer[256];
+       fr_dict_protocol_t      *our_dl_proto;
+
+       snprintf(buffer, sizeof(buffer), "libfreeradius_%s_dict_protocol", proto);
+
+       our_dl_proto = dlsym(dl_handle, buffer);
+       if (our_dl_proto && our_dl_proto->init() && (our_dl_proto->init() < 0)) {
+               fr_perror("fuzzer: Failed initializing library %s", buffer);
+               fr_exit_now(EXIT_FAILURE);
+       }
+
+       return our_dl_proto;
+}
+
+static inline
+fr_test_point_proto_decode_t *fuzzer_test_point(void *dl_handle, char const *proto)
+{
+       char                    buffer[256];
+       snprintf(buffer, sizeof(buffer), "%s_tp_decode_proto", proto);
+       return dlsym(dl_handle, buffer);
+}
+
 int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
        char const              *lib_dir        = getenv("FR_LIBRARY_PATH");
@@ -208,33 +233,36 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
         */
        fr_hostname_lookups = fr_reverse_lookups = false;
 
-       dl_loader = dl_loader_init(NULL, NULL, 0, false);
-       if (!dl_loader) {
-               fr_perror("fuzzer: Failed initializing library loader");
-               fr_exit_now(EXIT_FAILURE);
-       }
-
-       snprintf(buffer, sizeof(buffer), "libfreeradius-%s", proto);
-       dl = dl_by_name(dl_loader, buffer, NULL, false);
-       if (!dl) {
-               fr_perror("fuzzer: Failed loading library %s", buffer);
-               fr_exit_now(EXIT_FAILURE);
-       }
-
-       snprintf(buffer, sizeof(buffer), "libfreeradius_%s_dict_protocol", proto);
+       /*
+        *      Search in our symbol space first.  We may have been dynamically
+        *      or statically linked to the library we're fuzzing...
+        */
+       dl_proto = fuzzer_dict_init(RTLD_SELF, proto);
+       tp = fuzzer_test_point(RTLD_SELF, proto);
 
-       dl_proto = dlsym(dl->handle, buffer);
-       if (dl_proto && dl_proto->init() && (dl_proto->init() < 0)) {
-               fr_perror("fuzzer: Failed initializing library %s", buffer);
-               fr_exit_now(EXIT_FAILURE);
-       }
+       /*
+        *      Failed to find the test point, try and load it in
+        *      dynamically from the protocol library.
+        */
+       if (!tp) {
+               dl_loader = dl_loader_init(NULL, NULL, 0, false);
+               if (!dl_loader) {
+                       fr_perror("fuzzer: Failed initializing library loader");
+                       fr_exit_now(EXIT_FAILURE);
+               }
 
-       snprintf(buffer, sizeof(buffer), "%s_tp_decode_proto", proto);
+               snprintf(buffer, sizeof(buffer), "libfreeradius-%s", proto);
+               dl = dl_by_name(dl_loader, buffer, NULL, false);
+               if (!dl) {
+                       fr_perror("fuzzer: Failed loading library %s", buffer);
+                       fr_exit_now(EXIT_FAILURE);
+               }
 
-       tp = dlsym(dl->handle, buffer);
-       if (!tp) {
-               fr_perror("fuzzer: Failed finding test point %s", buffer);
-               fr_exit_now(EXIT_FAILURE);
+               if (!dl_proto) dl_proto = fuzzer_dict_init(dl->handle, proto);
+               if (!tp && !(tp = fuzzer_test_point(dl->handle, proto))) {
+                       fr_perror("fuzzer: Failed finding test point %s", buffer);
+                       fr_exit_now(EXIT_FAILURE);
+               }
        }
 
        init = true;