Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F285274
fuzz.diff
catenacyber (philippe antoine)
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
catenacyber
Apr 17 2018, 6:05 PM
2018-04-17 18:05:29 (UTC+2)
Size
12 KB
Subscribers
None
fuzz.diff
View Options
diff --git a/configure.ac b/configure.ac
index 540dffcd0..99ee9d17c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -954,6 +954,15 @@ AC_CHECK_LIB(util, openpty,
])
AC_SUBST(LIBUTIL_LIBS)
+# TODO choose when to build fuzzing with option ?
+AC_CHECK_LIB(FuzzingEngine, main,
+ [ LIB_FUZZING_ENGINE="-lFuzzingEngine"
+ have_fuzz=yes
+ ])
+AC_SUBST(LIB_FUZZING_ENGINE)
+AC_CHECK_PROG(HAVE_CLANGXX, clang++, 1)
+AM_CONDITIONAL(HAVE_LIB_FUZZING_ENGINE, [test "$have_fuzz" = yes -a "$HAVE_CLANGXX" = 1])
+
# shred is used to clean temporary plain text files.
AC_PATH_PROG(SHRED, shred, /usr/bin/shred)
AC_DEFINE_UNQUOTED(SHRED,
@@ -2039,6 +2048,7 @@ tests/migrations/Makefile
tests/gpgsm/Makefile
tests/gpgme/Makefile
tests/pkits/Makefile
+tests/fuzz/Makefile
g10/gpg.w32-manifest
])
diff --git a/g10/Makefile.am b/g10/Makefile.am
index b8b92d702..233dd282e 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -47,6 +47,7 @@ endif
# NB: We use noinst_ for gpg and gpgv so that we can install them with
# the install-hook target under the name gpg2/gpgv2.
noinst_PROGRAMS = gpg
+noinst_LIBRARIES = libgpg.a
if !HAVE_W32CE_SYSTEM
noinst_PROGRAMS += gpgv
endif
@@ -158,6 +159,9 @@ gpg_SOURCES = gpg.c \
keyedit.c keyedit.h \
$(gpg_sources)
+libgpg_a_SOURCES = keyedit.c keyedit.h \
+ $(gpg_sources)
+
gpgcompose_SOURCES = gpgcompose.c $(gpg_sources)
gpgv_SOURCES = gpgv.c \
$(common_source) \
diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h
index 285c4cb4d..7af328c2a 100644
--- a/g10/call-dirmngr.h
+++ b/g10/call-dirmngr.h
@@ -19,6 +19,8 @@
#ifndef GNUPG_G10_CALL_DIRMNGR_H
#define GNUPG_G10_CALL_DIRMNGR_H
+#include "options.h"
+
void gpg_dirmngr_deinit_session_data (ctrl_t ctrl);
gpg_error_t gpg_dirmngr_ks_list (ctrl_t ctrl, char **r_keyserver);
diff --git a/g10/compress-bz2.c b/g10/compress-bz2.c
index 45aa40dfc..5a59787f6 100644
--- a/g10/compress-bz2.c
+++ b/g10/compress-bz2.c
@@ -155,8 +155,11 @@ do_uncompress( compress_filter_context_t *zfx, bz_stream *bzs,
(unsigned)bzs->avail_in, (unsigned)bzs->avail_out, zrc);
if( zrc == BZ_STREAM_END )
rc = -1; /* eof */
- else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR )
- log_fatal("bz2lib inflate problem: rc=%d\n", zrc );
+ else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR ) {
+ log_error("bz2lib inflate problem: rc=%d\n", zrc );
+ rc = GPG_ERR_BAD_DATA;
+ break;
+ }
else if (zrc == BZ_OK && eofseen
&& !bzs->avail_in && bzs->avail_out > 0)
{
diff --git a/g10/compress.c b/g10/compress.c
index 61bb756f2..5d1f06102 100644
--- a/g10/compress.c
+++ b/g10/compress.c
@@ -204,10 +204,12 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
if( zrc == Z_STREAM_END )
rc = -1; /* eof */
else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) {
+ rc = -1;
+ zrc = Z_BUF_ERROR;
if( zs->msg )
- log_fatal("zlib inflate problem: %s\n", zs->msg );
+ log_error("zlib inflate problem: %s\n", zs->msg );
else
- log_fatal("zlib inflate problem: rc=%d\n", zrc );
+ log_error("zlib inflate problem: rc=%d\n", zrc );
}
} while (zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR
&& !leave);
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index e933abfa0..20ef8368a 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -709,7 +709,8 @@ parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos,
* the uncompressing layer - in some error cases it just loops
* and spits out 0xff bytes. */
log_error ("%s: garbled packet detected\n", iobuf_where (inp));
- g10_exit (2);
+ rc = gpg_error (GPG_ERR_INV_PACKET);
+ goto leave;
}
if (out && pkttype)
diff --git a/m4/iconv.m4 b/m4/iconv.m4
index 66bc76f48..2d6d6e423 100644
--- a/m4/iconv.m4
+++ b/m4/iconv.m4
@@ -83,6 +83,7 @@ int main ()
size_t res = iconv (cd_utf8_to_88591,
(char **) &inptr, &inbytesleft,
&outptr, &outbytesleft);
+ iconv_close(cd_utf8_to_88591);
if (res == 0)
return 1;
}
@@ -107,17 +108,19 @@ int main ()
}
}
#endif
+ iconv_t ic;
/* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
provided. */
if (/* Try standardized names. */
- iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+ (ic = iconv_open ("UTF-8", "EUC-JP")) == (iconv_t)(-1)
/* Try IRIX, OSF/1 names. */
- && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+ && (ic = iconv_open ("UTF-8", "eucJP")) == (iconv_t)(-1)
/* Try AIX names. */
- && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+ && (ic = iconv_open ("UTF-8", "IBM-eucJP")) == (iconv_t)(-1)
/* Try HP-UX names. */
- && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+ && (ic = iconv_open ("utf8", "eucJP")) == (iconv_t)(-1))
return 1;
+ iconv_close(ic);
return 0;
}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
[case "$host_os" in
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b9be6aaa6..f4085b824 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -18,7 +18,13 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = gpgscm openpgp migrations gpgsm gpgme pkits .
+SUBDIRS = gpgscm openpgp migrations gpgsm gpgme pkits
+
+if HAVE_LIB_FUZZING_ENGINE
+SUBDIRS += fuzz
+endif
+
+SUBDIRS += .
GPGSM = ../sm/gpgsm
diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
new file mode 100644
index 000000000..e2dee99a6
--- /dev/null
+++ b/tests/fuzz/Makefile.am
@@ -0,0 +1,50 @@
+# Makefile.am - For tests/fuzz
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
+# Process this file with automake to create Makefile.in
+
+
+# Programs required before we can run these tests.
+required_pgms = ../../g10/gpg$(EXEEXT)
+
+
+# Force linking with clang++ even if we have pure C fuzzing targets
+CCLD = clang++
+LDFLAGS += -stdlib=libc++
+
+AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/g10
+include $(top_srcdir)/am/cmacros.am
+
+noinst_PROGRAMS = fuzz_verify fuzz_import
+
+fuzz_verify_SOURCES = fuzz_verify.c
+
+fuzz_verify_LDADD = $(top_srcdir)/g10/libgpg.a ../../kbx/libkeybox.a ../../common/libcommon.a ../../common/libgpgrl.a $(LIB_FUZZING_ENGINE) \
+ $(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
+ $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+ $(LIBICONV) $(resource_objs) $(extra_sys_libs)
+
+fuzz_import_SOURCES = fuzz_import.c
+
+fuzz_import_LDADD = $(top_srcdir)/g10/libgpg.a ../../kbx/libkeybox.a ../../common/libcommon.a ../../common/libgpgrl.a $(LIB_FUZZING_ENGINE)\
+ $(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
+ $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
+ $(LIBICONV) $(resource_objs) $(extra_sys_libs)
+
+# 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_import.c b/tests/fuzz/fuzz_import.c
new file mode 100644
index 000000000..c31a21605
--- /dev/null
+++ b/tests/fuzz/fuzz_import.c
@@ -0,0 +1,86 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.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 <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;
+const char *filename = "/tmp/ramfuzz/fuzz.gpg";
+
+//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);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ kbnode_t keyblock;
+
+ if (! initialized) {
+ ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal));
+ if (!ctrlGlobal) {
+ exit(1);
+ }
+ //creates a dir if it does not exist already
+ //TODO mount it as ramfs
+ mkdir("/tmp/ramfuzz/", 0777);
+ fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ free(ctrlGlobal);
+ return 0;
+ }
+ 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;
+ }
+
+ read_key_from_file (ctrlGlobal, filename, &keyblock);
+ 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_verify.c b/tests/fuzz/fuzz_verify.c
new file mode 100644
index 000000000..63f42ce2b
--- /dev/null
+++ b/tests/fuzz/fuzz_verify.c
@@ -0,0 +1,92 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.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 <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);
+}
+
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+
+ if (! initialized) {
+ ctrlGlobal = (ctrl_t) malloc(sizeof(*ctrlGlobal));
+ if (!ctrlGlobal) {
+ exit(1);
+ }
+ //creates a dir if it does not exist already
+ //TODO mount it as ramfs
+ mkdir("/tmp/ramfuzz/", 0777);
+ filename=strdup("/tmp/ramfuzz/fuzz.gpg");
+ if (!filename) {
+ free(ctrlGlobal);
+ return 0;
+ }
+ fd = open("/tmp/ramfuzz/fuzz.gpg", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ free(ctrlGlobal);
+ free(filename);
+ return 0;
+ }
+ 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);
+
+ 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
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
153085
Attached To
T3914: Integration with oss-fuzz
Event Timeline
Log In to Comment