Commit 51eee5bf4c for strongswan.org

commit 51eee5bf4ce7dcdc832961b3c822db90a829b092
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Fri Oct 30 11:31:15 2026 +0100

    fuzz: Make fuzzers more efficient by implementing LLVMFuzzerInitialize

    This avoids the library init/deinit cycle and plugin load/unload for each
    input.

    Also fixed the error handling in `LLVMFuzzerInitialize()` because the
    drivers don't actually handle the return value (neither our local one,
    nor the one by libFuzzer).

diff --git a/fuzz/fuzz_certs.c b/fuzz/fuzz_certs.c
index a64701d828..760d47ddfb 100644
--- a/fuzz/fuzz_certs.c
+++ b/fuzz/fuzz_certs.c
@@ -17,24 +17,27 @@
 #include <library.h>
 #include <utils/debug.h>

-int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
-	certificate_t *cert;
-	chunk_t chunk;
-
 	dbg_default_set_level(-1);
 	library_init(NULL, "fuzz_certs");
 	if (!lib->plugins->load(lib->plugins, PLUGINS))
 	{
-		return 1;
+		fprintf(stderr, "failed to load plugins\n");
+		exit(1);
 	}
+	atexit(library_deinit);
+	return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+{
+	certificate_t *cert;
+	chunk_t chunk;

 	chunk = chunk_create((u_char*)buf, len);
 	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
 							  BUILD_BLOB, chunk, BUILD_END);
 	DESTROY_IF(cert);
-
-	lib->plugins->unload(lib->plugins);
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_crls.c b/fuzz/fuzz_crls.c
index ea735e1b93..6a3104ad17 100644
--- a/fuzz/fuzz_crls.c
+++ b/fuzz/fuzz_crls.c
@@ -17,24 +17,27 @@
 #include <library.h>
 #include <utils/debug.h>

-int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
-	certificate_t *cert;
-	chunk_t chunk;
-
 	dbg_default_set_level(-1);
 	library_init(NULL, "fuzz_crls");
 	if (!lib->plugins->load(lib->plugins, PLUGINS))
 	{
-		return 1;
+		fprintf(stderr, "failed to load plugins\n");
+		exit(1);
 	}
+	atexit(library_deinit);
+	return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+{
+	certificate_t *cert;
+	chunk_t chunk;

 	chunk = chunk_create((u_char*)buf, len);
 	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
 							  BUILD_BLOB, chunk, BUILD_END);
 	DESTROY_IF(cert);
-
-	lib->plugins->unload(lib->plugins);
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_ids.c b/fuzz/fuzz_ids.c
index 5c6b344a58..41605a5a42 100644
--- a/fuzz/fuzz_ids.c
+++ b/fuzz/fuzz_ids.c
@@ -17,6 +17,14 @@
 #include <library.h>
 #include <utils/debug.h>

