From ae86ce86078e5e163333885fec5319e0f0ee6b78 Mon Sep 17 00:00:00 2001 From: Vasco Franco Date: Fri, 15 Dec 2023 13:47:23 +0000 Subject: [PATCH 1/8] Add http3 initial fuzzer --- .github/workflows/ci.yml | 1 + .gitignore | 6 ++++++ Makefile.am | 4 ++++ curl_fuzzer.cc | 10 ++++++++++ mainline.sh | 20 ++++++++++++++++---- scripts/download_nghttp3.sh | 6 ++++++ scripts/download_ngtcp2.sh | 7 +++++++ scripts/download_openssl_quic.sh | 7 +++++++ scripts/fuzz_targets | 2 +- scripts/install_curl.sh | 6 +++++- scripts/install_nghttp3.sh | 26 ++++++++++++++++++++++++++ scripts/install_ngtcp2.sh | 29 +++++++++++++++++++++++++++++ scripts/install_openssl_quic.sh | 10 ++++++++++ 13 files changed, 128 insertions(+), 6 deletions(-) create mode 100755 scripts/download_nghttp3.sh create mode 100755 scripts/download_ngtcp2.sh create mode 100755 scripts/download_openssl_quic.sh create mode 100755 scripts/install_nghttp3.sh create mode 100755 scripts/install_ngtcp2.sh create mode 100755 scripts/install_openssl_quic.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb1420f17..bef6d8375 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,7 @@ jobs: - curl_fuzzer_gopher - curl_fuzzer_http - curl_fuzzer_https + - curl_fuzzer_http3 - curl_fuzzer_imap - curl_fuzzer_ldap - curl_fuzzer_mqtt diff --git a/.gitignore b/.gitignore index 269c2a40f..33287f8f1 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,8 @@ missing /curl_fuzzer_http_seed_corpus.zip /curl_fuzzer_https /curl_fuzzer_https_seed_corpus.zip +/curl_fuzzer_http3 +/curl_fuzzer_http3_seed_corpus.zip /curl_fuzzer_imap /curl_fuzzer_imap_seed_corpus.zip /curl_fuzzer_ldap @@ -62,3 +64,7 @@ missing /curl_fuzzer_smtp_seed_corpus.zip /curl_fuzzer_tftp /curl_fuzzer_tftp_seed_corpus.zip +/curl_fuzzer_ws +/curl_fuzzer_ws_seed_corpus.zip +/fuzz_url +/fuzz_url.zip diff --git a/Makefile.am b/Makefile.am index 12b29cbad..dd39df401 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,6 +42,7 @@ FUZZPROGS = curl_fuzzer \ curl_fuzzer_gopher \ curl_fuzzer_http \ curl_fuzzer_https \ + curl_fuzzer_http3 \ curl_fuzzer_imap \ curl_fuzzer_ldap \ curl_fuzzer_mqtt \ @@ -89,6 +90,9 @@ curl_fuzzer_http_LDADD = $(COMMON_LDADD) curl_fuzzer_https_SOURCES = $(COMMON_SOURCES) curl_fuzzer_https_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_HTTPS curl_fuzzer_https_LDADD = $(COMMON_LDADD) +curl_fuzzer_http3_SOURCES = $(COMMON_SOURCES) +curl_fuzzer_http3_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_HTTP3 -DFUZZ_PROTOCOLS_HTTPS +curl_fuzzer_http3_LDADD = $(COMMON_LDADD) curl_fuzzer_imap_SOURCES = $(COMMON_SOURCES) curl_fuzzer_imap_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_IMAP curl_fuzzer_imap_LDADD = $(COMMON_LDADD) diff --git a/curl_fuzzer.cc b/curl_fuzzer.cc index 44f0a2391..a6df5b8b7 100644 --- a/curl_fuzzer.cc +++ b/curl_fuzzer.cc @@ -571,6 +571,16 @@ int fuzz_set_allowed_protocols(FUZZ_DATA *fuzz) FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_PROTOCOLS_STR, allowed_protocols)); + #ifdef FUZZ_PROTOCOLS_HTTP3 + /* If we are fuzzing HTTP3, then we must be fuzzing the HTTPS protocol */ + #ifndef FUZZ_PROTOCOLS_HTTPS + rc = 255; + goto EXIT_LABEL; + #endif + + FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_3ONLY)); + #endif + EXIT_LABEL: return rc; diff --git a/mainline.sh b/mainline.sh index c0991a5fd..9adc6edfd 100755 --- a/mainline.sh +++ b/mainline.sh @@ -8,7 +8,10 @@ SCRIPTDIR=${BUILD_ROOT}/scripts CURLDIR=/tmp/curl OPENSSLDIR=/tmp/openssl -NGHTTPDIR=/tmp/nghttp2 +NGHTTP2DIR=/tmp/nghttp2 +NGHTTP3DIR=/tmp/nghttp3 +NGTCP2DIR=/tmp/ngtcp2 +OPENSLLQUICDIR=/tmp/openssl_quic INSTALLDIR=/tmp/curl_install # Parse the options. @@ -34,13 +37,22 @@ FUZZ_FLAG="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" export CFLAGS="-fsanitize=address" export CXXFLAGS="-fsanitize=address -stdlib=libstdc++ $FUZZ_FLAG" export CPPFLAGS="$FUZZ_FLAG" -export OPENSSLFLAGS="-fno-sanitize=alignment" +export OPENSSLFLAGS="-fno-sanitize=alignment -lstdc++" + +# Install openssl_quic (need openssl_quic, nghttp3, and ngtcp2 for HTTP3 support) +${SCRIPTDIR}/handle_x.sh openssl_quic ${OPENSLLQUICDIR} ${INSTALLDIR} || exit 1 # Install openssl -${SCRIPTDIR}/handle_x.sh openssl ${OPENSSLDIR} ${INSTALLDIR} || exit 1 +# ${SCRIPTDIR}/handle_x.sh openssl ${OPENSSLDIR} ${INSTALLDIR} || exit 1 # Install nghttp2 -${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTPDIR} ${INSTALLDIR} || exit 1 +${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTP2DIR} ${INSTALLDIR} || exit 1 + +# Install nghttp3 +${SCRIPTDIR}/handle_x.sh nghttp3 ${NGHTTP3DIR} ${INSTALLDIR} || exit 1 + +# Install ngtcp2 +${SCRIPTDIR}/handle_x.sh ngtcp2 ${NGTCP2DIR} ${INSTALLDIR} || exit 1 # Install curl after all other dependencies ${SCRIPTDIR}/handle_x.sh curl ${CURLDIR} ${INSTALLDIR} || exit 1 diff --git a/scripts/download_nghttp3.sh b/scripts/download_nghttp3.sh new file mode 100755 index 000000000..1885bbc39 --- /dev/null +++ b/scripts/download_nghttp3.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# If any commands fail, fail the script immediately. +set -ex + +git clone --depth 1 --branch v1.1.0 https://github.com/ngtcp2/nghttp3 $1 diff --git a/scripts/download_ngtcp2.sh b/scripts/download_ngtcp2.sh new file mode 100755 index 000000000..4dc70fd8b --- /dev/null +++ b/scripts/download_ngtcp2.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# If any commands fail, fail the script immediately. +set -ex + +# Clone the repository to the specified directory. +git clone --depth 1 --branch v1.1.0 https://github.com/ngtcp2/ngtcp2 $1 diff --git a/scripts/download_openssl_quic.sh b/scripts/download_openssl_quic.sh new file mode 100755 index 000000000..e06468c1a --- /dev/null +++ b/scripts/download_openssl_quic.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# If any commands fail, fail the script immediately. +set -ex + +# Clone the curl repository to the specified directory. +git clone --depth 1 -b openssl-3.1.4+quic https://github.com/quictls/openssl $1 diff --git a/scripts/fuzz_targets b/scripts/fuzz_targets index 907a163a8..6af136157 100644 --- a/scripts/fuzz_targets +++ b/scripts/fuzz_targets @@ -1,3 +1,3 @@ #!/bin/bash -export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_https curl_fuzzer_imap curl_fuzzer_ldap curl_fuzzer_mqtt curl_fuzzer_pop3 curl_fuzzer_rtmp curl_fuzzer_rtsp curl_fuzzer_scp curl_fuzzer_sftp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer_ws curl_fuzzer fuzz_url" +export FUZZ_TARGETS="curl_fuzzer_dict curl_fuzzer_file curl_fuzzer_ftp curl_fuzzer_gopher curl_fuzzer_http curl_fuzzer_https curl_fuzzer_http3 curl_fuzzer_imap curl_fuzzer_ldap curl_fuzzer_mqtt curl_fuzzer_pop3 curl_fuzzer_rtmp curl_fuzzer_rtsp curl_fuzzer_scp curl_fuzzer_sftp curl_fuzzer_smb curl_fuzzer_smtp curl_fuzzer_tftp curl_fuzzer_ws curl_fuzzer fuzz_url" diff --git a/scripts/install_curl.sh b/scripts/install_curl.sh index 4d6ec4730..4211ef6cf 100755 --- a/scripts/install_curl.sh +++ b/scripts/install_curl.sh @@ -47,7 +47,8 @@ pushd ${SRCDIR} # Build the library. ./buildconf -./configure --prefix=${INSTALLDIR} \ +./configure PKG_CONFIG_PATH=${INSTALLDIR}/lib/pkgconfig \ + --prefix=${INSTALLDIR} \ --disable-shared \ --enable-debug \ --enable-maintainer-mode \ @@ -55,6 +56,9 @@ pushd ${SRCDIR} --enable-ipv6 \ --enable-websockets \ --with-random=/dev/null \ + --with-openssl \ + --with-nghttp3 \ + --with-ngtcp2 \ ${SSLOPTION} \ ${NGHTTPOPTION} \ ${CODE_COVERAGE_OPTION} diff --git a/scripts/install_nghttp3.sh b/scripts/install_nghttp3.sh new file mode 100755 index 000000000..e8b50cefe --- /dev/null +++ b/scripts/install_nghttp3.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# If any commands fail, fail the script immediately. +set -ex + +SRCDIR=$1 +INSTALLDIR=$2 + +if [[ ! -d ${INSTALLDIR} ]] +then + # Make an install target directory. + mkdir ${INSTALLDIR} +fi + +pushd ${SRCDIR} + +# Build the library. +autoreconf -fi +./configure --prefix=${INSTALLDIR} \ + --disable-shared \ + --enable-static \ + --disable-threads \ + --enable-lib-only + +make +make install diff --git a/scripts/install_ngtcp2.sh b/scripts/install_ngtcp2.sh new file mode 100755 index 000000000..ae3abd27f --- /dev/null +++ b/scripts/install_ngtcp2.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# If any commands fail, fail the script immediately. +set -ex + +SRCDIR=$1 +INSTALLDIR=$2 + +if [[ ! -d ${INSTALLDIR} ]] +then + # Make an install target directory. + mkdir ${INSTALLDIR} +fi + +pushd ${SRCDIR} + +autoreconf -fi +./configure PKG_CONFIG_PATH=${INSTALLDIR}/lib/pkgconfig \ + LDFLAGS="-Wl,-rpath,${INSTALLDIR}" \ + --prefix=${INSTALLDIR} \ + --disable-shared \ + --enable-static \ + --disable-threads \ + --enable-lib-only \ + --with-openssl \ + + +make +make install diff --git a/scripts/install_openssl_quic.sh b/scripts/install_openssl_quic.sh new file mode 100755 index 000000000..fd881cdce --- /dev/null +++ b/scripts/install_openssl_quic.sh @@ -0,0 +1,10 @@ + +#!/bin/bash + +# If any commands fail, fail the script immediately. +set -ex + +SRCDIR=$1 +INSTALLDIR=$2 + +$(dirname "$0")/install_openssl.sh $SRCDIR $INSTALLDIR From c43ca0edfc11baafd235bc0c73e48e5d547ab7ac Mon Sep 17 00:00:00 2001 From: Vasco Franco Date: Fri, 15 Dec 2023 22:40:35 +0000 Subject: [PATCH 2/8] Use DGRAM for HTTP3 --- curl_fuzzer_callback.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/curl_fuzzer_callback.cc b/curl_fuzzer_callback.cc index 7d6152fc9..eee46154b 100644 --- a/curl_fuzzer_callback.cc +++ b/curl_fuzzer_callback.cc @@ -69,7 +69,14 @@ curl_socket_t fuzz_open_socket(void *ptr, sman->index, sman->index); - if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) { + + #ifdef FUZZ_PROTOCOLS_HTTP3 + const int socket_type = SOCK_DGRAM; + #else + const int socket_type = SOCK_STREAM; + #endif + + if(socketpair(AF_UNIX, socket_type, 0, fds)) { /* Failed to create a pair of sockets. */ return CURL_SOCKET_BAD; } From 8015b69a557817dddfb21e3205ec67378ab97878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Sat, 16 Dec 2023 21:10:05 +0000 Subject: [PATCH 3/8] Disable CRL option for HTTPS HTTP/3 appears to fail with it set to /dev/null --- curl_fuzzer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/curl_fuzzer.cc b/curl_fuzzer.cc index a6df5b8b7..89a1c297c 100644 --- a/curl_fuzzer.cc +++ b/curl_fuzzer.cc @@ -207,8 +207,10 @@ int fuzz_set_easy_options(FUZZ_DATA *fuzz) /* Set the hsts header cache filepath so that it can be fuzzed. */ FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_HSTS, FUZZ_HSTS_HEADER_CACHE_PATH)); +#ifndef FUZZ_PROTOCOLS_HTTPS /* Set the Certificate Revocation List file path so it can be fuzzed */ FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_CRLFILE, FUZZ_CRL_FILE_PATH)); +#endif /* Set the .netrc file path so it can be fuzzed */ FTRY(curl_easy_setopt(fuzz->easy, CURLOPT_NETRC_FILE, FUZZ_NETRC_FILE_PATH)); From 418955392f0ebe31a4d56aa957d58ab3190f7d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Sat, 16 Dec 2023 21:10:40 +0000 Subject: [PATCH 4/8] Add option to override ngtcp2 directory --- mainline.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mainline.sh b/mainline.sh index 9adc6edfd..dc510ddb5 100755 --- a/mainline.sh +++ b/mainline.sh @@ -17,15 +17,17 @@ INSTALLDIR=/tmp/curl_install # Parse the options. OPTIND=1 -while getopts "c:n:o:" opt +while getopts "c:n:o:t:" opt do case "$opt" in c) CURLDIR=$OPTARG ;; - n) NGHTTPDIR=$OPTARG + n) NGHTTP2DIR=$OPTARG ;; o) OPENSSLDIR=$OPTARG ;; + t) NGTCP2DIR=$OPTARG + ;; esac done shift $((OPTIND-1)) From 4630c29d49ddb5ffbb4e4a0e153126cd7b688bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Tue, 2 Jan 2024 22:47:19 +0000 Subject: [PATCH 5/8] Enable HTTP/3 build for OSS-Fuzz --- ossfuzz.sh | 17 ++++++-- scripts/download_ngtcp2.sh | 81 ++++++++++++++++++++++++++++++++++++++ scripts/install_curl.sh | 19 +++++++++ 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/ossfuzz.sh b/ossfuzz.sh index b70772bee..cec60d312 100755 --- a/ossfuzz.sh +++ b/ossfuzz.sh @@ -29,7 +29,9 @@ SCRIPTDIR=${BUILD_ROOT}/scripts ZLIBDIR=/src/zlib OPENSSLDIR=/src/openssl -NGHTTPDIR=/src/nghttp2 +NGHTTP2DIR=/src/nghttp2 +NGHTTP3DIR=/src/nghttp3 +NGTCP2DIR=/src/ngtcp2 GDBDIR=/src/gdb # Check for GDB-specific behaviour by checking for the GDBMODE flag. @@ -74,13 +76,20 @@ ${SCRIPTDIR}/handle_x.sh zlib ${ZLIBDIR} ${INSTALLDIR} || exit 1 # affect (see 16697, 17624) if [[ ${SANITIZER} != "memory" ]] then - # Install openssl + # Install openssl_quic (need openssl_quic, nghttp3, and ngtcp2 for HTTP3 support) export OPENSSLFLAGS="-fno-sanitize=alignment" - ${SCRIPTDIR}/handle_x.sh openssl ${OPENSSLDIR} ${INSTALLDIR} || exit 1 + ${SCRIPTDIR}/handle_x.sh openssl_quic ${OPENSSLDIR} ${INSTALLDIR} || exit 1 + + # HTTP3 requires SSL, so we also install it here + # Install nghttp3 + ${SCRIPTDIR}/handle_x.sh nghttp3 ${NGHTTP3DIR} ${INSTALLDIR} || exit 1 + + # Install ngtcp2 + ${SCRIPTDIR}/handle_x.sh ngtcp2 ${NGTCP2DIR} ${INSTALLDIR} || exit 1 fi # Install nghttp2 -${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTPDIR} ${INSTALLDIR} || exit 1 +${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTP2DIR} ${INSTALLDIR} || exit 1 # Compile curl ${SCRIPTDIR}/install_curl.sh /src/curl ${INSTALLDIR} diff --git a/scripts/download_ngtcp2.sh b/scripts/download_ngtcp2.sh index 4dc70fd8b..93b40a363 100755 --- a/scripts/download_ngtcp2.sh +++ b/scripts/download_ngtcp2.sh @@ -5,3 +5,84 @@ set -ex # Clone the repository to the specified directory. git clone --depth 1 --branch v1.1.0 https://github.com/ngtcp2/ngtcp2 $1 + +# Teach ngtcp2 about sockets +pushd $1 +patch -p1 <<'EOF' +From 52690d08112ccd9a5c01b5991735bf3f8e5121b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Emilio=20L=C3=B3pez?= +Date: Sat, 16 Dec 2023 21:33:17 +0000 +Subject: [PATCH] Teach ngtcp2 about sockets + +--- + crypto/shared.c | 4 ++++ + lib/includes/ngtcp2/ngtcp2.h | 5 +++++ + lib/ngtcp2_addr.c | 8 ++++++++ + 3 files changed, 17 insertions(+) + +diff --git a/crypto/shared.c b/crypto/shared.c +index 162094a3..08c9ed44 100644 +--- a/crypto/shared.c ++++ b/crypto/shared.c +@@ -1096,6 +1096,10 @@ static size_t crypto_generate_regular_token_aad(uint8_t *dest, + (const uint8_t *)&((const ngtcp2_sockaddr_in6 *)(void *)sa)->sin6_addr; + addrlen = sizeof(((const ngtcp2_sockaddr_in6 *)(void *)sa)->sin6_addr); + break; ++ case NGTCP2_AF_UNIX: ++ addr = NULL; ++ addrlen = 0; ++ break; + default: + assert(0); + abort(); +diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h +index a8d4b4af..63958e4c 100644 +--- a/lib/includes/ngtcp2/ngtcp2.h ++++ b/lib/includes/ngtcp2/ngtcp2.h +@@ -1235,6 +1235,10 @@ typedef struct ngtcp2_pkt_stateless_reset { + # error NGTCP2_AF_INET6 must be defined + # endif /* !NGTCP2_AF_INET6 */ + ++# ifndef NGTCP2_AF_UNIX ++# error NGTCP2_AF_UNIX must be defined ++# endif /* !NGTCP2_AF_UNIX */ ++ + typedef unsigned short int ngtcp2_sa_family; + typedef uint16_t ngtcp2_in_port; + +@@ -1270,6 +1274,7 @@ typedef uint32_t ngtcp2_socklen; + #else /* !NGTCP2_USE_GENERIC_SOCKADDR */ + # define NGTCP2_AF_INET AF_INET + # define NGTCP2_AF_INET6 AF_INET6 ++# define NGTCP2_AF_UNIX AF_UNIX + + /** + * @typedef +diff --git a/lib/ngtcp2_addr.c b/lib/ngtcp2_addr.c +index f389abe7..26b57f3d 100644 +--- a/lib/ngtcp2_addr.c ++++ b/lib/ngtcp2_addr.c +@@ -67,6 +67,10 @@ static int sockaddr_eq(const ngtcp2_sockaddr *a, const ngtcp2_sockaddr *b) { + return ai->sin6_port == bi->sin6_port && + memcmp(&ai->sin6_addr, &bi->sin6_addr, sizeof(ai->sin6_addr)) == 0; + } ++ case NGTCP2_AF_UNIX: { ++ // TODO: see what makes sense here ++ return 1; ++ } + default: + ngtcp2_unreachable(); + } +@@ -109,6 +113,10 @@ uint32_t ngtcp2_addr_compare(const ngtcp2_addr *aa, const ngtcp2_addr *bb) { + } + return flags; + } ++ case NGTCP2_AF_UNIX: { ++ // TODO: see what makes sense here? ++ return 0; ++ } + default: + ngtcp2_unreachable(); + } +EOF +popd diff --git a/scripts/install_curl.sh b/scripts/install_curl.sh index 4211ef6cf..fc090625d 100755 --- a/scripts/install_curl.sh +++ b/scripts/install_curl.sh @@ -45,6 +45,25 @@ fi pushd ${SRCDIR} +# TODO: Ignore HTTP3 socket connection failures +pushd $1 +patch -p1 <<'EOF' +diff --git a/lib/cf-socket.c b/lib/cf-socket.c +index e42b4a87b..f99fcd80c 100644 +--- a/lib/cf-socket.c ++++ b/lib/cf-socket.c +@@ -1650,7 +1650,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, + + rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen); + if(-1 == rc) { +- return socket_connect_result(data, ctx->r_ip, SOCKERRNO); ++ /* return socket_connect_result(data, ctx->r_ip, SOCKERRNO); */ + } + set_local_ip(cf, data); + CURL_TRC_CF(data, cf, "%s socket %" CURL_FORMAT_SOCKET_T +EOF +popd + # Build the library. ./buildconf ./configure PKG_CONFIG_PATH=${INSTALLDIR}/lib/pkgconfig \ From 890ad204c87858bd0c84a76c7ce5a93728d2fa31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Thu, 4 Jan 2024 19:47:59 +0000 Subject: [PATCH 6/8] corpora: add sample case for curl_fuzzer_http3 --- corpora/curl_fuzzer_http3/test_simple_httppost | Bin 0 -> 157 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 corpora/curl_fuzzer_http3/test_simple_httppost diff --git a/corpora/curl_fuzzer_http3/test_simple_httppost b/corpora/curl_fuzzer_http3/test_simple_httppost new file mode 100644 index 0000000000000000000000000000000000000000..e7e295dc763add38cb2ff411a4dc36675d9367d3 GIT binary patch literal 157 zcmW;CF$=;#42Iz-;vhH(f({OGZ%wZ{W$hv;=+Lb=Ts7EAxhri1Mf~p`^6^g32Lk|D zSE_B#LMmW literal 0 HcmV?d00001 From 2f9cecfd7882c5909354d714f44e6a398376dfb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 5 Jan 2024 19:32:35 +0000 Subject: [PATCH 7/8] renovate: add quictls, ngtcp2, nghttp3 to VERSIONS --- renovate.json | 11 +++++++++++ scripts/VERSIONS | 9 +++++++++ scripts/download_nghttp3.sh | 7 ++++++- scripts/download_ngtcp2.sh | 6 +++++- scripts/download_openssl_quic.sh | 8 ++++++-- 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/renovate.json b/renovate.json index 32f5071d7..3d6693b1b 100644 --- a/renovate.json +++ b/renovate.json @@ -23,6 +23,17 @@ "depNameTemplate": "openssl/openssl", "versioningTemplate": "regex:^openssl-(?\\d+)\\.(?\\d+)\\.(?\\d+)$", "registryUrlTemplate": "https://github.com" + }, + { + "customType": "regex", + "fileMatch": ["^scripts/VERSIONS$"], + "matchStrings": [ + "QUICTLS_VERSION=(?.*)\\s" + ], + "datasourceTemplate": "github-tags", + "depNameTemplate": "openssl/openssl", + "versioningTemplate": "regex:^openssl-(?\\d+)\\.(?\\d+)\\.(?\\d+)-quic\\d+$", + "registryUrlTemplate": "https://github.com" } ], "packageRules": [ diff --git a/scripts/VERSIONS b/scripts/VERSIONS index 4cc543388..1e1a19a10 100644 --- a/scripts/VERSIONS +++ b/scripts/VERSIONS @@ -3,5 +3,14 @@ # Handled by renovate.json OPENSSL_VERSION=openssl-3.2.0 +# Handled by renovate.json +QUICTLS_VERSION=openssl-3.1.4-quic1 + # renovate: datasource=github-tags depName=nghttp2/nghttp2 versioning=semver registryUrl=https://github.com NGHTTP2_VERSION=v1.58.0 + +# renovate: datasource=github-tags depName=ngtcp2/nghttp3 versioning=semver registryUrl=https://github.com +NGHTTP3_VERSION=v1.1.0 + +# renovate: datasource=github-tags depName=ngtcp2/ngtcp2 versioning=semver registryUrl=https://github.com +NGTCP2_VERSION=v1.1.0 diff --git a/scripts/download_nghttp3.sh b/scripts/download_nghttp3.sh index 1885bbc39..809a9b013 100755 --- a/scripts/download_nghttp3.sh +++ b/scripts/download_nghttp3.sh @@ -3,4 +3,9 @@ # If any commands fail, fail the script immediately. set -ex -git clone --depth 1 --branch v1.1.0 https://github.com/ngtcp2/nghttp3 $1 +# Get the script directory and source the VERSIONS file +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source $SCRIPT_DIR/VERSIONS + +# Clone the repository to the specified directory. +git clone --depth 1 --branch ${NGHTTP3_VERSION} https://github.com/ngtcp2/nghttp3 $1 diff --git a/scripts/download_ngtcp2.sh b/scripts/download_ngtcp2.sh index 93b40a363..8569af9e2 100755 --- a/scripts/download_ngtcp2.sh +++ b/scripts/download_ngtcp2.sh @@ -3,8 +3,12 @@ # If any commands fail, fail the script immediately. set -ex +# Get the script directory and source the VERSIONS file +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source $SCRIPT_DIR/VERSIONS + # Clone the repository to the specified directory. -git clone --depth 1 --branch v1.1.0 https://github.com/ngtcp2/ngtcp2 $1 +git clone --depth 1 --branch ${NGTCP2_VERSION} https://github.com/ngtcp2/ngtcp2 $1 # Teach ngtcp2 about sockets pushd $1 diff --git a/scripts/download_openssl_quic.sh b/scripts/download_openssl_quic.sh index e06468c1a..06320bddb 100755 --- a/scripts/download_openssl_quic.sh +++ b/scripts/download_openssl_quic.sh @@ -3,5 +3,9 @@ # If any commands fail, fail the script immediately. set -ex -# Clone the curl repository to the specified directory. -git clone --depth 1 -b openssl-3.1.4+quic https://github.com/quictls/openssl $1 +# Get the script directory and source the VERSIONS file +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source $SCRIPT_DIR/VERSIONS + +# Clone the repository to the specified directory. +git clone --depth 1 --branch ${QUICTLS_VERSION} https://github.com/quictls/openssl $1 From 3007983f0964ef94e0b6496ab07ae578d81c1593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 5 Jan 2024 19:51:04 +0000 Subject: [PATCH 8/8] mainline, ossfuzz: build with both OpenSSL and quictls --- Makefile.am | 12 +++++---- mainline.sh | 33 +++++++++++++------------ ossfuzz.sh | 51 ++++++++++++++++++++++----------------- scripts/download_curl.sh | 18 ++++++++++++++ scripts/install_curl.sh | 44 +++++++++++++++------------------ scripts/install_ngtcp2.sh | 1 - 6 files changed, 91 insertions(+), 68 deletions(-) diff --git a/Makefile.am b/Makefile.am index dd39df401..30ddb80f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,7 @@ ACLOCAL_AMFLAGS = -I m4 @CODE_COVERAGE_RULES@ # Include debug symbols by default as recommended by libfuzzer. -AM_CXXFLAGS = -g -I@INSTALLDIR@/include -I@INSTALLDIR@/utfuzzer +AM_CXXFLAGS = -g LIBS = -lpthread -lm @@ -60,8 +60,10 @@ FUZZPROGS = curl_fuzzer \ FUZZLIBS = libstandaloneengine.a COMMON_SOURCES = curl_fuzzer.cc curl_fuzzer_tlv.cc curl_fuzzer_callback.cc -COMMON_FLAGS = $(AM_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) -COMMON_LDADD = @INSTALLDIR@/lib/libcurl.la $(LIB_FUZZING_ENGINE) $(CODE_COVERAGE_LIBS) +COMMON_FLAGS = -I@INSTALLDIR@/openssl/include -I@INSTALLDIR@/openssl/utfuzzer $(AM_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) +COMMON_LDADD = @INSTALLDIR@/openssl/lib/libcurl.la $(LIB_FUZZING_ENGINE) $(CODE_COVERAGE_LIBS) +HTTP3_FLAGS = -I@INSTALLDIR@/openssl_quic/include -I@INSTALLDIR@/openssl_quic/utfuzzer $(AM_CXXFLAGS) $(CODE_COVERAGE_CXXFLAGS) +HTTP3_LDADD = @INSTALLDIR@/openssl_quic/lib/libcurl.la $(LIB_FUZZING_ENGINE) $(CODE_COVERAGE_LIBS) libstandaloneengine_a_SOURCES = standalone_fuzz_target_runner.cc libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS) @@ -91,8 +93,8 @@ curl_fuzzer_https_SOURCES = $(COMMON_SOURCES) curl_fuzzer_https_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_HTTPS curl_fuzzer_https_LDADD = $(COMMON_LDADD) curl_fuzzer_http3_SOURCES = $(COMMON_SOURCES) -curl_fuzzer_http3_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_HTTP3 -DFUZZ_PROTOCOLS_HTTPS -curl_fuzzer_http3_LDADD = $(COMMON_LDADD) +curl_fuzzer_http3_CXXFLAGS = $(HTTP3_FLAGS) -DFUZZ_PROTOCOLS_HTTP3 -DFUZZ_PROTOCOLS_HTTPS +curl_fuzzer_http3_LDADD = $(HTTP3_LDADD) curl_fuzzer_imap_SOURCES = $(COMMON_SOURCES) curl_fuzzer_imap_CXXFLAGS = $(COMMON_FLAGS) -DFUZZ_PROTOCOLS_IMAP curl_fuzzer_imap_LDADD = $(COMMON_LDADD) diff --git a/mainline.sh b/mainline.sh index dc510ddb5..f0c18c669 100755 --- a/mainline.sh +++ b/mainline.sh @@ -11,8 +11,7 @@ OPENSSLDIR=/tmp/openssl NGHTTP2DIR=/tmp/nghttp2 NGHTTP3DIR=/tmp/nghttp3 NGTCP2DIR=/tmp/ngtcp2 -OPENSLLQUICDIR=/tmp/openssl_quic -INSTALLDIR=/tmp/curl_install +INSTALLDIRTOP=/tmp/curl_install # Parse the options. OPTIND=1 @@ -41,23 +40,27 @@ export CXXFLAGS="-fsanitize=address -stdlib=libstdc++ $FUZZ_FLAG" export CPPFLAGS="$FUZZ_FLAG" export OPENSSLFLAGS="-fno-sanitize=alignment -lstdc++" -# Install openssl_quic (need openssl_quic, nghttp3, and ngtcp2 for HTTP3 support) -${SCRIPTDIR}/handle_x.sh openssl_quic ${OPENSLLQUICDIR} ${INSTALLDIR} || exit 1 +for tls_lib in openssl openssl_quic; do + INSTALLDIR="$INSTALLDIRTOP/$tls_lib" + mkdir -p "$INSTALLDIR" -# Install openssl -# ${SCRIPTDIR}/handle_x.sh openssl ${OPENSSLDIR} ${INSTALLDIR} || exit 1 + # Install tls_lib + ${SCRIPTDIR}/handle_x.sh ${tls_lib} ${OPENSSLDIR}/${tls_lib} ${INSTALLDIR} || exit 1 -# Install nghttp2 -${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTP2DIR} ${INSTALLDIR} || exit 1 + # Install nghttp2 + ${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTP2DIR} ${INSTALLDIR} || exit 1 -# Install nghttp3 -${SCRIPTDIR}/handle_x.sh nghttp3 ${NGHTTP3DIR} ${INSTALLDIR} || exit 1 + if [[ "$tls_lib" == "openssl_quic" ]]; then + # Install nghttp3 + ${SCRIPTDIR}/handle_x.sh nghttp3 ${NGHTTP3DIR} ${INSTALLDIR} || exit 1 -# Install ngtcp2 -${SCRIPTDIR}/handle_x.sh ngtcp2 ${NGTCP2DIR} ${INSTALLDIR} || exit 1 + # Install ngtcp2 + ${SCRIPTDIR}/handle_x.sh ngtcp2 ${NGTCP2DIR} ${INSTALLDIR} || exit 1 + fi -# Install curl after all other dependencies -${SCRIPTDIR}/handle_x.sh curl ${CURLDIR} ${INSTALLDIR} || exit 1 + # Install curl after all other dependencies + ${SCRIPTDIR}/handle_x.sh curl ${CURLDIR} ${INSTALLDIR} || exit 1 +done # Compile and test the fuzzers. -${SCRIPTDIR}/compile_fuzzer.sh ${INSTALLDIR} || exit 1 +${SCRIPTDIR}/compile_fuzzer.sh ${INSTALLDIRTOP} || exit 1 diff --git a/ossfuzz.sh b/ossfuzz.sh index cec60d312..7152b3e1a 100755 --- a/ossfuzz.sh +++ b/ossfuzz.sh @@ -55,7 +55,7 @@ echo "FUZZ_TARGETS: $FUZZ_TARGETS" export MAKEFLAGS+="-j$(nproc)" # Make an install directory -export INSTALLDIR=/src/curl_install +export INSTALLDIRTOP=/src/curl_install # Check for GDB-specific behaviour by checking for the GDBMODE flag. # - Compile and installing GDB if necessary. @@ -69,33 +69,40 @@ then fi fi -# Install zlib -${SCRIPTDIR}/handle_x.sh zlib ${ZLIBDIR} ${INSTALLDIR} || exit 1 +for tls_lib in openssl openssl_quic; do + INSTALLDIR="$INSTALLDIRTOP/$tls_lib" + mkdir -p "$INSTALLDIR" -# For the memory sanitizer build, turn off OpenSSL as it causes bugs we can't -# affect (see 16697, 17624) -if [[ ${SANITIZER} != "memory" ]] -then - # Install openssl_quic (need openssl_quic, nghttp3, and ngtcp2 for HTTP3 support) - export OPENSSLFLAGS="-fno-sanitize=alignment" - ${SCRIPTDIR}/handle_x.sh openssl_quic ${OPENSSLDIR} ${INSTALLDIR} || exit 1 - - # HTTP3 requires SSL, so we also install it here - # Install nghttp3 - ${SCRIPTDIR}/handle_x.sh nghttp3 ${NGHTTP3DIR} ${INSTALLDIR} || exit 1 + # Install zlib + ${SCRIPTDIR}/handle_x.sh zlib ${ZLIBDIR} ${INSTALLDIR} || exit 1 - # Install ngtcp2 - ${SCRIPTDIR}/handle_x.sh ngtcp2 ${NGTCP2DIR} ${INSTALLDIR} || exit 1 -fi + # For the memory sanitizer build, turn off OpenSSL as it causes bugs we can't + # affect (see 16697, 17624) + if [[ ${SANITIZER} != "memory" ]] + then + # Install openssl_quic (need openssl_quic, nghttp3, and ngtcp2 for HTTP3 support) + export OPENSSLFLAGS="-fno-sanitize=alignment" + ${SCRIPTDIR}/handle_x.sh ${tls_lib} ${OPENSSLDIR}/${tls_lib} ${INSTALLDIR} || exit 1 + + if [[ "$tls_lib" == "openssl_quic" ]] + then + # Install nghttp3 + ${SCRIPTDIR}/handle_x.sh nghttp3 ${NGHTTP3DIR} ${INSTALLDIR} || exit 1 + + # Install ngtcp2 + ${SCRIPTDIR}/handle_x.sh ngtcp2 ${NGTCP2DIR} ${INSTALLDIR} || exit 1 + fi + fi -# Install nghttp2 -${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTP2DIR} ${INSTALLDIR} || exit 1 + # Install nghttp2 + ${SCRIPTDIR}/handle_x.sh nghttp2 ${NGHTTP2DIR} ${INSTALLDIR} || exit 1 -# Compile curl -${SCRIPTDIR}/install_curl.sh /src/curl ${INSTALLDIR} + # Compile curl + ${SCRIPTDIR}/install_curl.sh /src/curl ${INSTALLDIR} +done # Build the fuzzers. -${SCRIPTDIR}/compile_fuzzer.sh ${INSTALLDIR} +${SCRIPTDIR}/compile_fuzzer.sh ${INSTALLDIRTOP} make zip # Copy the fuzzers over. diff --git a/scripts/download_curl.sh b/scripts/download_curl.sh index 0d078d885..6a90b9830 100755 --- a/scripts/download_curl.sh +++ b/scripts/download_curl.sh @@ -6,3 +6,21 @@ set -ex # Clone the curl repository to the specified directory. git clone http://github.com/curl/curl $1 +# TODO: Ignore HTTP3 socket connection failures +pushd $1 +patch -p1 <<'EOF' +diff --git a/lib/cf-socket.c b/lib/cf-socket.c +index e42b4a87b..f99fcd80c 100644 +--- a/lib/cf-socket.c ++++ b/lib/cf-socket.c +@@ -1650,7 +1650,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, + + rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen); + if(-1 == rc) { +- return socket_connect_result(data, ctx->r_ip, SOCKERRNO); ++ /* return socket_connect_result(data, ctx->r_ip, SOCKERRNO); */ + } + set_local_ip(cf, data); + CURL_TRC_CF(data, cf, "%s socket %" CURL_FORMAT_SOCKET_T +EOF +popd diff --git a/scripts/install_curl.sh b/scripts/install_curl.sh index fc090625d..99c7728d3 100755 --- a/scripts/install_curl.sh +++ b/scripts/install_curl.sh @@ -38,31 +38,26 @@ fi if [[ -f ${INSTALLDIR}/lib/libnghttp2.a ]] then - NGHTTPOPTION=--with-nghttp2=${INSTALLDIR} + NGHTTP2OPTION=--with-nghttp2=${INSTALLDIR} else - NGHTTPOPTION=--without-nghttp2 + NGHTTP2OPTION=--without-nghttp2 fi -pushd ${SRCDIR} +if [[ -f ${INSTALLDIR}/lib/libnghttp3.a ]] +then + NGHTTP3OPTION=--with-nghttp3=${INSTALLDIR} +else + NGHTTP3OPTION=--without-nghttp3 +fi -# TODO: Ignore HTTP3 socket connection failures -pushd $1 -patch -p1 <<'EOF' -diff --git a/lib/cf-socket.c b/lib/cf-socket.c -index e42b4a87b..f99fcd80c 100644 ---- a/lib/cf-socket.c -+++ b/lib/cf-socket.c -@@ -1650,7 +1650,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, - - rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen); - if(-1 == rc) { -- return socket_connect_result(data, ctx->r_ip, SOCKERRNO); -+ /* return socket_connect_result(data, ctx->r_ip, SOCKERRNO); */ - } - set_local_ip(cf, data); - CURL_TRC_CF(data, cf, "%s socket %" CURL_FORMAT_SOCKET_T -EOF -popd +if [[ -f ${INSTALLDIR}/lib/libngtcp2.a ]] +then + NGTCP2OPTION=--with-ngtcp2=${INSTALLDIR} +else + NGTCP2OPTION=--without-ngtcp2 +fi + +pushd ${SRCDIR} # Build the library. ./buildconf @@ -75,11 +70,10 @@ popd --enable-ipv6 \ --enable-websockets \ --with-random=/dev/null \ - --with-openssl \ - --with-nghttp3 \ - --with-ngtcp2 \ ${SSLOPTION} \ - ${NGHTTPOPTION} \ + ${NGHTTP2OPTION} \ + ${NGHTTP3OPTION} \ + ${NGTCP2OPTION} \ ${CODE_COVERAGE_OPTION} make V=1 diff --git a/scripts/install_ngtcp2.sh b/scripts/install_ngtcp2.sh index ae3abd27f..3e53e8314 100755 --- a/scripts/install_ngtcp2.sh +++ b/scripts/install_ngtcp2.sh @@ -20,7 +20,6 @@ autoreconf -fi --prefix=${INSTALLDIR} \ --disable-shared \ --enable-static \ - --disable-threads \ --enable-lib-only \ --with-openssl \