From 51e638b3d3a763c6c6eef2bf0a77cc57410bb8c6 Mon Sep 17 00:00:00 2001 From: Catena cyber <35799796+catenacyber@users.noreply.github.com> Date: Wed, 17 Oct 2018 19:41:44 +0200 Subject: [PATCH] [gnupg] Limit size of inputs for gnupg import fuzz target (#1871) * Limit size of inputs for gnupg import fuzz target And adds the targets out of the diff * Removes option limiting size for gnupg target import As it is done in the target itself * Removes max length options for fuzz targets in gnupg --- projects/gnupg/fuzz_decrypt.c | 146 ++++++ projects/gnupg/fuzz_decrypt.options | 2 + projects/gnupg/fuzz_import.c | 160 +++++++ projects/gnupg/fuzz_list.c | 163 +++++++ projects/gnupg/fuzz_list.options | 2 + projects/gnupg/fuzz_verify.c | 143 ++++++ projects/gnupg/fuzzgnupg.diff | 663 ---------------------------- 7 files changed, 616 insertions(+), 663 deletions(-) create mode 100644 projects/gnupg/fuzz_decrypt.c create mode 100644 projects/gnupg/fuzz_decrypt.options create mode 100644 projects/gnupg/fuzz_import.c create mode 100644 projects/gnupg/fuzz_list.c create mode 100644 projects/gnupg/fuzz_list.options create mode 100644 projects/gnupg/fuzz_verify.c diff --git a/projects/gnupg/fuzz_decrypt.c b/projects/gnupg/fuzz_decrypt.c new file mode 100644 index 000000000..c8c334a31 --- /dev/null +++ b/projects/gnupg/fuzz_decrypt.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "gpg.h" +#include "../common/types.h" +#include "../common/iobuf.h" +#include "keydb.h" +#include "keyedit.h" +#include "../common/util.h" +#include "main.h" +#include "call-dirmngr.h" +#include "trustdb.h" + +#include +#include +#include +#include +#include + +static bool initialized = false; +ctrl_t ctrlGlobal; +int fd; +char *filename; + +//hack not to include gpg.c which has main function +int g10_errors_seen = 0; + +void +g10_exit( int rc ) +{ + gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + gcry_control (GCRYCTL_TERM_SECMEM ); + exit (rc); +} + +static void +gpg_deinit_default_ctrl (ctrl_t ctrl) +{ +#ifdef USE_TOFU + tofu_closedbs (ctrl); +#endif + gpg_dirmngr_deinit_session_data (ctrl); + + keydb_release (ctrl->cached_getkey_kdb); +} + +static void +my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) +{ + return; +} + +static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) +{ + if (typeflag == FTW_F){ + unlink(fpath); + } + return 0; +} + +static void rmrfdir(char *path) +{ + ftw(path, unlink_cb, 16); + if (rmdir(path) != 0) { + printf("failed rmdir, errno=%d\n", errno); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + + if (! initialized) { + ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); + if (!ctrlGlobal) { + exit(1); + } + //deletes previous tmp dir and (re)create it as a ramfs + //system("umount /tmp/fuzzdirdecrypt"); + rmrfdir("/tmp/fuzzdirdecrypt"); + mkdir("/tmp/fuzzdirdecrypt", 0700); + //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirdecrypt"); + filename=strdup("/tmp/fuzzdirdecrypt/fuzz.gpg"); + if (!filename) { + free(ctrlGlobal); + return 0; + } + fd = open("/tmp/fuzzdirdecrypt/fuzz.gpg", O_RDWR | O_CREAT, 0600); + if (fd == -1) { + free(ctrlGlobal); + free(filename); + return 0; + } + gnupg_set_homedir("/tmp/fuzzdirdecrypt/"); + if (keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, + KEYDB_RESOURCE_FLAG_DEFAULT) != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + return 0; + } + if (setup_trustdb (1, NULL) != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + return 0; + } + //populate /tmp/fuzzdirdecrypt/ as homedir ~/.gnupg + strlist_t sl = NULL; + public_key_list (ctrlGlobal, sl, 0); + free_strlist(sl); + //no output for stderr + log_set_file("/tmp/fuzzdecrypt.log"); + gcry_set_log_handler (my_gcry_logger, NULL); + gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); + //overwrite output file + opt.batch = 1; + opt.answer_yes = 1; + initialized = true; + } + + memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + + if (ftruncate(fd, Size) == -1) { + return 0; + } + if (lseek (fd, 0, SEEK_SET) < 0) { + return 0; + } + if (write (fd, Data, Size) != Size) { + return 0; + } + + decrypt_messages(ctrlGlobal, 1, &filename); + gpg_deinit_default_ctrl (ctrlGlobal); + memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + decrypt_message(ctrlGlobal, filename); + gpg_deinit_default_ctrl (ctrlGlobal); + + return 0; +} diff --git a/projects/gnupg/fuzz_decrypt.options b/projects/gnupg/fuzz_decrypt.options new file mode 100644 index 000000000..83ee50897 --- /dev/null +++ b/projects/gnupg/fuzz_decrypt.options @@ -0,0 +1,2 @@ +[libfuzzer] +close_fd_mask = 1 diff --git a/projects/gnupg/fuzz_import.c b/projects/gnupg/fuzz_import.c new file mode 100644 index 000000000..499f7aacc --- /dev/null +++ b/projects/gnupg/fuzz_import.c @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "gpg.h" +#include "../common/types.h" +#include "../common/iobuf.h" +#include "keydb.h" +#include "keyedit.h" +#include "../common/util.h" +#include "main.h" +#include "call-dirmngr.h" +#include "trustdb.h" + +#include +#include +#include +#include +#include + +// 8kb should be enough ;-) +#define MAX_LEN 0x2000 + +static bool initialized = false; +ctrl_t ctrlGlobal; +int fd; +char *filename; + +//hack not to include gpg.c which has main function +int g10_errors_seen = 0; + +void +g10_exit( int rc ) +{ + gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + gcry_control (GCRYCTL_TERM_SECMEM ); + exit (rc); +} + +static void +gpg_deinit_default_ctrl (ctrl_t ctrl) +{ +#ifdef USE_TOFU + tofu_closedbs (ctrl); +#endif + gpg_dirmngr_deinit_session_data (ctrl); + + keydb_release (ctrl->cached_getkey_kdb); +} + +static void +my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) +{ + return; +} + +static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) +{ + if (typeflag == FTW_F){ + unlink(fpath); + } + return 0; +} + +static void rmrfdir(char *path) +{ + ftw(path, unlink_cb, 16); + if (rmdir(path) != 0) { + printf("failed rmdir, errno=%d\n", errno); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (! initialized) { + ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); + if (!ctrlGlobal) { + exit(1); + } + //deletes previous tmp dir and (re)create it as a ramfs + //system("umount /tmp/fuzzdirimport"); + rmrfdir("/tmp/fuzzdirimport"); + if (mkdir("/tmp/fuzzdirimport", 0700) < 0) { + printf("failed mkdir, errno=%d\n", errno); + if (errno != EEXIST) { + return 0; + } + } + //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirimport"); + filename=strdup("/tmp/fuzzdirimport/fuzz.gpg"); + if (!filename) { + free(ctrlGlobal); + return 0; + } + fd = open(filename, O_RDWR | O_CREAT, 0666); + if (fd == -1) { + free(filename); + free(ctrlGlobal); + printf("failed open, errno=%d\n", errno); + return 0; + } + gnupg_set_homedir("/tmp/fuzzdirimport/"); + gpg_error_t gpgerr = keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, KEYDB_RESOURCE_FLAG_DEFAULT); + if (gpgerr != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + printf("failed keydb_add_resource, errno=%d\n", gpgerr); + return 0; + } + gpgerr = setup_trustdb (1, NULL); + if (gpgerr != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + printf("failed setup_trustdb, errno=%d\n", gpgerr); + return 0; + } + //populate /tmp/fuzzdirimport/ as homedir ~/.gnupg + strlist_t sl = NULL; + public_key_list (ctrlGlobal, sl, 0); + free_strlist(sl); + //no output for stderr + log_set_file("/tmp/fuzzimport.log"); + gcry_set_log_handler (my_gcry_logger, NULL); + gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); + initialized = true; + } + + memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + if (Size > MAX_LEN) { + // limit maximum size to avoid long computing times + Size = MAX_LEN; + } + + if (ftruncate(fd, Size) == -1) { + return 0; + } + if (lseek (fd, 0, SEEK_SET) < 0) { + return 0; + } + if (write (fd, Data, Size) != Size) { + return 0; + } + + import_keys (ctrlGlobal, &filename, 1, NULL, IMPORT_REPAIR_KEYS, 0, NULL); + gpg_deinit_default_ctrl (ctrlGlobal); + /*memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + PKT_public_key pk; + get_pubkey_fromfile (ctrlGlobal, &pk, filename); + release_public_key_parts (&pk); + gpg_deinit_default_ctrl (ctrlGlobal);*/ + + return 0; +} diff --git a/projects/gnupg/fuzz_list.c b/projects/gnupg/fuzz_list.c new file mode 100644 index 000000000..937fdd5ea --- /dev/null +++ b/projects/gnupg/fuzz_list.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "gpg.h" +#include "../common/types.h" +#include "../common/iobuf.h" +#include "keydb.h" +#include "keyedit.h" +#include "../common/util.h" +#include "main.h" +#include "call-dirmngr.h" +#include "trustdb.h" + +#include +#include +#include +#include +#include + +static bool initialized = false; +ctrl_t ctrlGlobal; +int fd; +char *filename; + +//hack not to include gpg.c which has main function +int g10_errors_seen = 0; + +void +g10_exit( int rc ) +{ + gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + gcry_control (GCRYCTL_TERM_SECMEM ); + exit (rc); +} + +static void +gpg_deinit_default_ctrl (ctrl_t ctrl) +{ +#ifdef USE_TOFU + tofu_closedbs (ctrl); +#endif + gpg_dirmngr_deinit_session_data (ctrl); + + keydb_release (ctrl->cached_getkey_kdb); +} + +static void +my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) +{ + return; +} + +static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) +{ + if (typeflag == FTW_F){ + unlink(fpath); + } + return 0; +} + +static void rmrfdir(char *path) +{ + ftw(path, unlink_cb, 16); + if (rmdir(path) != 0) { + printf("failed rmdir, errno=%d\n", errno); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + IOBUF a; + armor_filter_context_t *afx = NULL; + + if (! initialized) { + ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); + if (!ctrlGlobal) { + exit(1); + } + //deletes previous tmp dir and (re)create it as a ramfs + //system("umount /tmp/fuzzdirlist"); + rmrfdir("/tmp/fuzzdirlist"); + if (mkdir("/tmp/fuzzdirlist", 0700) < 0) { + printf("failed mkdir, errno=%d\n", errno); + if (errno != EEXIST) { + return 0; + } + } + //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirlist"); + filename=strdup("/tmp/fuzzdirlist/fuzz.gpg"); + if (!filename) { + free(ctrlGlobal); + return 0; + } + fd = open(filename, O_RDWR | O_CREAT, 0666); + if (fd == -1) { + free(filename); + free(ctrlGlobal); + printf("failed open, errno=%d\n", errno); + return 0; + } + gnupg_set_homedir("/tmp/fuzzdirlist/"); + gpg_error_t gpgerr = keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, KEYDB_RESOURCE_FLAG_DEFAULT); + if (gpgerr != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + printf("failed keydb_add_resource, errno=%d\n", gpgerr); + return 0; + } + gpgerr = setup_trustdb (1, NULL); + if (gpgerr != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + printf("failed setup_trustdb, errno=%d\n", gpgerr); + return 0; + } + //populate /tmp/fuzzdirlist/ as homedir ~/.gnupg + strlist_t sl = NULL; + public_key_list (ctrlGlobal, sl, 0); + free_strlist(sl); + //no output for stderr + log_set_file("/tmp/fuzzlist.log"); + gcry_set_log_handler (my_gcry_logger, NULL); + gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); + opt.list_packets=1; + set_packet_list_mode(1); + initialized = true; + } + + memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + + if (ftruncate(fd, Size) == -1) { + return 0; + } + if (lseek (fd, 0, SEEK_SET) < 0) { + return 0; + } + if (write (fd, Data, Size) != Size) { + return 0; + } + + a = iobuf_open(filename); + if( !a ) { + printf("failed iobuf_open\n"); + return 0; + } + if( use_armor_filter( a ) ) { + afx = new_armor_context (); + push_armor_filter (afx, a); + } + proc_packets (ctrlGlobal, NULL, a ); + iobuf_close(a); + release_armor_context (afx); + gpg_deinit_default_ctrl (ctrlGlobal); + + return 0; +} diff --git a/projects/gnupg/fuzz_list.options b/projects/gnupg/fuzz_list.options new file mode 100644 index 000000000..83ee50897 --- /dev/null +++ b/projects/gnupg/fuzz_list.options @@ -0,0 +1,2 @@ +[libfuzzer] +close_fd_mask = 1 diff --git a/projects/gnupg/fuzz_verify.c b/projects/gnupg/fuzz_verify.c new file mode 100644 index 000000000..15412583f --- /dev/null +++ b/projects/gnupg/fuzz_verify.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "gpg.h" +#include "../common/types.h" +#include "../common/iobuf.h" +#include "keydb.h" +#include "keyedit.h" +#include "../common/util.h" +#include "main.h" +#include "call-dirmngr.h" +#include "trustdb.h" + +#include +#include +#include +#include +#include + +static bool initialized = false; +ctrl_t ctrlGlobal; +int fd; +char *filename; + +//hack not to include gpg.c which has main function +int g10_errors_seen = 0; + +void +g10_exit( int rc ) +{ + gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + gcry_control (GCRYCTL_TERM_SECMEM ); + exit (rc); +} + +static void +gpg_deinit_default_ctrl (ctrl_t ctrl) +{ +#ifdef USE_TOFU + tofu_closedbs (ctrl); +#endif + gpg_dirmngr_deinit_session_data (ctrl); + + keydb_release (ctrl->cached_getkey_kdb); +} + +static void +my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) +{ + return; +} + +static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) +{ + if (typeflag == FTW_F){ + unlink(fpath); + } + return 0; +} + +static void rmrfdir(char *path) +{ + ftw(path, unlink_cb, 16); + if (rmdir(path) != 0) { + printf("failed rmdir, errno=%d\n", errno); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + + if (! initialized) { + ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); + if (!ctrlGlobal) { + exit(1); + } + //deletes previous tmp dir and (re)create it as a ramfs + //system("umount /tmp/fuzzdirverify"); + rmrfdir("/tmp/fuzzdirverify"); + mkdir("/tmp/fuzzdirverify/", 0700); + //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirverify"); + filename=strdup("/tmp/fuzzdirverify/fuzz.gpg"); + if (!filename) { + free(ctrlGlobal); + return 0; + } + fd = open("/tmp/fuzzdirverify/fuzz.gpg", O_RDWR | O_CREAT, 0600); + if (fd == -1) { + free(ctrlGlobal); + free(filename); + return 0; + } + gnupg_set_homedir("/tmp/fuzzdirverify/"); + if (keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, + KEYDB_RESOURCE_FLAG_DEFAULT) != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + return 0; + } + if (setup_trustdb (1, NULL) != GPG_ERR_NO_ERROR) { + free(filename); + free(ctrlGlobal); + close(fd); + return 0; + } + //populate /tmp/fuzzdirverify/ as homedir ~/.gnupg + strlist_t sl = NULL; + public_key_list (ctrlGlobal, sl, 0); + free_strlist(sl); + //no output for stderr + log_set_file("/tmp/fuzzverify.log"); + gcry_set_log_handler (my_gcry_logger, NULL); + gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); + initialized = true; + } + + memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + + if (ftruncate(fd, Size) == -1) { + return 0; + } + if (lseek (fd, 0, SEEK_SET) < 0) { + return 0; + } + if (write (fd, Data, Size) != Size) { + return 0; + } + + verify_signatures(ctrlGlobal, 1, &filename); + gpg_deinit_default_ctrl (ctrlGlobal); + memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); + ctrlGlobal->magic = SERVER_CONTROL_MAGIC; + verify_files(ctrlGlobal, 1, &filename); + gpg_deinit_default_ctrl (ctrlGlobal); + + return 0; +} diff --git a/projects/gnupg/fuzzgnupg.diff b/projects/gnupg/fuzzgnupg.diff index 8cfdd6788..ee8949f90 100644 --- a/projects/gnupg/fuzzgnupg.diff +++ b/projects/gnupg/fuzzgnupg.diff @@ -320,666 +320,3 @@ index 000000000..3bf039a54 +# We need to depend on a couple of programs so that the tests don't +# start before all programs are built. +all-local: $(required_pgms) -diff --git a/tests/fuzz/fuzz_decrypt.c b/tests/fuzz/fuzz_decrypt.c -new file mode 100644 -index 000000000..c8c334a31 ---- /dev/null -+++ b/tests/fuzz/fuzz_decrypt.c -@@ -0,0 +1,146 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "gpg.h" -+#include "../common/types.h" -+#include "../common/iobuf.h" -+#include "keydb.h" -+#include "keyedit.h" -+#include "../common/util.h" -+#include "main.h" -+#include "call-dirmngr.h" -+#include "trustdb.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+static bool initialized = false; -+ctrl_t ctrlGlobal; -+int fd; -+char *filename; -+ -+//hack not to include gpg.c which has main function -+int g10_errors_seen = 0; -+ -+void -+g10_exit( int rc ) -+{ -+ gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); -+ gcry_control (GCRYCTL_TERM_SECMEM ); -+ exit (rc); -+} -+ -+static void -+gpg_deinit_default_ctrl (ctrl_t ctrl) -+{ -+#ifdef USE_TOFU -+ tofu_closedbs (ctrl); -+#endif -+ gpg_dirmngr_deinit_session_data (ctrl); -+ -+ keydb_release (ctrl->cached_getkey_kdb); -+} -+ -+static void -+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) -+{ -+ return; -+} -+ -+static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) -+{ -+ if (typeflag == FTW_F){ -+ unlink(fpath); -+ } -+ return 0; -+} -+ -+static void rmrfdir(char *path) -+{ -+ ftw(path, unlink_cb, 16); -+ if (rmdir(path) != 0) { -+ printf("failed rmdir, errno=%d\n", errno); -+ } -+} -+ -+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { -+ -+ if (! initialized) { -+ ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); -+ if (!ctrlGlobal) { -+ exit(1); -+ } -+ //deletes previous tmp dir and (re)create it as a ramfs -+ //system("umount /tmp/fuzzdirdecrypt"); -+ rmrfdir("/tmp/fuzzdirdecrypt"); -+ mkdir("/tmp/fuzzdirdecrypt", 0700); -+ //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirdecrypt"); -+ filename=strdup("/tmp/fuzzdirdecrypt/fuzz.gpg"); -+ if (!filename) { -+ free(ctrlGlobal); -+ return 0; -+ } -+ fd = open("/tmp/fuzzdirdecrypt/fuzz.gpg", O_RDWR | O_CREAT, 0600); -+ if (fd == -1) { -+ free(ctrlGlobal); -+ free(filename); -+ return 0; -+ } -+ gnupg_set_homedir("/tmp/fuzzdirdecrypt/"); -+ if (keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, -+ KEYDB_RESOURCE_FLAG_DEFAULT) != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ return 0; -+ } -+ if (setup_trustdb (1, NULL) != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ return 0; -+ } -+ //populate /tmp/fuzzdirdecrypt/ as homedir ~/.gnupg -+ strlist_t sl = NULL; -+ public_key_list (ctrlGlobal, sl, 0); -+ free_strlist(sl); -+ //no output for stderr -+ log_set_file("/tmp/fuzzdecrypt.log"); -+ gcry_set_log_handler (my_gcry_logger, NULL); -+ gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); -+ //overwrite output file -+ opt.batch = 1; -+ opt.answer_yes = 1; -+ initialized = true; -+ } -+ -+ memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ -+ if (ftruncate(fd, Size) == -1) { -+ return 0; -+ } -+ if (lseek (fd, 0, SEEK_SET) < 0) { -+ return 0; -+ } -+ if (write (fd, Data, Size) != Size) { -+ return 0; -+ } -+ -+ decrypt_messages(ctrlGlobal, 1, &filename); -+ gpg_deinit_default_ctrl (ctrlGlobal); -+ memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ decrypt_message(ctrlGlobal, filename); -+ gpg_deinit_default_ctrl (ctrlGlobal); -+ -+ return 0; -+} -diff --git a/tests/fuzz/fuzz_decrypt.options b/tests/fuzz/fuzz_decrypt.options -new file mode 100644 -index 000000000..9dd056806 ---- /dev/null -+++ b/tests/fuzz/fuzz_decrypt.options -@@ -0,0 +1,3 @@ -+[libfuzzer] -+max_len = 65536 -+close_fd_mask = 1 -diff --git a/tests/fuzz/fuzz_import.c b/tests/fuzz/fuzz_import.c -new file mode 100644 -index 000000000..3fd1f1c42 ---- /dev/null -+++ b/tests/fuzz/fuzz_import.c -@@ -0,0 +1,153 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "gpg.h" -+#include "../common/types.h" -+#include "../common/iobuf.h" -+#include "keydb.h" -+#include "keyedit.h" -+#include "../common/util.h" -+#include "main.h" -+#include "call-dirmngr.h" -+#include "trustdb.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+static bool initialized = false; -+ctrl_t ctrlGlobal; -+int fd; -+char *filename; -+ -+//hack not to include gpg.c which has main function -+int g10_errors_seen = 0; -+ -+void -+g10_exit( int rc ) -+{ -+ gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); -+ gcry_control (GCRYCTL_TERM_SECMEM ); -+ exit (rc); -+} -+ -+static void -+gpg_deinit_default_ctrl (ctrl_t ctrl) -+{ -+#ifdef USE_TOFU -+ tofu_closedbs (ctrl); -+#endif -+ gpg_dirmngr_deinit_session_data (ctrl); -+ -+ keydb_release (ctrl->cached_getkey_kdb); -+} -+ -+static void -+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) -+{ -+ return; -+} -+ -+static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) -+{ -+ if (typeflag == FTW_F){ -+ unlink(fpath); -+ } -+ return 0; -+} -+ -+static void rmrfdir(char *path) -+{ -+ ftw(path, unlink_cb, 16); -+ if (rmdir(path) != 0) { -+ printf("failed rmdir, errno=%d\n", errno); -+ } -+} -+ -+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { -+ if (! initialized) { -+ ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); -+ if (!ctrlGlobal) { -+ exit(1); -+ } -+ //deletes previous tmp dir and (re)create it as a ramfs -+ //system("umount /tmp/fuzzdirimport"); -+ rmrfdir("/tmp/fuzzdirimport"); -+ if (mkdir("/tmp/fuzzdirimport", 0700) < 0) { -+ printf("failed mkdir, errno=%d\n", errno); -+ if (errno != EEXIST) { -+ return 0; -+ } -+ } -+ //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirimport"); -+ filename=strdup("/tmp/fuzzdirimport/fuzz.gpg"); -+ if (!filename) { -+ free(ctrlGlobal); -+ return 0; -+ } -+ fd = open(filename, O_RDWR | O_CREAT, 0666); -+ if (fd == -1) { -+ free(filename); -+ free(ctrlGlobal); -+ printf("failed open, errno=%d\n", errno); -+ return 0; -+ } -+ gnupg_set_homedir("/tmp/fuzzdirimport/"); -+ gpg_error_t gpgerr = keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, KEYDB_RESOURCE_FLAG_DEFAULT); -+ if (gpgerr != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ printf("failed keydb_add_resource, errno=%d\n", gpgerr); -+ return 0; -+ } -+ gpgerr = setup_trustdb (1, NULL); -+ if (gpgerr != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ printf("failed setup_trustdb, errno=%d\n", gpgerr); -+ return 0; -+ } -+ //populate /tmp/fuzzdirimport/ as homedir ~/.gnupg -+ strlist_t sl = NULL; -+ public_key_list (ctrlGlobal, sl, 0); -+ free_strlist(sl); -+ //no output for stderr -+ log_set_file("/tmp/fuzzimport.log"); -+ gcry_set_log_handler (my_gcry_logger, NULL); -+ gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); -+ initialized = true; -+ } -+ -+ memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ -+ if (ftruncate(fd, Size) == -1) { -+ return 0; -+ } -+ if (lseek (fd, 0, SEEK_SET) < 0) { -+ return 0; -+ } -+ if (write (fd, Data, Size) != Size) { -+ return 0; -+ } -+ -+ import_keys (ctrlGlobal, &filename, 1, NULL, IMPORT_REPAIR_KEYS, 0, NULL); -+ gpg_deinit_default_ctrl (ctrlGlobal); -+ /*memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ PKT_public_key pk; -+ get_pubkey_fromfile (ctrlGlobal, &pk, filename); -+ release_public_key_parts (&pk); -+ gpg_deinit_default_ctrl (ctrlGlobal);*/ -+ -+ return 0; -+} -diff --git a/tests/fuzz/fuzz_import.options b/tests/fuzz/fuzz_import.options -new file mode 100644 -index 000000000..678d526b1 ---- /dev/null -+++ b/tests/fuzz/fuzz_import.options -@@ -0,0 +1,2 @@ -+[libfuzzer] -+max_len = 65536 -diff --git a/tests/fuzz/fuzz_list.c b/tests/fuzz/fuzz_list.c -new file mode 100644 -index 000000000..937fdd5ea ---- /dev/null -+++ b/tests/fuzz/fuzz_list.c -@@ -0,0 +1,163 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "gpg.h" -+#include "../common/types.h" -+#include "../common/iobuf.h" -+#include "keydb.h" -+#include "keyedit.h" -+#include "../common/util.h" -+#include "main.h" -+#include "call-dirmngr.h" -+#include "trustdb.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+static bool initialized = false; -+ctrl_t ctrlGlobal; -+int fd; -+char *filename; -+ -+//hack not to include gpg.c which has main function -+int g10_errors_seen = 0; -+ -+void -+g10_exit( int rc ) -+{ -+ gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); -+ gcry_control (GCRYCTL_TERM_SECMEM ); -+ exit (rc); -+} -+ -+static void -+gpg_deinit_default_ctrl (ctrl_t ctrl) -+{ -+#ifdef USE_TOFU -+ tofu_closedbs (ctrl); -+#endif -+ gpg_dirmngr_deinit_session_data (ctrl); -+ -+ keydb_release (ctrl->cached_getkey_kdb); -+} -+ -+static void -+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) -+{ -+ return; -+} -+ -+static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) -+{ -+ if (typeflag == FTW_F){ -+ unlink(fpath); -+ } -+ return 0; -+} -+ -+static void rmrfdir(char *path) -+{ -+ ftw(path, unlink_cb, 16); -+ if (rmdir(path) != 0) { -+ printf("failed rmdir, errno=%d\n", errno); -+ } -+} -+ -+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { -+ IOBUF a; -+ armor_filter_context_t *afx = NULL; -+ -+ if (! initialized) { -+ ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); -+ if (!ctrlGlobal) { -+ exit(1); -+ } -+ //deletes previous tmp dir and (re)create it as a ramfs -+ //system("umount /tmp/fuzzdirlist"); -+ rmrfdir("/tmp/fuzzdirlist"); -+ if (mkdir("/tmp/fuzzdirlist", 0700) < 0) { -+ printf("failed mkdir, errno=%d\n", errno); -+ if (errno != EEXIST) { -+ return 0; -+ } -+ } -+ //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirlist"); -+ filename=strdup("/tmp/fuzzdirlist/fuzz.gpg"); -+ if (!filename) { -+ free(ctrlGlobal); -+ return 0; -+ } -+ fd = open(filename, O_RDWR | O_CREAT, 0666); -+ if (fd == -1) { -+ free(filename); -+ free(ctrlGlobal); -+ printf("failed open, errno=%d\n", errno); -+ return 0; -+ } -+ gnupg_set_homedir("/tmp/fuzzdirlist/"); -+ gpg_error_t gpgerr = keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, KEYDB_RESOURCE_FLAG_DEFAULT); -+ if (gpgerr != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ printf("failed keydb_add_resource, errno=%d\n", gpgerr); -+ return 0; -+ } -+ gpgerr = setup_trustdb (1, NULL); -+ if (gpgerr != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ printf("failed setup_trustdb, errno=%d\n", gpgerr); -+ return 0; -+ } -+ //populate /tmp/fuzzdirlist/ as homedir ~/.gnupg -+ strlist_t sl = NULL; -+ public_key_list (ctrlGlobal, sl, 0); -+ free_strlist(sl); -+ //no output for stderr -+ log_set_file("/tmp/fuzzlist.log"); -+ gcry_set_log_handler (my_gcry_logger, NULL); -+ gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); -+ opt.list_packets=1; -+ set_packet_list_mode(1); -+ initialized = true; -+ } -+ -+ memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ -+ if (ftruncate(fd, Size) == -1) { -+ return 0; -+ } -+ if (lseek (fd, 0, SEEK_SET) < 0) { -+ return 0; -+ } -+ if (write (fd, Data, Size) != Size) { -+ return 0; -+ } -+ -+ a = iobuf_open(filename); -+ if( !a ) { -+ printf("failed iobuf_open\n"); -+ return 0; -+ } -+ if( use_armor_filter( a ) ) { -+ afx = new_armor_context (); -+ push_armor_filter (afx, a); -+ } -+ proc_packets (ctrlGlobal, NULL, a ); -+ iobuf_close(a); -+ release_armor_context (afx); -+ gpg_deinit_default_ctrl (ctrlGlobal); -+ -+ return 0; -+} -diff --git a/tests/fuzz/fuzz_list.options b/tests/fuzz/fuzz_list.options -new file mode 100644 -index 000000000..9dd056806 ---- /dev/null -+++ b/tests/fuzz/fuzz_list.options -@@ -0,0 +1,3 @@ -+[libfuzzer] -+max_len = 65536 -+close_fd_mask = 1 -diff --git a/tests/fuzz/fuzz_verify.c b/tests/fuzz/fuzz_verify.c -new file mode 100644 -index 000000000..15412583f ---- /dev/null -+++ b/tests/fuzz/fuzz_verify.c -@@ -0,0 +1,143 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "config.h" -+#include "gpg.h" -+#include "../common/types.h" -+#include "../common/iobuf.h" -+#include "keydb.h" -+#include "keyedit.h" -+#include "../common/util.h" -+#include "main.h" -+#include "call-dirmngr.h" -+#include "trustdb.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+static bool initialized = false; -+ctrl_t ctrlGlobal; -+int fd; -+char *filename; -+ -+//hack not to include gpg.c which has main function -+int g10_errors_seen = 0; -+ -+void -+g10_exit( int rc ) -+{ -+ gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); -+ gcry_control (GCRYCTL_TERM_SECMEM ); -+ exit (rc); -+} -+ -+static void -+gpg_deinit_default_ctrl (ctrl_t ctrl) -+{ -+#ifdef USE_TOFU -+ tofu_closedbs (ctrl); -+#endif -+ gpg_dirmngr_deinit_session_data (ctrl); -+ -+ keydb_release (ctrl->cached_getkey_kdb); -+} -+ -+static void -+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) -+{ -+ return; -+} -+ -+static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag) -+{ -+ if (typeflag == FTW_F){ -+ unlink(fpath); -+ } -+ return 0; -+} -+ -+static void rmrfdir(char *path) -+{ -+ ftw(path, unlink_cb, 16); -+ if (rmdir(path) != 0) { -+ printf("failed rmdir, errno=%d\n", errno); -+ } -+} -+ -+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { -+ -+ if (! initialized) { -+ ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal)); -+ if (!ctrlGlobal) { -+ exit(1); -+ } -+ //deletes previous tmp dir and (re)create it as a ramfs -+ //system("umount /tmp/fuzzdirverify"); -+ rmrfdir("/tmp/fuzzdirverify"); -+ mkdir("/tmp/fuzzdirverify/", 0700); -+ //system("mount -t tmpfs -o size=64M tmpfs /tmp/fuzzdirverify"); -+ filename=strdup("/tmp/fuzzdirverify/fuzz.gpg"); -+ if (!filename) { -+ free(ctrlGlobal); -+ return 0; -+ } -+ fd = open("/tmp/fuzzdirverify/fuzz.gpg", O_RDWR | O_CREAT, 0600); -+ if (fd == -1) { -+ free(ctrlGlobal); -+ free(filename); -+ return 0; -+ } -+ gnupg_set_homedir("/tmp/fuzzdirverify/"); -+ if (keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG, -+ KEYDB_RESOURCE_FLAG_DEFAULT) != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ return 0; -+ } -+ if (setup_trustdb (1, NULL) != GPG_ERR_NO_ERROR) { -+ free(filename); -+ free(ctrlGlobal); -+ close(fd); -+ return 0; -+ } -+ //populate /tmp/fuzzdirverify/ as homedir ~/.gnupg -+ strlist_t sl = NULL; -+ public_key_list (ctrlGlobal, sl, 0); -+ free_strlist(sl); -+ //no output for stderr -+ log_set_file("/tmp/fuzzverify.log"); -+ gcry_set_log_handler (my_gcry_logger, NULL); -+ gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG); -+ initialized = true; -+ } -+ -+ memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ -+ if (ftruncate(fd, Size) == -1) { -+ return 0; -+ } -+ if (lseek (fd, 0, SEEK_SET) < 0) { -+ return 0; -+ } -+ if (write (fd, Data, Size) != Size) { -+ return 0; -+ } -+ -+ verify_signatures(ctrlGlobal, 1, &filename); -+ gpg_deinit_default_ctrl (ctrlGlobal); -+ memset(ctrlGlobal, 0, sizeof(*ctrlGlobal)); -+ ctrlGlobal->magic = SERVER_CONTROL_MAGIC; -+ verify_files(ctrlGlobal, 1, &filename); -+ gpg_deinit_default_ctrl (ctrlGlobal); -+ -+ return 0; -+} -diff --git a/tests/fuzz/fuzz_verify.options b/tests/fuzz/fuzz_verify.options -new file mode 100644 -index 000000000..678d526b1 ---- /dev/null -+++ b/tests/fuzz/fuzz_verify.options -@@ -0,0 +1,2 @@ -+[libfuzzer] -+max_len = 65536