287 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
			
		
		
	
	
			287 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
| diff --git a/configure.ac b/configure.ac
 | |
| index 7b398f3df..ee69b3063 100644
 | |
| --- a/configure.ac
 | |
| +++ b/configure.ac
 | |
| @@ -991,6 +991,15 @@ if test x"$use_tofu" = xyes ; then
 | |
|    fi
 | |
|  fi
 | |
|  
 | |
| +# TODO choose when to build fuzzing with option ?
 | |
| +AC_CHECK_LIB(FuzzingEngine, main,
 | |
| +              [ LIB_FUZZING_ENGINE="$LIB_FUZZING_ENGINE"
 | |
| +                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])
 | |
| +
 | |
|  AM_CONDITIONAL(SQLITE3, test "$have_sqlite" = "yes")
 | |
|  
 | |
|  if test x"$use_tofu" = xyes ; then
 | |
| @@ -2149,6 +2158,7 @@ tests/migrations/Makefile
 | |
|  tests/tpm2dtests/Makefile
 | |
|  tests/gpgme/Makefile
 | |
|  tests/pkits/Makefile
 | |
| +tests/fuzz/Makefile
 | |
|  g10/gpg.w32-manifest
 | |
|  tools/gpg-connect-agent.w32-manifest
 | |
|  tools/gpgconf.w32-manifest
 | |
| diff --git a/g10/Makefile.am b/g10/Makefile.am
 | |
| index eb23573b7..785ac2b4b 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
 | |
| @@ -164,6 +165,9 @@ gpg_sources = server.c          \
 | |
|  gpg_SOURCES  = gpg.c \
 | |
|  	keyedit.c keyedit.h	\
 | |
|  	$(gpg_sources)
 | |
| +libgpg_a_SOURCES  = keyedit.c keyedit.h	\
 | |
| +	$(gpg_sources)
 | |
| +
 | |
|  
 | |
|  gpgv_SOURCES = gpgv.c           \
 | |
|  	      $(common_source)  \
 | |
| diff --git a/g10/armor.c b/g10/armor.c
 | |
| index eb2d28bca..594f5bd2d 100644
 | |
| --- a/g10/armor.c
 | |
| +++ b/g10/armor.c
 | |
| @@ -313,7 +313,9 @@ static void
 | |
|  invalid_armor(void)
 | |
|  {
 | |
|      write_status(STATUS_BADARMOR);
 | |
| +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 | |
|      g10_exit(1); /* stop here */
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  
 | |
| diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h
 | |
| index c0f1e0cec..52652a0e0 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..1a74a89d7 100644
 | |
| --- a/g10/compress-bz2.c
 | |
| +++ b/g10/compress-bz2.c
 | |
| @@ -155,8 +155,15 @@ 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 ) {
 | |
| +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 | |
| +            log_error("bz2lib inflate problem: rc=%d\n", zrc );
 | |
| +            rc = GPG_ERR_BAD_DATA;
 | |
| +            break;
 | |
| +#else
 | |
| +            log_fatal("bz2lib inflate problem: rc=%d\n", zrc );
 | |
| +#endif
 | |
| +        }
 | |
|        else if (zrc == BZ_OK && eofseen
 | |
|                 && !bzs->avail_in && bzs->avail_out > 0)
 | |
|          {
 | |
| diff --git a/g10/compress.c b/g10/compress.c
 | |
| index e7a6f2b11..9a9ab5460 100644
 | |
| --- a/g10/compress.c
 | |
| +++ b/g10/compress.c
 | |
| @@ -204,10 +204,19 @@ 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 ) {
 | |
| +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 | |
| +        rc = -1;
 | |
| +        zrc = Z_BUF_ERROR;
 | |
| +	    if( zs->msg )
 | |
| +		log_error("zlib inflate problem: %s\n", zs->msg );
 | |
| +	    else
 | |
| +		log_error("zlib inflate problem: rc=%d\n", zrc );
 | |
| +#else
 | |
|  	    if( zs->msg )
 | |
|  		log_fatal("zlib inflate problem: %s\n", zs->msg );
 | |
|  	    else
 | |
|  		log_fatal("zlib inflate problem: rc=%d\n", zrc );
 | |
| +#endif
 | |
|  	}
 | |
|      } 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 bb05eabb7..638d895d0 100644
 | |
| --- a/g10/parse-packet.c
 | |
| +++ b/g10/parse-packet.c
 | |
| @@ -806,7 +806,12 @@ 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));
 | |
| +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 | |
| +      rc = gpg_error (GPG_ERR_INV_PACKET);
 | |
| +      goto leave;
 | |
| +#else
 | |
|        g10_exit (2);
 | |
| +#endif
 | |
|      }
 | |
|  
 | |
|    if (out && pkttype)
 | |
| diff --git a/g10/plaintext.c b/g10/plaintext.c
 | |