+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+	dbg_default_set_level(-1);
+	library_init(NULL, "fuzz_ids");
+	atexit(library_deinit);
+	return 0;
+}
+
 int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 {
 	identification_t *id, *clone;
@@ -25,9 +33,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	id_part_t part;
 	char str_buf[BUF_LEN], min_buf[3];

-	dbg_default_set_level(-1);
-	library_init(NULL, "fuzz_ids");
-
 	chunk = chunk_create((u_char*)buf, len);
 	id = identification_create_from_data(chunk);
 	if (id)
@@ -51,7 +56,5 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	snprintf(str_buf, sizeof(str_buf), "%Y", id);
 	snprintf(min_buf, sizeof(min_buf), "%Y", id);
 	DESTROY_IF(id);
-
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_ocsp_req.c b/fuzz/fuzz_ocsp_req.c
index f6fd276bf9..50b23762a5 100644
--- a/fuzz/fuzz_ocsp_req.c
+++ b/fuzz/fuzz_ocsp_req.c
@@ -17,24 +17,27 @@
 #include <library.h>
 #include <utils/debug.h>

-int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
-	certificate_t *cert;
-	chunk_t chunk;
-
 	dbg_default_set_level(-1);
 	library_init(NULL, "fuzz_ocsp_req");
 	if (!lib->plugins->load(lib->plugins, PLUGINS))
 	{
-		return 1;
+		fprintf(stderr, "failed to load plugins\n");
+		exit(1);
 	}
+	atexit(library_deinit);
+	return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+{
+	certificate_t *cert;
+	chunk_t chunk;

 	chunk = chunk_create((u_char*)buf, len);
 	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
 							  BUILD_BLOB, chunk, BUILD_END);
 	DESTROY_IF(cert);
-
-	lib->plugins->unload(lib->plugins);
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_ocsp_rsp.c b/fuzz/fuzz_ocsp_rsp.c
index fe91317cbf..1b40b5f2c9 100644
--- a/fuzz/fuzz_ocsp_rsp.c
+++ b/fuzz/fuzz_ocsp_rsp.c
@@ -17,24 +17,27 @@
 #include <library.h>
 #include <utils/debug.h>

-int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
-	certificate_t *cert;
-	chunk_t chunk;
-
 	dbg_default_set_level(-1);
 	library_init(NULL, "fuzz_ocsp_rsp");
 	if (!lib->plugins->load(lib->plugins, PLUGINS))
 	{
-		return 1;
+		fprintf(stderr, "failed to load plugins\n");
+		exit(1);
 	}
+	atexit(library_deinit);
+	return 0;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+{
+	certificate_t *cert;
+	chunk_t chunk;

 	chunk = chunk_create((u_char*)buf, len);
 	cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
 							  BUILD_BLOB, chunk, BUILD_END);
 	DESTROY_IF(cert);
-
-	lib->plugins->unload(lib->plugins);
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_pa_tnc.c b/fuzz/fuzz_pa_tnc.c
index 8271d43be0..eb9d3ce9fd 100644
--- a/fuzz/fuzz_pa_tnc.c
+++ b/fuzz/fuzz_pa_tnc.c
@@ -20,6 +20,16 @@
 #include <ietf/ietf_attr_pa_tnc_error.h>
 #include <utils/debug.h>

+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+	dbg_default_set_level(-1);
+	library_init(NULL, "fuzz_pa_tnc");
+	libimcv_init(FALSE);
+	atexit(library_deinit);
+	atexit(libimcv_deinit);
+	return 0;
+}
+
 int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 {
 	pa_tnc_msg_t *msg;
@@ -29,10 +39,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	enumerator_t *enumerator;
 	chunk_t chunk;

-	dbg_default_set_level(-1);
-	library_init(NULL, "fuzz_pa_tnc");
-	libimcv_init(FALSE);
-
 	chunk = chunk_create((u_char*)buf, len);

 	/* Parse incoming PA-TNC message */
@@ -62,8 +68,5 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	enumerator->destroy(enumerator);

 	msg->destroy(msg);
-
-	libimcv_deinit();
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_pb_tnc.c b/fuzz/fuzz_pb_tnc.c
index a1636fcd99..b31b1eba30 100644
--- a/fuzz/fuzz_pb_tnc.c
+++ b/fuzz/fuzz_pb_tnc.c
@@ -20,6 +20,14 @@
 #include <state_machine/pb_tnc_state_machine.h>
 #include <utils/debug.h>

+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+	dbg_default_set_level(-1);
+	library_init(NULL, "fuzz_pb_tnc");
+	atexit(library_deinit);
+	return 0;
+}
+
 int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 {
 	pb_tnc_batch_t *batch;
@@ -30,9 +38,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	bool from_server;
 	chunk_t chunk;

-	dbg_default_set_level(-1);
-	library_init(NULL, "fuzz_pb_tnc");
-
 	chunk = chunk_create((u_char*)buf, len);

 	INIT(state,
@@ -68,6 +73,5 @@ int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
 	batch->destroy(batch);

 	free(state);
-	library_deinit();
 	return 0;
 }
diff --git a/fuzz/fuzz_radius.c b/fuzz/fuzz_radius.c
index 7cc18baf3d..071528a213 100644
--- a/fuzz/fuzz_radius.c
+++ b/fuzz/fuzz_radius.c
@@ -24,7 +24,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
 	library_init(NULL, "fuzz_radius");
 	if (!lib->plugins->load(lib->plugins, PLUGINS))
 	{
-		return 1;
+		fprintf(stderr, "failed to load plugins\n");
+		exit(1);
 	}
 	atexit(library_deinit);
 	return 0;
diff --git a/fuzz/fuzz_tls.c b/fuzz/fuzz_tls.c
index ee72f70c81..984a18da94 100644
--- a/fuzz/fuzz_tls.c
+++ b/fuzz/fuzz_tls.c
@@ -147,7 +147,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
 	library_init(NULL, "fuzz_tls");
 	if (!lib->plugins->load(lib->plugins, PLUGINS))
 	{
-		return 1;
+		fprintf(stderr, "failed to load plugins\n");
+		exit(1);
 	}
 	atexit(library_deinit);
 	setup_cert();