summaryrefslogtreecommitdiff
path: root/security/nss/fuzz
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commitad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299 (patch)
tree10027f336435511475e392454359edea8e25895d /security/nss/fuzz
parent15477ed9af4859dacb069040b5d4de600803d3bc (diff)
downloaduxp-ad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'security/nss/fuzz')
-rw-r--r--security/nss/fuzz/.clang-format4
-rwxr-xr-xsecurity/nss/fuzz/clone_corpus.sh4
-rwxr-xr-xsecurity/nss/fuzz/clone_libfuzzer.sh4
-rw-r--r--security/nss/fuzz/fuzz.gyp65
-rwxr-xr-xsecurity/nss/fuzz/git-copy.sh32
-rw-r--r--security/nss/fuzz/nssfuzz.cc148
-rw-r--r--security/nss/fuzz/pkcs8_target.cc37
-rw-r--r--security/nss/fuzz/quickder_targets.cc36
-rw-r--r--security/nss/fuzz/registry.h71
-rw-r--r--security/nss/fuzz/shared.h18
-rw-r--r--security/nss/fuzz/warning.txt15
11 files changed, 434 insertions, 0 deletions
diff --git a/security/nss/fuzz/.clang-format b/security/nss/fuzz/.clang-format
new file mode 100644
index 0000000000..06e3c5115f
--- /dev/null
+++ b/security/nss/fuzz/.clang-format
@@ -0,0 +1,4 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+...
diff --git a/security/nss/fuzz/clone_corpus.sh b/security/nss/fuzz/clone_corpus.sh
new file mode 100755
index 0000000000..a41cbc0c50
--- /dev/null
+++ b/security/nss/fuzz/clone_corpus.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+d=$(dirname $0)
+exec $d/git-copy.sh https://github.com/mozilla/nss-fuzzing-corpus master $d/corpus
diff --git a/security/nss/fuzz/clone_libfuzzer.sh b/security/nss/fuzz/clone_libfuzzer.sh
new file mode 100755
index 0000000000..91c93de314
--- /dev/null
+++ b/security/nss/fuzz/clone_libfuzzer.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+d=$(dirname $0)
+exec $d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer 1b543d6e5073b56be214394890c9193979a3d7e1 $d/libFuzzer
diff --git a/security/nss/fuzz/fuzz.gyp b/security/nss/fuzz/fuzz.gyp
new file mode 100644
index 0000000000..4321c5cf5e
--- /dev/null
+++ b/security/nss/fuzz/fuzz.gyp
@@ -0,0 +1,65 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+{
+ 'includes': [
+ '../coreconf/config.gypi',
+ '../cmd/platlibs.gypi'
+ ],
+ 'targets': [
+ {
+ 'target_name': 'libFuzzer',
+ 'type': 'static_library',
+ 'sources': [
+ 'libFuzzer/FuzzerCrossOver.cpp',
+ 'libFuzzer/FuzzerDriver.cpp',
+ 'libFuzzer/FuzzerExtFunctionsDlsym.cpp',
+ 'libFuzzer/FuzzerExtFunctionsWeak.cpp',
+ 'libFuzzer/FuzzerIO.cpp',
+ 'libFuzzer/FuzzerLoop.cpp',
+ 'libFuzzer/FuzzerMutate.cpp',
+ 'libFuzzer/FuzzerSHA1.cpp',
+ 'libFuzzer/FuzzerTracePC.cpp',
+ 'libFuzzer/FuzzerTraceState.cpp',
+ 'libFuzzer/FuzzerUtil.cpp',
+ 'libFuzzer/FuzzerUtilDarwin.cpp',
+ 'libFuzzer/FuzzerUtilLinux.cpp',
+ ],
+ 'cflags': [
+ '-O2',
+ ],
+ 'cflags/': [
+ ['exclude', '-fsanitize='],
+ ['exclude', '-fsanitize-'],
+ ],
+ 'xcode_settings': {
+ 'GCC_OPTIMIZATION_LEVEL': '2', # -O2
+ 'OTHER_CFLAGS/': [
+ ['exclude', '-fsanitize='],
+ ['exclude', '-fsanitize-'],
+ ],
+ },
+ },
+ {
+ 'target_name': 'nssfuzz',
+ 'type': 'executable',
+ 'sources': [
+ 'nssfuzz.cc',
+ 'pkcs8_target.cc',
+ 'quickder_targets.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ 'libFuzzer',
+ ]
+ }
+ ],
+ 'target_defaults': {
+ 'include_dirs': [
+ 'libFuzzer',
+ ],
+ },
+ 'variables': {
+ 'module': 'nss',
+ }
+}
diff --git a/security/nss/fuzz/git-copy.sh b/security/nss/fuzz/git-copy.sh
new file mode 100755
index 0000000000..1389ddabde
--- /dev/null
+++ b/security/nss/fuzz/git-copy.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $0 <repo> <branch> <directory>" 1>&2
+ exit 2
+fi
+
+REPO=$1
+COMMIT=$2
+DIR=$3
+
+echo "Copy '$COMMIT' from '$REPO' to '$DIR'"
+if [ -f $DIR/.git-copy ]; then
+ CURRENT=$(cat $DIR/.git-copy)
+ if [ $(echo -n $COMMIT | wc -c) != "40" ]; then
+ ACTUAL=$(git ls-remote $REPO $COMMIT | cut -c 1-40 -)
+ else
+ ACTUAL=$COMMIT
+ fi
+ if [ CURRENT = ACTUAL ]; then
+ echo "Up to date."
+ fi
+fi
+
+mkdir -p $DIR
+git -C $DIR init -q
+git -C $DIR fetch -q --depth=1 $REPO $COMMIT:git-copy-tmp
+git -C $DIR reset --hard git-copy-tmp
+git -C $DIR show-ref HEAD | cut -c 1-40 - > $DIR/.git-copy
+rm -rf $DIR/.git
diff --git a/security/nss/fuzz/nssfuzz.cc b/security/nss/fuzz/nssfuzz.cc
new file mode 100644
index 0000000000..d9769309a4
--- /dev/null
+++ b/security/nss/fuzz/nssfuzz.cc
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <iomanip>
+#include <iostream>
+#include <memory>
+
+#include "keyhi.h"
+#include "pk11pub.h"
+
+#include "FuzzerInternal.h"
+#include "registry.h"
+#include "shared.h"
+
+using namespace std;
+
+class Args {
+ public:
+ Args(int argc, char **argv) : args_(argv, argv + argc) {}
+
+ string &operator[](const int idx) { return args_[idx]; }
+
+ bool Has(const string &arg) {
+ return any_of(args_.begin(), args_.end(),
+ [&arg](string &a) { return a.find(arg) == 0; });
+ }
+
+ void Append(const string &arg) { args_.push_back(arg); }
+
+ void Remove(const int index) {
+ assert(index < count());
+ args_.erase(args_.begin() + index);
+ }
+
+ vector<char *> argv() {
+ vector<char *> out;
+ out.resize(count());
+
+ transform(args_.begin(), args_.end(), out.begin(),
+ [](string &a) { return const_cast<char *>(a.c_str()); });
+
+ return out;
+ }
+
+ size_t count() { return args_.size(); }
+
+ private:
+ vector<string> args_;
+};
+
+void printUsage(Args &args) {
+ size_t sep = args[0].rfind("/") + 1;
+ string progName = args[0].substr(sep);
+
+ cerr << progName << " - Various libFuzzer targets for NSS" << endl << endl;
+ cerr << "Usage: " << progName << " <target> <libFuzzer options>" << endl
+ << endl;
+ cerr << "Valid targets:" << endl;
+
+ vector<string> names = Registry::Names();
+
+ // Find length of the longest name.
+ size_t name_w =
+ max_element(names.begin(), names.end(), [](string &a, string &b) {
+ return a.size() < b.size();
+ })->size();
+
+ // Find length of the longest description.
+ auto max = max_element(names.begin(), names.end(), [](string &a, string &b) {
+ return Registry::Desc(a).size() < Registry::Desc(b).size();
+ });
+ size_t desc_w = Registry::Desc(*max).size();
+
+ // Print list of targets.
+ for (string name : names) {
+ cerr << " " << left << setw(name_w) << name << " - " << setw(desc_w)
+ << Registry::Desc(name)
+ << " [default max_len=" << Registry::MaxLen(name) << "]" << endl;
+ }
+
+ // Some usage examples.
+ cerr << endl << "Run fuzzer with a given corpus directory:" << endl;
+ cerr << " " << progName << " <target> /path/to/corpus" << endl;
+
+ cerr << endl << "Run fuzzer with a single test input:" << endl;
+ cerr << " " << progName
+ << " <target> ./crash-14d4355b971092e39572bc306a135ddf9f923e19" << endl;
+
+ cerr << endl
+ << "Specify the number of cores you wish to dedicate to fuzzing:"
+ << endl;
+ cerr << " " << progName << " <target> -jobs=8 -workers=8 /path/to/corpus"
+ << endl;
+
+ cerr << endl << "Override the maximum length of a test input:" << endl;
+ cerr << " " << progName << " <target> -max_len=2048 /path/to/corpus" << endl;
+
+ cerr << endl
+ << "Minimize a given corpus and put the result into 'new_corpus':"
+ << endl;
+ cerr << " " << progName
+ << " <target> -merge=1 -max_len=50000 ./new_corpus /path/to/corpus"
+ << endl;
+
+ cerr << endl << "Merge new test inputs into a corpus:" << endl;
+ cerr
+ << " " << progName
+ << " <target> -merge=1 -max_len=50000 /path/to/corpus ./inputs1 ./inputs2"
+ << endl;
+
+ cerr << endl << "Print libFuzzer usage information:" << endl;
+ cerr << " " << progName << " <target> -help=1" << endl << endl;
+
+ cerr << "Check out the docs at http://llvm.org/docs/LibFuzzer.html" << endl;
+}
+
+int main(int argc, char **argv) {
+ Args args(argc, argv);
+
+ if (args.count() < 2 || !Registry::Has(args[1])) {
+ printUsage(args);
+ return 1;
+ }
+
+ string targetName(args[1]);
+
+ // Remove the target argument when -workers=x or -jobs=y is NOT given.
+ // If both are given, libFuzzer will spawn multiple processes for the target.
+ if (!args.Has("-workers=") || !args.Has("-jobs=")) {
+ args.Remove(1);
+ }
+
+ // Set default max_len arg, if none given and we're not merging.
+ if (!args.Has("-max_len=") && !args.Has("-merge=1")) {
+ uint16_t maxLen = Registry::MaxLen(targetName);
+ args.Append("-max_len=" + to_string(maxLen));
+ }
+
+ // Hand control to the libFuzzer driver.
+ vector<char *> args_new(args.argv());
+ argc = args_new.size();
+ argv = args_new.data();
+
+ return fuzzer::FuzzerDriver(&argc, &argv, Registry::Func(targetName));
+}
diff --git a/security/nss/fuzz/pkcs8_target.cc b/security/nss/fuzz/pkcs8_target.cc
new file mode 100644
index 0000000000..8b6ed7b57b
--- /dev/null
+++ b/security/nss/fuzz/pkcs8_target.cc
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <assert.h>
+#include <stdint.h>
+#include <memory>
+
+#include "keyhi.h"
+#include "pk11pub.h"
+
+#include "registry.h"
+#include "shared.h"
+
+extern "C" int pkcs8_fuzzing_target(const uint8_t *Data, size_t Size) {
+ SECItem data = {siBuffer, (unsigned char *)Data, (unsigned int)Size};
+
+ static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
+ assert(db != nullptr);
+
+ PK11SlotInfo *slot = PK11_GetInternalSlot();
+ assert(slot != nullptr);
+
+ SECKEYPrivateKey *key = nullptr;
+ if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, &data, nullptr, nullptr,
+ false, false, KU_ALL, &key,
+ nullptr) == SECSuccess) {
+ SECKEY_DestroyPrivateKey(key);
+ }
+
+ PK11_FreeSlot(slot);
+ return 0;
+}
+
+REGISTER_FUZZING_TARGET("pkcs8", pkcs8_fuzzing_target, 2048, "PKCS#8 Import")
diff --git a/security/nss/fuzz/quickder_targets.cc b/security/nss/fuzz/quickder_targets.cc
new file mode 100644
index 0000000000..2517721961
--- /dev/null
+++ b/security/nss/fuzz/quickder_targets.cc
@@ -0,0 +1,36 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdint.h>
+
+#include "cert.h"
+
+#include "registry.h"
+
+void QuickDERDecode(void *dst, const SEC_ASN1Template *tpl, const uint8_t *buf,
+ size_t len) {
+ PORTCheapArenaPool pool;
+ SECItem data = {siBuffer, const_cast<unsigned char *>(buf),
+ static_cast<unsigned int>(len)};
+
+ PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
+ (void)SEC_QuickDERDecodeItem(&pool.arena, dst, tpl, &data);
+ PORT_DestroyCheapArena(&pool);
+}
+
+extern "C" int cert_fuzzing_target(const uint8_t *Data, size_t Size) {
+ CERTCertificate cert;
+ QuickDERDecode(&cert, SEC_SignedCertificateTemplate, Data, Size);
+ return 0;
+}
+
+REGISTER_FUZZING_TARGET("cert", cert_fuzzing_target, 3072, "Certificate Import")
+
+extern "C" int spki_fuzzing_target(const uint8_t *Data, size_t Size) {
+ CERTSubjectPublicKeyInfo spki;
+ QuickDERDecode(&spki, CERT_SubjectPublicKeyInfoTemplate, Data, Size);
+ return 0;
+}
+
+REGISTER_FUZZING_TARGET("spki", spki_fuzzing_target, 1024, "SPKI Import")
diff --git a/security/nss/fuzz/registry.h b/security/nss/fuzz/registry.h
new file mode 100644
index 0000000000..760118dec9
--- /dev/null
+++ b/security/nss/fuzz/registry.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef registry_h__
+#define registry_h__
+
+#include <map>
+#include "FuzzerInternal.h"
+#include "nss.h"
+
+class Registry {
+ public:
+ static void Add(std::string name, fuzzer::UserCallback func, uint16_t max_len,
+ std::string desc) {
+ assert(!Has(name));
+ GetInstance().targets_[name] = TargetData(func, max_len, desc);
+ }
+
+ static bool Has(std::string name) {
+ return GetInstance().targets_.count(name) > 0;
+ }
+
+ static fuzzer::UserCallback Func(std::string name) {
+ assert(Has(name));
+ return std::get<0>(Get(name));
+ }
+
+ static uint16_t MaxLen(std::string name) {
+ assert(Has(name));
+ return std::get<1>(Get(name));
+ }
+
+ static std::string& Desc(std::string name) {
+ assert(Has(name));
+ return std::get<2>(Get(name));
+ }
+
+ static std::vector<std::string> Names() {
+ std::vector<std::string> names;
+ for (auto& it : GetInstance().targets_) {
+ names.push_back(it.first);
+ }
+ return names;
+ }
+
+ private:
+ typedef std::tuple<fuzzer::UserCallback, uint16_t, std::string> TargetData;
+
+ static Registry& GetInstance() {
+ static Registry registry;
+ return registry;
+ }
+
+ static TargetData& Get(std::string name) {
+ return GetInstance().targets_[name];
+ }
+
+ Registry() {}
+
+ std::map<std::string, TargetData> targets_;
+};
+
+#define REGISTER_FUZZING_TARGET(name, func, max_len, desc) \
+ static void __attribute__((constructor)) Register_##func() { \
+ Registry::Add(name, func, max_len, desc); \
+ }
+
+#endif // registry_h__
diff --git a/security/nss/fuzz/shared.h b/security/nss/fuzz/shared.h
new file mode 100644
index 0000000000..09d805ed85
--- /dev/null
+++ b/security/nss/fuzz/shared.h
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef shared_h__
+#define shared_h__
+
+#include "nss.h"
+
+class NSSDatabase {
+ public:
+ NSSDatabase() { NSS_NoDB_Init(nullptr); }
+ ~NSSDatabase() { NSS_Shutdown(); }
+};
+
+#endif // shared_h__
diff --git a/security/nss/fuzz/warning.txt b/security/nss/fuzz/warning.txt
new file mode 100644
index 0000000000..2c83d7ed2a
--- /dev/null
+++ b/security/nss/fuzz/warning.txt
@@ -0,0 +1,15 @@
+
+##############################################
+## ##
+## WARNING: You're building with -Dfuzz=1 ##
+## ##
+## This means: ##
+## ##
+## * Your PRNG is DETERMINISTIC. ##
+## * TLS transcripts are PLAINTEXT. ##
+## * TLS signature checks are DISABLED. ##
+## ##
+## Thank you for fuzzing! ##
+## ##
+##############################################
+