[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
This commit is contained in:
Catena cyber 2018-10-17 19:41:44 +02:00 committed by Max Moroz
parent ea855f048a
commit 51e638b3d3
7 changed files with 616 additions and 663 deletions

View File

@ -0,0 +1,146 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ftw.h>
#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 <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mount.h>
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;
}

View File

@ -0,0 +1,2 @@
[libfuzzer]
close_fd_mask = 1

View File

@ -0,0 +1,160 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ftw.h>
#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 <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mount.h>
// 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;
}

163
projects/gnupg/fuzz_list.c Normal file
View File

@ -0,0 +1,163 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ftw.h>
#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 <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mount.h>
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;
}

View File

@ -0,0 +1,2 @@
[libfuzzer]
close_fd_mask = 1

View File

@ -0,0 +1,143 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <ftw.h>
#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 <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mount.h>
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;
}

View File

@ -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 <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ftw.h>
+
+#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 <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/mount.h>
+
+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 <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ftw.h>
+
+#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 <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/mount.h>
+
+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 <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ftw.h>
+
+#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 <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/mount.h>
+
+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 <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ftw.h>
+
+#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 <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/mount.h>
+
+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