| index 3e169d93f..aa83ffbe0 100644
 | |
| --- a/g10/plaintext.c
 | |
| +++ b/g10/plaintext.c
 | |
| @@ -617,10 +617,16 @@ ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
 | |
|  
 | |
|    if (!fp)
 | |
|      {
 | |
| +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
 | |
| +        errno = ENOENT;
 | |
| +        rc = gpg_error_from_syserror ();
 | |
| +        goto leave;
 | |
| +#else
 | |
|        if (opt.verbose)
 | |
|  	log_info (_("reading stdin ...\n"));
 | |
|        fp = iobuf_open (NULL);
 | |
|        log_assert (fp);
 | |
| +#endif
 | |
|      }
 | |
|    do_hash (md, md2, fp, textmode);
 | |
|    iobuf_close (fp);
 | |
| diff --git a/g10/sig-check.c b/g10/sig-check.c
 | |
| index 8dd18b2e2..9f5db89f9 100644
 | |
| --- a/g10/sig-check.c
 | |
| +++ b/g10/sig-check.c
 | |
| @@ -783,8 +783,9 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
 | |
|  	    {
 | |
|                gcry_md_hd_t md;
 | |
|  
 | |
| -              if (gcry_md_open (&md, sig->digest_algo, 0))
 | |
| -                BUG ();
 | |
| +              rc = gcry_md_open (&md, sig->digest_algo, 0);
 | |
| +              if (rc)
 | |
| +                  return rc;
 | |
|                hash_public_key(md,pk);
 | |
|  	      /* Note: check_signature only checks that the signature
 | |
|  		 is good.  It does not fail if the key is revoked.  */
 | |
| diff --git a/tests/Makefile.am b/tests/Makefile.am
 | |
| index f29b68a53..e788c9916 100644
 | |
| --- a/tests/Makefile.am
 | |
| +++ b/tests/Makefile.am
 | |
| @@ -24,7 +24,13 @@ else
 | |
|  tpm2dtests =
 | |
|  endif
 | |
|  
 | |
| -SUBDIRS = gpgscm openpgp cms migrations gpgme pkits $(tpm2dtests) .
 | |
| +SUBDIRS = gpgscm openpgp cms migrations gpgme pkits $(tpm2dtests)
 | |
| +
 | |
| +if MAINTAINER_MODE
 | |
| +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..eb2216d3e
 | |
| --- /dev/null
 | |
| +++ b/tests/fuzz/Makefile.am
 | |
| @@ -0,0 +1,84 @@
 | |
| +# 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++
 | |
| +AM_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_decrypt fuzz_list
 | |
| +
 | |
| +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) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
 | |
| +	     $(LIBICONV) $(resource_objs) $(extra_sys_libs)
 | |
| +
 | |
| +fuzz_verify_DEPENDENCIES = fuzz_verify_seed_corpus.zip
 | |
| +
 | |
| +fuzz_verify_seed_corpus.zip:
 | |
| +	cd .. && zip -r fuzz/fuzz_verify_seed_corpus.zip openpgp/tofu/conflicting/* openpgp/tofu/cross-sigs/* openpgp/samplemsgs/*
 | |
| +
 | |
| +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) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
 | |
| +	     $(LIBICONV) $(resource_objs) $(extra_sys_libs)
 | |
| +
 | |
| +fuzz_import_DEPENDENCIES = fuzz_import_seed_corpus.zip
 | |
| +
 | |
| +fuzz_import_seed_corpus.zip:
 | |
| +	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/*
 | |
| +
 | |
| +fuzz_decrypt_SOURCES = fuzz_decrypt.c
 | |
| +
 | |
| +fuzz_decrypt_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) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
 | |
| +	     $(LIBICONV) $(resource_objs) $(extra_sys_libs)
 | |
| +
 | |
| +fuzz_decrypt_DEPENDENCIES = fuzz_decrypt_seed_corpus.zip
 | |
| +
 | |
| +fuzz_decrypt_seed_corpus.zip:
 | |
| +	cd .. && zip -r fuzz/fuzz_decrypt_seed_corpus.zip openpgp/tofu/conflicting/* openpgp/tofu/cross-sigs/* openpgp/samplemsgs/*
 | |
| +
 | |
| +fuzz_list_SOURCES = fuzz_list.c
 | |
| +
 | |
| +fuzz_list_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) $(NPTH_LIBS) $(GPG_ERROR_LIBS) \
 | |
| +$(LIBICONV) $(resource_objs) $(extra_sys_libs)
 | |
| +
 | |
| +fuzz_list_DEPENDENCIES = fuzz_list_seed_corpus.zip
 | |
| +
 | |
| +fuzz_list_seed_corpus.zip:
 | |
| +	cd .. && zip -r fuzz/fuzz_list_seed_corpus.zip openpgp/
 | |
| +
 | |
| +# 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)
 |