• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/configure.ac b/configure.ac
2index 7b398f3df..ee69b3063 100644
3--- a/configure.ac
4+++ b/configure.ac
5@@ -991,6 +991,15 @@ if test x"$use_tofu" = xyes ; then
6   fi
7 fi
8
9+# TODO choose when to build fuzzing with option ?
10+AC_CHECK_LIB(FuzzingEngine, main,
11+              [ LIB_FUZZING_ENGINE="$LIB_FUZZING_ENGINE"
12+                have_fuzz=yes
13+             ])
14+AC_SUBST(LIB_FUZZING_ENGINE)
15+AC_CHECK_PROG(HAVE_CLANGXX, clang++, 1)
16+AM_CONDITIONAL(HAVE_LIB_FUZZING_ENGINE, [test "$have_fuzz" = yes -a "$HAVE_CLANGXX" = 1])
17+
18 AM_CONDITIONAL(SQLITE3, test "$have_sqlite" = "yes")
19
20 if test x"$use_tofu" = xyes ; then
21@@ -2149,6 +2158,7 @@ tests/migrations/Makefile
22 tests/tpm2dtests/Makefile
23 tests/gpgme/Makefile
24 tests/pkits/Makefile
25+tests/fuzz/Makefile
26 g10/gpg.w32-manifest
27 tools/gpg-connect-agent.w32-manifest
28 tools/gpgconf.w32-manifest
29diff --git a/g10/Makefile.am b/g10/Makefile.am
30index eb23573b7..785ac2b4b 100644
31--- a/g10/Makefile.am
32+++ b/g10/Makefile.am
33@@ -47,6 +47,7 @@ endif
34 # NB: We use noinst_ for gpg and gpgv so that we can install them with
35 # the install-hook target under the name gpg2/gpgv2.
36 noinst_PROGRAMS = gpg
37+noinst_LIBRARIES = libgpg.a
38 if !HAVE_W32CE_SYSTEM
39 noinst_PROGRAMS += gpgv
40 endif
41@@ -164,6 +165,9 @@ gpg_sources = server.c          \
42 gpg_SOURCES  = gpg.c \
43 	keyedit.c keyedit.h	\
44 	$(gpg_sources)
45+libgpg_a_SOURCES  = keyedit.c keyedit.h	\
46+	$(gpg_sources)
47+
48
49 gpgv_SOURCES = gpgv.c           \
50 	      $(common_source)  \
51diff --git a/g10/armor.c b/g10/armor.c
52index eb2d28bca..594f5bd2d 100644
53--- a/g10/armor.c
54+++ b/g10/armor.c
55@@ -313,7 +313,9 @@ static void
56 invalid_armor(void)
57 {
58     write_status(STATUS_BADARMOR);
59+#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
60     g10_exit(1); /* stop here */
61+#endif
62 }
63
64
65diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h
66index c0f1e0cec..52652a0e0 100644
67--- a/g10/call-dirmngr.h
68+++ b/g10/call-dirmngr.h
69@@ -19,6 +19,8 @@
70 #ifndef GNUPG_G10_CALL_DIRMNGR_H
71 #define GNUPG_G10_CALL_DIRMNGR_H
72
73+#include "options.h"
74+
75 void gpg_dirmngr_deinit_session_data (ctrl_t ctrl);
76
77 gpg_error_t gpg_dirmngr_ks_list (ctrl_t ctrl, char **r_keyserver);
78diff --git a/g10/compress-bz2.c b/g10/compress-bz2.c
79index 45aa40dfc..1a74a89d7 100644
80--- a/g10/compress-bz2.c
81+++ b/g10/compress-bz2.c
82@@ -155,8 +155,15 @@ do_uncompress( compress_filter_context_t *zfx, bz_stream *bzs,
83 		  (unsigned)bzs->avail_in, (unsigned)bzs->avail_out, zrc);
84       if( zrc == BZ_STREAM_END )
85 	rc = -1; /* eof */
86-      else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR )
87-	log_fatal("bz2lib inflate problem: rc=%d\n", zrc );
88+      else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR ) {
89+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
90+            log_error("bz2lib inflate problem: rc=%d\n", zrc );
91+            rc = GPG_ERR_BAD_DATA;
92+            break;
93+#else
94+            log_fatal("bz2lib inflate problem: rc=%d\n", zrc );
95+#endif
96+        }
97       else if (zrc == BZ_OK && eofseen
98                && !bzs->avail_in && bzs->avail_out > 0)
99         {
100diff --git a/g10/compress.c b/g10/compress.c
101index e7a6f2b11..9a9ab5460 100644
102--- a/g10/compress.c
103+++ b/g10/compress.c
104@@ -204,10 +204,19 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
105 	if( zrc == Z_STREAM_END )
106 	    rc = -1; /* eof */
107 	else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) {
108+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
109+        rc = -1;
110+        zrc = Z_BUF_ERROR;
111+	    if( zs->msg )
112+		log_error("zlib inflate problem: %s\n", zs->msg );
113+	    else
114+		log_error("zlib inflate problem: rc=%d\n", zrc );
115+#else
116 	    if( zs->msg )
117 		log_fatal("zlib inflate problem: %s\n", zs->msg );
118 	    else
119 		log_fatal("zlib inflate problem: rc=%d\n", zrc );
120+#endif
121 	}
122     } while (zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR
123              && !leave);
124diff --git a/g10/parse-packet.c b/g10/parse-packet.c
125index bb05eabb7..638d895d0 100644
126--- a/g10/parse-packet.c
127+++ b/g10/parse-packet.c
128@@ -806,7 +806,12 @@ parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos,
129        * the uncompressing layer - in some error cases it just loops
130        * and spits out 0xff bytes. */
131       log_error ("%s: garbled packet detected\n", iobuf_where (inp));
132+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
133+      rc = gpg_error (GPG_ERR_INV_PACKET);
134+      goto leave;
135+#else
136       g10_exit (2);
137+#endif
138     }
139
140   if (out && pkttype)
141diff --git a/g10/plaintext.c b/g10/plaintext.c
142index 3e169d93f..aa83ffbe0 100644
143--- a/g10/plaintext.c
144+++ b/g10/plaintext.c
145@@ -617,10 +617,16 @@ ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
146
147   if (!fp)
148     {
149+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
150+        errno = ENOENT;
151+        rc = gpg_error_from_syserror ();
152+        goto leave;
153+#else
154       if (opt.verbose)
155 	log_info (_("reading stdin ...\n"));
156       fp = iobuf_open (NULL);
157       log_assert (fp);
158+#endif
159     }
160   do_hash (md, md2, fp, textmode);
161   iobuf_close (fp);
162diff --git a/g10/sig-check.c b/g10/sig-check.c
163index 8dd18b2e2..9f5db89f9 100644
164--- a/g10/sig-check.c
165+++ b/g10/sig-check.c
166@@ -783,8 +783,9 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
167 	    {
168               gcry_md_hd_t md;
169
170-              if (gcry_md_open (&md, sig->digest_algo, 0))
171-                BUG ();
172+              rc = gcry_md_open (&md, sig->digest_algo, 0);
173+              if (rc)
174+                  return rc;
175               hash_public_key(md,pk);
176 	      /* Note: check_signature only checks that the signature
177 		 is good.  It does not fail if the key is revoked.  */
178diff --git a/tests/Makefile.am b/tests/Makefile.am
179index f29b68a53..e788c9916 100644
180--- a/tests/Makefile.am
181+++ b/tests/Makefile.am
182@@ -24,7 +24,13 @@ else
183 tpm2dtests =
184 endif
185
186-SUBDIRS = gpgscm openpgp cms migrations gpgme pkits $(tpm2dtests) .
187+SUBDIRS = gpgscm openpgp cms migrations gpgme pkits $(tpm2dtests)
188+
189+if MAINTAINER_MODE
190+SUBDIRS += fuzz
191+endif
192+
193+SUBDIRS += .
194
195 GPGSM = ../sm/gpgsm
196
197diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am
198new file mode 100644
199index 000000000..eb2216d3e
200--- /dev/null
201+++ b/tests/fuzz/Makefile.am
202@@ -0,0 +1,84 @@
203+# Makefile.am - For tests/fuzz
204+# Copyright (C) 2018 Free Software Foundation, Inc.
205+#
206+# This file is part of GnuPG.
207+#
208+# GnuPG is free software; you can redistribute it and/or modify
209+# it under the terms of the GNU General Public License as published by
210+# the Free Software Foundation; either version 3 of the License, or
211+# (at your option) any later version.
212+#
213+# GnuPG is distributed in the hope that it will be useful,
214+# but WITHOUT ANY WARRANTY; without even the implied warranty of
215+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
216+# GNU General Public License for more details.
217+#
218+# You should have received a copy of the GNU General Public License
219+# along with this program; if not, see <https://www.gnu.org/licenses/>.
220+# Process this file with automake to create Makefile.in
221+
222+
223+# Programs required before we can run these tests.
224+required_pgms = ../../g10/gpg$(EXEEXT)
225+
226+
227+# Force linking with clang++ even if we have pure C fuzzing targets
228+CCLD = clang++
229+AM_LDFLAGS = -stdlib=libc++
230+
231+AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/g10
232+include $(top_srcdir)/am/cmacros.am
233+
234+noinst_PROGRAMS = fuzz_verify fuzz_import fuzz_decrypt fuzz_list
235+
236+fuzz_verify_SOURCES = fuzz_verify.c
237+
238+fuzz_verify_LDADD = $(top_srcdir)/g10/libgpg.a ../../kbx/libkeybox.a ../../common/libcommon.a ../../common/libgpgrl.a  $(LIB_FUZZING_ENGINE) \
239+         $(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
240+             $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
241+	     $(LIBICONV) $(resource_objs) $(extra_sys_libs)
242+
243+fuzz_verify_DEPENDENCIES = fuzz_verify_seed_corpus.zip
244+
245+fuzz_verify_seed_corpus.zip:
246+	cd .. && zip -r fuzz/fuzz_verify_seed_corpus.zip openpgp/tofu/conflicting/* openpgp/tofu/cross-sigs/* openpgp/samplemsgs/*
247+
248+fuzz_import_SOURCES = fuzz_import.c
249+
250+fuzz_import_LDADD =  $(top_srcdir)/g10/libgpg.a ../../kbx/libkeybox.a ../../common/libcommon.a ../../common/libgpgrl.a  $(LIB_FUZZING_ENGINE)\
251+         $(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
252+             $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
253+	     $(LIBICONV) $(resource_objs) $(extra_sys_libs)
254+
255+fuzz_import_DEPENDENCIES = fuzz_import_seed_corpus.zip
256+
257+fuzz_import_seed_corpus.zip:
258+	cd .. && zip -r fuzz/fuzz_import_seed_corpus.zip openpgp/samplekeys/* openpgp/key-selection/* openpgp/*.asc openpgp/trust-pgp/*.asc openpgp/tofu/conflicting/* openpgp/tofu/cross-sigs/*
259+
260+fuzz_decrypt_SOURCES = fuzz_decrypt.c
261+
262+fuzz_decrypt_LDADD =  $(top_srcdir)/g10/libgpg.a ../../kbx/libkeybox.a ../../common/libcommon.a ../../common/libgpgrl.a  $(LIB_FUZZING_ENGINE)\
263+         $(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
264+             $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
265+	     $(LIBICONV) $(resource_objs) $(extra_sys_libs)
266+
267+fuzz_decrypt_DEPENDENCIES = fuzz_decrypt_seed_corpus.zip
268+
269+fuzz_decrypt_seed_corpus.zip:
270+	cd .. && zip -r fuzz/fuzz_decrypt_seed_corpus.zip openpgp/tofu/conflicting/* openpgp/tofu/cross-sigs/* openpgp/samplemsgs/*
271+
272+fuzz_list_SOURCES = fuzz_list.c
273+
274+fuzz_list_LDADD =  $(top_srcdir)/g10/libgpg.a ../../kbx/libkeybox.a ../../common/libcommon.a ../../common/libgpgrl.a  $(LIB_FUZZING_ENGINE)\
275+$(ZLIBS) $(LIBINTL) $(CAPLIBS) $(NETLIBS) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \
276+$(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
277+$(LIBICONV) $(resource_objs) $(extra_sys_libs)
278+
279+fuzz_list_DEPENDENCIES = fuzz_list_seed_corpus.zip
280+
281+fuzz_list_seed_corpus.zip:
282+	cd .. && zip -r fuzz/fuzz_list_seed_corpus.zip openpgp/
283+
284+# We need to depend on a couple of programs so that the tests don't
285+# start before all programs are built.
286+all-local: $(required_pgms)
287