diff --git a/.gitignore b/.gitignore
index f9a8c7d1259ed8e8ffd229f757247e9998a1aaf1..c72e57c3cae288faff7c7a7698576e66c88f455c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,10 +5,7 @@
*.a
honggfuzz
Makefile.bak
-hfuzz_cc/hfuzz-clang
-hfuzz_cc/hfuzz-clang++
-hfuzz_cc/hfuzz-gcc
-hfuzz_cc/hfuzz-g++
+hfuzz_cc/hfuzz-cc
mac/mach_exc.h
mac/mach_excUser.c
mac/mach_excServer.h
diff --git a/Android.bp b/Android.bp
index 11576d591f0b11571e4bf0d943d5ecf14d7cb561..5fcd6bfd41dacdfa0001eda756019bd3146a6161 100644
--- a/Android.bp
+++ b/Android.bp
@@ -21,7 +21,7 @@ cc_defaults {
cc_library_headers {
name: "honggfuzz_libcommon_headers",
- export_include_dirs: ["libcommon"],
+ export_include_dirs: ["libhfcommon"],
}
cc_library {
@@ -32,10 +32,7 @@ cc_library {
header_libs: ["honggfuzz_libcommon_headers"],
export_header_lib_headers: ["honggfuzz_libcommon_headers"],
srcs: [
- "libcommon/files.c",
- "libcommon/log.c",
- "libcommon/ns.c",
- "libcommon/util.c",
+ "libhfcommon/*.c",
],
@@ -71,10 +68,7 @@ cc_library {
],
srcs: [
- "libhfuzz/instrument.c",
- "libhfuzz/linux.c",
- "libhfuzz/memorycmp.c",
- "libhfuzz/persistent.c",
+ "libhfuzz/*.c",
],
}
@@ -103,21 +97,11 @@ cc_binary {
],
srcs: [
- "cmdline.c",
- "display.c",
- "fuzz.c",
- "honggfuzz.c",
- "input.c",
- "mangle.c",
- "report.c",
- "sancov.c",
- "sanitizers.c",
- "subproc.c",
- "linux/arch.c",
- "linux/trace.c",
- "linux/perf.c",
- "linux/unwind.c",
- "linux/pt.c",
+ "*.c",
+ "linux/*.c",
+ ],
+ exclude_srcs: [
+ "linux/bfd.c",
],
}
diff --git a/CHANGELOG b/CHANGELOG
index 729c774bd4209c169992fc3b6616f7e5a70bdb87..8d6e6f7fbe0463e70708e78caedd212e66577ca9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,44 @@
-2017-12-09 - Version 1.3
+2019-02-23 - Version 1.8
+ - Native support for NetBSD
+ - Multiple smaller changes wrt threading - e.g. introducing the signal thread
+ - Removed the support for -p (pid fuzzing), honggfuzz net driver, or persistent fuzzing mode should be used instead
+ - Reimplementation of memory comparison routines, now verified with glibc's test-suite
+ - Improved hfuzz-cc/clang/gcc - e.g. for the MacOSX platform, also using -fno-sanitize=fuzzer if -fsanitize=fuzzer is specified, + some samba code wrappers
+ - Examples: new corpora for some of those, new patch for ISC Bind (9.13.5)
+
+2018-08-23 - Version 1.7
+ - Native support for NetBSD
+ - ASCII only fuzzing
+ - Updated corpora for ISC Bind
+ - Printing final stats upon exit
+ - Refreshed support for Intel PT
+ - Support for __sanitizer_cov_trace_div
+ - Updated fuzzing examples for OpenSSL
+
+2018-04-19 - Version 1.6 (rev aeaad48)
+ - Fixed Dockerfile
+ - Fixed a few format problems with file reporting
+ - Updated display formatting
+ - Make it work under WSL (Windows Subsystem for Linux)
+
+2018-02-22 - Version 1.5 (rev 3b1b70b)
+ - Persistent fuzzing now works with MacOS-X
+ - Fixed some examples/ to make it work with MacOS-X
+ - Should compile cleanly with newer MacOS-X versions
+
+2018-02-07 - Version 1.4 (rev 28c7d9e)
+ - Socketfuzzer by @dobin
+ - TCP fuzzer (HonggFuzzer NetDriver) in libhfnetdriver
+ - Display: changed layout a bit
+ - Fix some compilation isuses for MacOS-X
+ - Make it compile with OpenBSD
+ - Better examples/ dir: Apache HTTP, ISC Bind
+ - Added persistent and netdriver signatures
+ - Added missing symbols for newer -fsanitize-coverage (const)
+ - Changed internal structures (global vs run)
+ - Android: Make it compile with newer SDKs
+
+2017-12-09 - Version 1.3 (rev dd9f149)
- Software instrumentation - support for cmp_const __sanitizer_cov_trace_const funcs
- Refreshed (mostly) OpenSSL corpora
- Mangling: additional function for ASCII numbers
diff --git a/Dockerfile b/Dockerfile
index 55705bb9b12efb7845ca1491424639f1e7ff386b..4053f36b9378415785edc16bb7147b0a64764d84 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:17.04
+FROM ubuntu:rolling
RUN apt-get -y update && apt-get install -y \
gcc \
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index d645695673349e3947e8e5ae42332d0ac3164cd7..0000000000000000000000000000000000000000
--- a/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000000000000000000000000000000000000..d24842f3cdcf2e447f9a7a26fa387ad63f5c4b91
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+COPYING
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 1d567642ad4305509726e82c60ff370999454aab..fc5ea74ee85e8e256da6300b473706c47dc8cdfc 100644
--- a/Makefile
+++ b/Makefile
@@ -24,23 +24,21 @@
CC ?= gcc
LD = $(CC)
BIN := honggfuzz
-HFUZZ_CC_BINS := hfuzz_cc/hfuzz-clang hfuzz_cc/hfuzz-clang++ hfuzz_cc/hfuzz-gcc hfuzz_cc/hfuzz-g++
+HFUZZ_CC_BIN := hfuzz_cc/hfuzz-cc
HFUZZ_CC_SRCS := hfuzz_cc/hfuzz-cc.c
-COMMON_CFLAGS := -D_GNU_SOURCE -Wall -Werror -Wframe-larger-than=131072 -Wno-format-truncation -I.
-COMMON_LDFLAGS := -lm libcommon/libcommon.a
+COMMON_CFLAGS := -D_GNU_SOURCE -Wall -Werror -Wno-format-truncation -I.
+COMMON_LDFLAGS := -lm libhfcommon/libhfcommon.a
COMMON_SRCS := $(sort $(wildcard *.c))
-CFLAGS ?= -O3
+CFLAGS ?= -O3 -mtune=native
LDFLAGS ?=
-LIBS_CFLAGS ?= -fPIC -fno-stack-protector -fno-builtin -D__NO_STRING_INLINES -D__NO_INLINE__
-HFUZZ_USE_RET_ADDR ?= false
-ifneq ($(HFUZZ_USE_RET_ADDR),false)
- LIBS_CFLAGS += -D_HF_USE_RET_ADDR=$(HFUZZ_USE_RET_ADDR) -Wno-error=frame-address
-endif
+LIBS_CFLAGS ?= -fPIC -fno-stack-protector
+GREP_COLOR ?=
OS ?= $(shell uname -s)
MARCH ?= $(shell uname -m)
+KERNEL ?= $(shell uname -r)
-ifeq ($(OS),Linux)
+ifeq ($(OS)$(findstring Microsoft,$(KERNEL)),Linux) # matches Linux but excludes WSL (Windows Subsystem for Linux)
ARCH := LINUX
ARCH_CFLAGS := -std=c11 -I/usr/local/include \
@@ -48,7 +46,7 @@ ifeq ($(OS),Linux)
-funroll-loops \
-D_FILE_OFFSET_BITS=64
ARCH_LDFLAGS := -L/usr/local/include \
- -lpthread -lunwind-ptrace -lunwind-generic -lbfd -lopcodes -lrt -ldl
+ -pthread -lunwind-ptrace -lunwind-generic -lbfd -lopcodes -lrt -ldl
ARCH_SRCS := $(sort $(wildcard linux/*.c))
LIBS_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
@@ -68,22 +66,28 @@ ifeq ($(OS),Linux)
ARCH_LDFLAGS += -lipt
endif
ifdef WARN_LIBRARY
- $(info ***************************************************************)
- $(info Development libraries which are most likely missing on your OS:)
- $(info $(WARN_LIBRARY))
- $(info ***************************************************************)
+ $(info --------------------------------------------------------)
+ $(info Libraries which are most likely missing on your OS. )
+ $(info This can result in linking/compilation errors. )
+ $(info > $(WARN_LIBRARY))
+ $(info --------------------------------------------------------)
endif
# OS Linux
else ifeq ($(OS),Darwin)
ARCH := DARWIN
+ # MacOS-X grep seem to use colors unconditionally
+ GREP_COLOR = --color=never
+
# Figure out which crash reporter to use.
CRASHWRANGLER := third_party/mac
OS_VERSION := $(shell sw_vers -productVersion)
- ifneq (,$(findstring 10.13,$(OS_VERSION)))
+ ifneq (,$(findstring 10.14,$(OS_VERSION)))
+ CRASH_REPORT := $(CRASHWRANGLER)/CrashReport_Sierra.o
+ else ifneq (,$(findstring 10.13,$(OS_VERSION)))
CRASH_REPORT := $(CRASHWRANGLER)/CrashReport_Sierra.o
else ifneq (,$(findstring 10.12,$(OS_VERSION)))
- CRASH_REPORT := $(CRASHWRANGLER)/CrashReport_Yosemite.o
+ CRASH_REPORT := $(CRASHWRANGLER)/CrashReport_Sierra.o
else ifneq (,$(findstring 10.11,$(OS_VERSION)))
# El Capitan didn't break compatibility
CRASH_REPORT := $(CRASHWRANGLER)/CrashReport_Yosemite.o
@@ -99,12 +103,10 @@ else ifeq ($(OS),Darwin)
# Figure out which XCode SDK to use.
OSX_SDK_VERSION := $(shell xcrun --show-sdk-version)
- SDK_NAME :=macosx$(OSX_SDK_VERSION)
+ SDK_NAME_V := macosx$(OSX_SDK_VERSION)
+ SDK_V := $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path 2>/dev/null)
+ SDK_NAME := macosx
SDK := $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path 2>/dev/null)
- ifeq (,$(findstring MacOSX.platform,$(SDK)))
- XC_PATH := $(shell xcode-select -p)
- $(error $(SDK_NAME) not found in $(XC_PATH))
- endif
CC := $(shell xcrun --sdk $(SDK_NAME) --find cc)
LD := $(shell xcrun --sdk $(SDK_NAME) --find cc)
@@ -112,14 +114,16 @@ else ifeq ($(OS),Darwin)
-x objective-c -pedantic -fblocks \
-Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized \
-Wreturn-type -Wpointer-arith -Wno-gnu-case-range -Wno-gnu-designator \
- -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-attributes
+ -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-attributes \
+ -Wno-embedded-directive
ARCH_LDFLAGS := -F/System/Library/PrivateFrameworks -framework CoreSymbolication -framework IOKit \
- -F$(SDK)/System/Library/Frameworks -F$(SDK)/System/Library/PrivateFrameworks \
+ -F$(SDK_V)/System/Library/Frameworks -F$(SDK_V)/System/Library/PrivateFrameworks \
+ -F$(SDK)/System/Library/Frameworks \
-framework Foundation -framework ApplicationServices -framework Symbolication \
-framework CoreServices -framework CrashReporterSupport -framework CoreFoundation \
-framework CommerceKit $(CRASH_REPORT)
- XCODE_VER := $(shell xcodebuild -version | grep "^Xcode" | cut -d " " -f2)
+ XCODE_VER := $(shell xcodebuild -version | grep $(GREP_COLOR) "^Xcode" | cut -d " " -f2)
ifeq "8.3" "$(word 1, $(sort 8.3 $(XCODE_VER)))"
ARCH_LDFLAGS += -F/Applications/Xcode.app/Contents/SharedFrameworks \
-framework CoreSymbolicationDT \
@@ -133,24 +137,39 @@ else ifeq ($(OS),Darwin)
endif
ARCH_SRCS := $(sort $(wildcard mac/*.c))
# OS Darwin
+else ifeq ($(OS),NetBSD)
+ ARCH := NETBSD
+
+ ARCH_SRCS := $(sort $(wildcard netbsd/*.c))
+ ARCH_CFLAGS := -std=c11 -I/usr/local/include -I/usr/pkg/include \
+ -Wextra -Wno-override-init \
+ -funroll-loops -D_KERNTYPES
+ ARCH_LDFLAGS := -L/usr/local/lib -L/usr/pkg/lib \
+ -pthread -lcapstone -lrt \
+ -Wl,--rpath=/usr/pkg/lib
+
+ # OS NetBSD
else
ARCH := POSIX
+
ARCH_SRCS := $(sort $(wildcard posix/*.c))
ARCH_CFLAGS := -std=c11 -I/usr/local/include \
-Wextra -Wno-initializer-overrides -Wno-override-init \
-Wno-unknown-warning-option -Wno-unknown-pragmas \
-funroll-loops
- ARCH_LDFLAGS := -lpthread -L/usr/local/include -lrt
+ ARCH_LDFLAGS := -pthread -L/usr/local/lib
# OS Posix
endif
+CFLAGS_BLOCKS =
COMPILER = $(shell $(CC) -v 2>&1 | \
- grep -oE '((gcc|clang) version|LLVM version.*clang)' | \
- grep -oE '(clang|gcc)' | head -n1)
+ grep $(GREP_COLOR) -oE '((gcc|clang) version|LLVM version.*clang)' | \
+ grep $(GREP_COLOR) -oE '(clang|gcc)' | head -n1)
ifeq ($(COMPILER),clang)
ARCH_CFLAGS += -Wno-initializer-overrides -Wno-unknown-warning-option
- ARCH_CFLAGS += -fblocks
- CFLAGS_NOBLOCKS = -fno-blocks
+ ARCH_CFLAGS += -Wno-gnu-empty-initializer -Wno-format-pedantic
+ ARCH_CFLAGS += -Wno-gnu-statement-expression
+ CFLAGS_BLOCKS = -fblocks
ifneq ($(OS),Darwin)
ARCH_LDFLAGS += -lBlocksRuntime
@@ -160,14 +179,18 @@ endif
SRCS := $(COMMON_SRCS) $(ARCH_SRCS)
OBJS := $(SRCS:.c=.o)
-LHFUZZ_SRCS := $(wildcard libhfuzz/*.c)
+LHFUZZ_SRCS := $(sort $(wildcard libhfuzz/*.c))
LHFUZZ_OBJS := $(LHFUZZ_SRCS:.c=.o)
LHFUZZ_ARCH := libhfuzz/libhfuzz.a
HFUZZ_INC ?= $(shell pwd)
-LCOMMON_SRCS := $(wildcard libcommon/*.c)
+LCOMMON_SRCS := $(sort $(wildcard libhfcommon/*.c))
LCOMMON_OBJS := $(LCOMMON_SRCS:.c=.o)
-LCOMMON_ARCH := libcommon/libcommon.a
+LCOMMON_ARCH := libhfcommon/libhfcommon.a
+
+LNETDRIVER_SRCS := $(sort $(wildcard libhfnetdriver/*.c))
+LNETDRIVER_OBJS := $(LNETDRIVER_SRCS:.c=.o)
+LNETDRIVER_ARCH := libhfnetdriver/libhfnetdriver.a
# Respect external user defines
CFLAGS += $(COMMON_CFLAGS) $(ARCH_CFLAGS) -D_HF_ARCH_${ARCH}
@@ -235,7 +258,7 @@ else
endif
endif
-SUBDIR_ROOTS := linux mac posix libhfuzz libcommon
+SUBDIR_ROOTS := linux mac netbsd posix libhfuzz libhfcommon libhfnetdriver
DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
CLEAN_PATTERNS := *.o *~ core *.a *.dSYM *.la *.so *.dylib
SUBDIR_GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(CLEAN_PATTERNS)))
@@ -243,14 +266,16 @@ MAC_GARGBAGE := $(wildcard mac/mach_exc*)
ANDROID_GARBAGE := obj libs
CLEAN_TARGETS := core Makefile.bak \
- $(OBJS) $(BIN) $(HFUZZ_CC_BINS) \
- $(LHFUZZ_ARCH) $(LHFUZZ_OBJS) $(LCOMMON_ARCH) $(LCOMMON_OBJS) \
+ $(OBJS) $(BIN) $(HFUZZ_CC_BIN) \
+ $(LHFUZZ_ARCH) $(LHFUZZ_OBJS) \
+ $(LCOMMON_ARCH) $(LCOMMON_OBJS) \
+ $(LNETDRIVER_ARCH) $(LNETDRIVER_OBJS) \
$(MAC_GARGBAGE) $(ANDROID_GARBAGE) $(SUBDIR_GARBAGE)
-all: $(BIN) $(HFUZZ_CC_BINS) $(LHFUZZ_ARCH) $(LCOMMON_ARCH)
+all: $(BIN) $(HFUZZ_CC_BIN) $(LHFUZZ_ARCH) $(LCOMMON_ARCH) $(LNETDRIVER_ARCH)
%.o: %.c
- $(CC) -c $(CFLAGS) -o $@ $<
+ $(CC) -c $(CFLAGS) $(CFLAGS_BLOCKS) -o $@ $<
%.so: %.c
$(CC) -fPIC -shared $(CFLAGS) -o $@ $<
@@ -261,20 +286,26 @@ all: $(BIN) $(HFUZZ_CC_BINS) $(LHFUZZ_ARCH) $(LCOMMON_ARCH)
$(BIN): $(OBJS) $(LCOMMON_ARCH)
$(LD) -o $(BIN) $(OBJS) $(LDFLAGS)
-$(HFUZZ_CC_BINS): $(LHFUZZ_ARCH) $(LCOMMON_ARCH) $(HFUZZ_CC_SRCS)
- $(LD) -o $@ $(HFUZZ_CC_SRCS) $(LDFLAGS) $(CFLAGS) -D_HFUZZ_INC_PATH=$(HFUZZ_INC)
+$(HFUZZ_CC_BIN): $(LCOMMON_ARCH) $(LHFUZZ_ARCH) $(LNETDRIVER_ARCH) $(HFUZZ_CC_SRCS)
+ $(LD) -o $@ $(HFUZZ_CC_SRCS) $(LDFLAGS) $(CFLAGS) $(CFLAGS_BLOCKS) -D_HFUZZ_INC_PATH=$(HFUZZ_INC)
+
+$(LCOMMON_OBJS): $(LCOMMON_SRCS)
+ $(CC) -c $(CFLAGS) $(LIBS_CFLAGS) -o $@ $(@:.o=.c)
+
+$(LCOMMON_ARCH): $(LCOMMON_OBJS)
+ $(AR) rcs $(LCOMMON_ARCH) $(LCOMMON_OBJS)
$(LHFUZZ_OBJS): $(LHFUZZ_SRCS)
- $(CC) -c $(CFLAGS) $(LIBS_CFLAGS) $(CFLAGS_NOBLOCKS) -o $@ $(@:.o=.c)
+ $(CC) -c $(CFLAGS) $(LIBS_CFLAGS) -o $@ $(@:.o=.c)
-$(LHFUZZ_ARCH): $(LHFUZZ_OBJS) $(LCOMMON_ARCH)
+$(LHFUZZ_ARCH): $(LHFUZZ_OBJS) $(LCOMMON_OBJS)
$(AR) rcs $(LHFUZZ_ARCH) $(LHFUZZ_OBJS) $(LCOMMON_OBJS)
-$(LCOMMON_OBJS): $(LCOMMON_SRCS)
- $(CC) -c $(CFLAGS) $(LIBS_CFLAGS) $(CFLAGS_NOBLOCKS) -o $@ $(@:.o=.c)
+$(LNETDRIVER_OBJS): $(LNETDRIVER_SRCS)
+ $(CC) -c $(CFLAGS) $(LIBS_CFLAGS) -o $@ $(@:.o=.c)
-$(LCOMMON_ARCH): $(LCOMMON_OBJS)
- $(AR) rcs $(LCOMMON_ARCH) $(LCOMMON_OBJS)
+$(LNETDRIVER_ARCH): $(LNETDRIVER_OBJS) $(LCOMMON_OBJS)
+ $(AR) rcs $(LNETDRIVER_ARCH) $(LNETDRIVER_OBJS) $(LCOMMON_OBJS)
.PHONY: clean
clean:
@@ -282,10 +313,10 @@ clean:
.PHONY: indent
indent:
- clang-format -style="{BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 100, AlignAfterOpenBracket: false}" -i -sort-includes *.c *.h */*.c */*.h
+ clang-format -style="{BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 100, AlignAfterOpenBracket: DontAlign, AllowShortFunctionsOnASingleLine: false, AlwaysBreakBeforeMultilineStrings: false}" -i -sort-includes *.c *.h */*.c */*.h
.PHONY: depend
-depend:
+depend: all
makedepend -Y. -Y* -- *.c */*.c
.PHONY: android
@@ -336,67 +367,106 @@ android-clean-deps:
rm -rf "third_party/android/libBlocksRuntime/$$cpu"; \
done
+PREFIX ?= /usr/local
+BIN_PATH =$(PREFIX)/bin
+
+install: all
+ mkdir -p -m 755 $${DESTDIR}$(BIN_PATH)
+ install -m 755 honggfuzz $${DESTDIR}$(BIN_PATH)
+ install -m 755 hfuzz_cc/hfuzz-cc $${DESTDIR}$(BIN_PATH)
+ install -m 755 hfuzz_cc/hfuzz-clang $${DESTDIR}$(BIN_PATH)
+ install -m 755 hfuzz_cc/hfuzz-clang++ $${DESTDIR}$(BIN_PATH)
+ install -m 755 hfuzz_cc/hfuzz-gcc $${DESTDIR}$(BIN_PATH)
+ install -m 755 hfuzz_cc/hfuzz-g++ $${DESTDIR}$(BIN_PATH)
+
# DO NOT DELETE
-cmdline.o: cmdline.h honggfuzz.h libcommon/util.h libcommon/common.h
-cmdline.o: libcommon/files.h libcommon/common.h libcommon/log.h
-display.o: display.h honggfuzz.h libcommon/util.h libcommon/common.h
-display.o: libcommon/log.h libcommon/common.h
-fuzz.o: fuzz.h honggfuzz.h libcommon/util.h arch.h input.h libcommon/common.h
-fuzz.o: libcommon/files.h libcommon/common.h libcommon/log.h mangle.h
-fuzz.o: report.h sancov.h sanitizers.h subproc.h
-honggfuzz.o: cmdline.h honggfuzz.h libcommon/util.h libcommon/common.h
-honggfuzz.o: display.h fuzz.h input.h libcommon/files.h libcommon/common.h
-honggfuzz.o: libcommon/log.h
-input.o: input.h honggfuzz.h libcommon/util.h libcommon/common.h
-input.o: libcommon/files.h libcommon/common.h libcommon/log.h
-mangle.o: mangle.h honggfuzz.h libcommon/util.h libcommon/common.h
-mangle.o: libcommon/log.h libcommon/common.h
-report.o: report.h honggfuzz.h libcommon/util.h libcommon/common.h
-report.o: libcommon/log.h libcommon/common.h
-sancov.o: sancov.h honggfuzz.h libcommon/util.h libcommon/common.h
-sancov.o: libcommon/files.h libcommon/common.h libcommon/log.h sanitizers.h
-sanitizers.o: sanitizers.h honggfuzz.h libcommon/util.h libcommon/common.h
-sanitizers.o: libcommon/files.h libcommon/common.h libcommon/log.h
-subproc.o: subproc.h honggfuzz.h libcommon/util.h arch.h fuzz.h
-subproc.o: libcommon/common.h libcommon/files.h libcommon/common.h
-subproc.o: libcommon/log.h sanitizers.h
-hfuzz_cc/hfuzz-cc.o: honggfuzz.h libcommon/util.h libcommon/common.h
-hfuzz_cc/hfuzz-cc.o: libcommon/files.h libcommon/common.h libcommon/log.h
-libcommon/files.o: libcommon/files.h libcommon/common.h libcommon/log.h
-libcommon/files.o: libcommon/util.h
-libcommon/log.o: libcommon/log.h libcommon/common.h libcommon/util.h
-libcommon/ns.o: libcommon/ns.h libcommon/common.h libcommon/files.h
-libcommon/ns.o: libcommon/log.h
-libcommon/util.o: libcommon/util.h libcommon/common.h libcommon/files.h
-libcommon/util.o: libcommon/log.h
-libhfuzz/instrument.o: libhfuzz/instrument.h honggfuzz.h libcommon/util.h
-libhfuzz/instrument.o: libcommon/common.h libcommon/log.h libcommon/common.h
-libhfuzz/linux.o: libcommon/common.h libhfuzz/libhfuzz.h libcommon/files.h
-libhfuzz/linux.o: libcommon/common.h libcommon/log.h libcommon/ns.h
-libhfuzz/memorycmp.o: libhfuzz/instrument.h
-libhfuzz/persistent.o: libhfuzz/libhfuzz.h honggfuzz.h libcommon/util.h
-libhfuzz/persistent.o: libcommon/common.h libcommon/files.h
-libhfuzz/persistent.o: libcommon/common.h libcommon/log.h
-linux/arch.o: arch.h honggfuzz.h libcommon/util.h fuzz.h libcommon/common.h
-linux/arch.o: libcommon/files.h libcommon/common.h libcommon/log.h
-linux/arch.o: libcommon/ns.h linux/perf.h linux/trace.h sancov.h sanitizers.h
-linux/arch.o: subproc.h
-linux/bfd.o: linux/bfd.h linux/unwind.h honggfuzz.h libcommon/util.h
-linux/bfd.o: libcommon/common.h libcommon/files.h libcommon/common.h
-linux/bfd.o: libcommon/log.h
-linux/perf.o: linux/perf.h honggfuzz.h libcommon/util.h libcommon/common.h
-linux/perf.o: libcommon/files.h libcommon/common.h libcommon/log.h linux/pt.h
-linux/pt.o: libcommon/common.h libcommon/log.h libcommon/common.h
-linux/pt.o: libcommon/util.h linux/pt.h honggfuzz.h
-linux/trace.o: linux/trace.h honggfuzz.h libcommon/util.h libcommon/common.h
-linux/trace.o: libcommon/files.h libcommon/common.h libcommon/log.h
-linux/trace.o: linux/bfd.h linux/unwind.h sancov.h sanitizers.h subproc.h
-linux/unwind.o: linux/unwind.h honggfuzz.h libcommon/util.h
-linux/unwind.o: libcommon/common.h libcommon/log.h libcommon/common.h
-mac/arch.o: arch.h honggfuzz.h libcommon/util.h libcommon/common.h
-mac/arch.o: libcommon/files.h libcommon/common.h libcommon/log.h sancov.h
+cmdline.o: cmdline.h honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+cmdline.o: display.h libhfcommon/files.h libhfcommon/common.h
+cmdline.o: libhfcommon/log.h
+display.o: display.h honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+display.o: libhfcommon/log.h
+fuzz.o: fuzz.h honggfuzz.h libhfcommon/util.h arch.h input.h
+fuzz.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+fuzz.o: libhfcommon/log.h mangle.h report.h sanitizers.h socketfuzzer.h
+fuzz.o: subproc.h
+honggfuzz.o: cmdline.h honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+honggfuzz.o: display.h fuzz.h input.h libhfcommon/files.h
+honggfuzz.o: libhfcommon/common.h libhfcommon/log.h socketfuzzer.h subproc.h
+input.o: input.h honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+input.o: libhfcommon/files.h libhfcommon/common.h mangle.h subproc.h
+input.o: libhfcommon/log.h
+mangle.o: mangle.h honggfuzz.h libhfcommon/util.h input.h
+mangle.o: libhfcommon/common.h libhfcommon/log.h
+report.o: report.h honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+report.o: libhfcommon/log.h
+sanitizers.o: sanitizers.h honggfuzz.h libhfcommon/util.h cmdline.h
+sanitizers.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+sanitizers.o: libhfcommon/log.h
+socketfuzzer.o: honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+socketfuzzer.o: libhfcommon/files.h libhfcommon/common.h libhfcommon/log.h
+socketfuzzer.o: libhfcommon/ns.h socketfuzzer.h
+subproc.o: subproc.h honggfuzz.h libhfcommon/util.h arch.h fuzz.h
+subproc.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+subproc.o: libhfcommon/log.h
+hfuzz_cc/hfuzz-cc.o: honggfuzz.h libhfcommon/util.h libhfcommon/common.h
+hfuzz_cc/hfuzz-cc.o: libhfcommon/files.h libhfcommon/common.h
+hfuzz_cc/hfuzz-cc.o: libhfcommon/log.h
+libhfcommon/files.o: libhfcommon/files.h libhfcommon/common.h
+libhfcommon/files.o: libhfcommon/common.h libhfcommon/log.h
+libhfcommon/files.o: libhfcommon/util.h
+libhfcommon/log.o: libhfcommon/log.h libhfcommon/common.h libhfcommon/util.h
+libhfcommon/ns.o: libhfcommon/ns.h libhfcommon/common.h libhfcommon/files.h
+libhfcommon/ns.o: libhfcommon/common.h libhfcommon/log.h
+libhfcommon/util.o: libhfcommon/util.h libhfcommon/common.h
+libhfcommon/util.o: libhfcommon/files.h libhfcommon/common.h
+libhfcommon/util.o: libhfcommon/log.h
+libhfnetdriver/netdriver.o: libhfnetdriver/netdriver.h honggfuzz.h
+libhfnetdriver/netdriver.o: libhfcommon/util.h libhfcommon/common.h
+libhfnetdriver/netdriver.o: libhfcommon/files.h libhfcommon/common.h
+libhfnetdriver/netdriver.o: libhfcommon/log.h libhfcommon/ns.h
+libhfuzz/fetch.o: libhfuzz/fetch.h honggfuzz.h libhfcommon/util.h
+libhfuzz/fetch.o: libhfcommon/common.h libhfcommon/files.h
+libhfuzz/fetch.o: libhfcommon/common.h libhfcommon/log.h
+libhfuzz/instrument.o: libhfuzz/instrument.h honggfuzz.h libhfcommon/util.h
+libhfuzz/instrument.o: libhfcommon/common.h libhfcommon/log.h
+libhfuzz/linux.o: libhfcommon/common.h libhfcommon/files.h
+libhfuzz/linux.o: libhfcommon/common.h libhfcommon/log.h libhfcommon/ns.h
+libhfuzz/linux.o: libhfuzz/libhfuzz.h
+libhfuzz/memorycmp.o: libhfcommon/common.h libhfuzz/instrument.h
+libhfuzz/persistent.o: libhfuzz/libhfuzz.h honggfuzz.h libhfcommon/util.h
+libhfuzz/persistent.o: libhfcommon/common.h libhfcommon/files.h
+libhfuzz/persistent.o: libhfcommon/common.h libhfcommon/log.h
+libhfuzz/persistent.o: libhfuzz/fetch.h libhfuzz/instrument.h
+linux/arch.o: arch.h honggfuzz.h libhfcommon/util.h fuzz.h
+linux/arch.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+linux/arch.o: libhfcommon/log.h libhfcommon/ns.h linux/perf.h linux/trace.h
+linux/arch.o: sanitizers.h subproc.h
+linux/bfd.o: linux/bfd.h linux/unwind.h honggfuzz.h libhfcommon/util.h
+linux/bfd.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+linux/bfd.o: libhfcommon/log.h
+linux/perf.o: linux/perf.h honggfuzz.h libhfcommon/util.h
+linux/perf.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+linux/perf.o: libhfcommon/log.h linux/pt.h
+linux/pt.o: libhfcommon/common.h libhfcommon/log.h libhfcommon/util.h
+linux/pt.o: linux/pt.h honggfuzz.h
+linux/trace.o: linux/trace.h honggfuzz.h libhfcommon/util.h
+linux/trace.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+linux/trace.o: libhfcommon/log.h linux/bfd.h linux/unwind.h sanitizers.h
+linux/trace.o: socketfuzzer.h subproc.h
+linux/unwind.o: linux/unwind.h honggfuzz.h libhfcommon/util.h
+linux/unwind.o: libhfcommon/common.h libhfcommon/log.h
+mac/arch.o: arch.h honggfuzz.h libhfcommon/util.h fuzz.h libhfcommon/common.h
+mac/arch.o: libhfcommon/files.h libhfcommon/common.h libhfcommon/log.h
mac/arch.o: subproc.h
-posix/arch.o: arch.h honggfuzz.h libcommon/util.h fuzz.h libcommon/common.h
-posix/arch.o: libcommon/files.h libcommon/common.h libcommon/log.h sancov.h
-posix/arch.o: subproc.h
+netbsd/arch.o: arch.h honggfuzz.h libhfcommon/util.h fuzz.h
+netbsd/arch.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+netbsd/arch.o: libhfcommon/log.h libhfcommon/ns.h netbsd/trace.h subproc.h
+netbsd/trace.o: netbsd/trace.h honggfuzz.h libhfcommon/util.h
+netbsd/trace.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+netbsd/trace.o: libhfcommon/log.h netbsd/unwind.h socketfuzzer.h subproc.h
+netbsd/unwind.o: netbsd/unwind.h honggfuzz.h libhfcommon/util.h
+netbsd/unwind.o: libhfcommon/common.h libhfcommon/log.h
+posix/arch.o: arch.h honggfuzz.h libhfcommon/util.h fuzz.h
+posix/arch.o: libhfcommon/common.h libhfcommon/files.h libhfcommon/common.h
+posix/arch.o: libhfcommon/log.h subproc.h
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index d645695673349e3947e8e5ae42332d0ac3164cd7..0000000000000000000000000000000000000000
--- a/NOTICE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 120000
index 0000000000000000000000000000000000000000..d24842f3cdcf2e447f9a7a26fa387ad63f5c4b91
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1 @@
+COPYING
\ No newline at end of file
diff --git a/README.md b/README.md
index 054a6f1302e30f8d08adede2f60e8a2c46d5290f..b2718ed5672421d8ddb73d1f13d639e3749b3a9d 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,56 @@
-# honggfuzz #
+# honggfuzz
-**Description**
+## Description
-A security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with interesting analysis options. See [USAGE](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for more data on the usage.
+A security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with interesting analysis options. See [USAGE](https://github.com/google/honggfuzz/blob/master/docs/USAGE.md) for the description of command-line options.
- * It's __multi-threaded__ and __multi-process__: no need to run multiple copies of your fuzzer, as honggfuzz can unlock potential of all your available CPU cores. The file corpus is shared between threads (and fuzzed instances)
- * It's blazingly fast (esp. in the [persistent fuzzing mode](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md)). A simple _LLVMFuzzerTestOneInput_ function can be tested with __up to 1mo iterations per second__ on a relatively modern CPU (e.g. i7-6700K)
- * Has a nice track record of uncovered security bugs: e.g. the __only__ (to the date) __vulnerability in OpenSSL with the [critical](https://www.openssl.org/news/secadv/20160926.txt) score mark__ was discovered by honggfuzz. See the Throphies paragraph for the summary of findings to the date
- * Uses low-level interfaces to monitor processes (e.g. _ptrace_ under Linux). As opposed to other fuzzers, it __will discover and report hidden signals__ (caught and potentially hidden by signal handlers)
- * Easy-to-use, feed it a simple input corpus (__can even consist of a single, 1-byte file__) and it will work its way up expanding it utilizing feedback-based coverage metrics
+ * It's __multi-process__ and __multi-threaded__: no need to run multiple copies of your fuzzer, as honggfuzz can unlock potential of all your available CPU cores with a single supervising process. The file corpus is automatically shared and improved between the fuzzing threads and fuzzed processes.
+ * It's blazingly fast when in the [persistent fuzzing mode](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md)). A simple/empty _LLVMFuzzerTestOneInput_ function can be tested with __up to 1mo iterations per second__ on a relatively modern CPU (e.g. i7-6700K)
+ * Has a [solid track record](#trophies) of uncovered security bugs: the __only__ (to the date) __vulnerability in OpenSSL with the [critical](https://www.openssl.org/news/secadv/20160926.txt) score mark__ was discovered by honggfuzz. See the [Trophies](#trophies) paragraph for the summary of findings to the date
+ * Uses low-level interfaces to monitor processes (e.g. _ptrace_ under Linux and NetBSD). As opposed to other fuzzers, it __will discover and report hijacked/ignored signals from crashes__ (intercepted and potentially hidden by a fuzzed program)
+ * Easy-to-use, feed it a simple corpus directory (can even be empty) and it will work its way up expanding it utilizing feedback-based coverage metrics
* Supports several (more than any other coverage-based feedback-driven fuzzer) hardware-based (CPU: branch/instruction counting, __Intel BTS__, __Intel PT__) and software-based [feedback-driven fuzzing](https://github.com/google/honggfuzz/blob/master/docs/FeedbackDrivenFuzzing.md) methods known from other fuzzers (libfuzzer, afl)
- * Works (at least) under GNU/Linux, FreeBSD, Mac OS X, Windows/CygWin and [Android](https://github.com/google/honggfuzz/blob/master/docs/Android.md)
- * Supports __persistent fuzzing mode__ (long-lived process calling a fuzzed API repeatedly) with libhfuzz/libhfuzz.a. More on that can be found [here](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md)
- * [Can fuzz remote/standalone long-lasting processes](https://github.com/google/honggfuzz/blob/master/docs/AttachingToPid.md) (e.g. network servers like __Apache's httpd__ and __ISC's bind__), though the [persistent fuzzing mode](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md) is suggested instead: as it's faster and multiple instances of a service can be fuzzed at once in this mode
+ * Works (at least) under GNU/Linux, FreeBSD, NetBSD, Mac OS X, Windows/CygWin and [Android](https://github.com/google/honggfuzz/blob/master/docs/Android.md)
+ * Supports the __persistent fuzzing mode__ (long-lived process calling a fuzzed API repeatedly) with libhfuzz/libhfuzz.a. More on that can be found [here](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md)
* It comes with the __[examples](https://github.com/google/honggfuzz/tree/master/examples) directory__, consisting of real world fuzz setups for widely-used software (e.g. Apache and OpenSSL)
-**Code**
+---
- * Latest stable version: [1.2](https://github.com/google/honggfuzz/releases), but using the __master__ branch is highly encouraged
+
+
+
+
+---
+
+## Code
+
+ * Latest stable version: [1.8](https://github.com/google/honggfuzz/releases)
* [Changelog](https://github.com/google/honggfuzz/blob/master/CHANGELOG)
-**Requirements**
+## Requirements
* **Linux** - The BFD library (libbfd-dev) and libunwind (libunwind-dev/libunwind8-dev), clang-4.0 or higher for software-based coverage modes
* **FreeBSD** - gmake, clang-3.6 or newer (clang-devel/4.0 suggested)
+ * **NetBSD** - gmake, clang, capstone, libBlocksRuntime
* **Android** - Android SDK/NDK. Also see [this detailed doc](https://github.com/google/honggfuzz/blob/master/docs/Android.md) on how to build and run it
* **Windows** - CygWin
* **Darwin/OS X** - Xcode 10.8+
* if **Clang/LLVM** is used to compile honggfuzz - link it with the BlocksRuntime Library (libblocksruntime-dev)
-**Trophies**
+
+## Trophies
Honggfuzz has been used to find a few interesting security problems in major software packages; An incomplete list:
* [Pre-auth remote crash in __OpenSSH__](https://anongit.mindrot.org/openssh.git/commit/?id=28652bca29046f62c7045e933e6b931de1d16737)
- * __Apache__
+ * __Apache HTTPD__
* [Remote crash in __mod\_http2__ • CVE-2017-7659](http://seclists.org/oss-sec/2017/q2/504)
* [Use-after-free in __mod\_http2__ • CVE-2017-9789](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9789)
* [Memory leak in __mod\_auth\_digest__ • CVE-2017-9788](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9788)
- * __SSL__
+ * [Out of bound access • CVE-2018-1301](http://seclists.org/oss-sec/2018/q1/265)
+ * [Write after free in HTTP/2 • CVE-2018-1302](http://seclists.org/oss-sec/2018/q1/268)
+ * [Out of bound read • CVE-2018-1303](http://seclists.org/oss-sec/2018/q1/266)
+ * Various __SSL__ libs
* [Remote OOB read in __OpenSSL__ • CVE-2015-1789]( https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1789)
* [Remote Use-after-Free (potential RCE, rated as __critical__) in __OpenSSL__ • CVE-2016-6309](https://www.openssl.org/news/secadv/20160926.txt)
* [Remote OOB write in __OpenSSL__ • CVE-2016-7054](https://www.openssl.org/news/secadv/20161110.txt)
@@ -53,10 +65,11 @@ Honggfuzz has been used to find a few interesting security problems in major sof
* [Multiple bugs in the __poppler__ library](http://lists.freedesktop.org/archives/poppler/2010-November/006726.html)
* [Multiple exploitable bugs in __IDA-Pro__](https://www.hex-rays.com/bugbounty.shtml)
* [Remote DoS in __Crypto++__ • CVE-2016-9939](http://www.openwall.com/lists/oss-security/2016/12/12/7)
- * Language interpreters
+ * Programming language interpreters
* [__PHP/Python/Ruby__](https://github.com/dyjakan/interpreter-bugs)
* [PHP WDDX](https://bugs.php.net/bug.php?id=74145)
* [PHP](https://bugs.php.net/bug.php?id=74194)
+ * [Perl](https://www.nntp.perl.org/group/perl.perl5.porters/2018/03/msg250072.html)
* [Double-free in __LibXMP__](https://github.com/cmatsuoka/libxmp/commit/bd1eb5cfcd802820073504c234c3f735e96c3355)
* [Heap buffer overflow in SAPCAR • CVE-2017-8852](https://www.coresecurity.com/blog/sapcar-heap-buffer-overflow-crash-exploit)
* [Crashes in __libbass__](http://seclists.org/oss-sec/2017/q4/185)
@@ -68,22 +81,39 @@ Honggfuzz has been used to find a few interesting security problems in major sof
* [CVE-2010-2519](https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2010-2519)
* [CVE-2010-2520](https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2010-2520)
* [CVE-2010-2527](https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2010-2527)
- * A couple of problems in the [__MATLAB MAT File I/O Library__](https://sourceforge.net/projects/matio): [1](https://github.com/tbeu/matio/commit/406438f497931f45fb3edf6de17d3a59a922c257), [2](https://github.com/tbeu/matio/commit/406438f497931f45fb3edf6de17d3a59a922c257), [3](https://github.com/tbeu/matio/commit/a55b9c2c01582b712d5a643699a13b5c41687db1), [4](https://github.com/tbeu/matio/commit/3e6283f37652e29e457ab9467f7738a562594b6b), [5](https://github.com/tbeu/matio/commit/783ee496a6914df68e77e6019054ad91e8ed6420)
+ * [Infinite loop in __NGINX Unit__](https://github.com/nginx/unit/commit/477e8177b70acb694759e62d830b8a311a736324)
+ * A couple of problems in the [__MATLAB MAT File I/O Library__](https://sourceforge.net/projects/matio): [#1](https://github.com/tbeu/matio/commit/406438f497931f45fb3edf6de17d3a59a922c257), [#2](https://github.com/tbeu/matio/commit/406438f497931f45fb3edf6de17d3a59a922c257), [#3](https://github.com/tbeu/matio/commit/a55b9c2c01582b712d5a643699a13b5c41687db1), [#4](https://github.com/tbeu/matio/commit/3e6283f37652e29e457ab9467f7738a562594b6b), [#5](https://github.com/tbeu/matio/commit/783ee496a6914df68e77e6019054ad91e8ed6420)
+ * [Samba's tdbdump + tdbtool](http://seclists.org/oss-sec/2018/q2/206)
+ * [Crash in __djvulibre__](https://github.com/barak/djvulibre/commit/89d71b01d606e57ecec2c2930c145bb20ba5bbe3)
+ * __Rust__:
+ * panic() in regex [#1](https://github.com/rust-lang/regex/issues/464), [#2](https://github.com/rust-lang/regex/issues/465), [#3](https://github.com/rust-lang/regex/issues/465#issuecomment-381412816)
+ * panic() in h2 [#1](https://github.com/carllerche/h2/pull/260), [#2](https://github.com/carllerche/h2/pull/261), [#3](https://github.com/carllerche/h2/pull/262)
+ * panic() in sleep-parser [#1](https://github.com/datrs/sleep-parser/issues/3)
+ * panic() in lewton [#1](https://github.com/RustAudio/lewton/issues/27)
* ... and more
-**Projects utilizing Honggfuzz**
+## Projects utilizing Honggfuzz
+
* [__QuickFuzz__ by CIFASIS](http://quickfuzz.org)
* [__OSS-Fuzz__](https://github.com/google/oss-fuzz)
* [__Frog And Fuzz__](https://github.com/warsang/FrogAndFuzz/tree/develop)
* [dyjakan's __interpreters fuzzing__ project](https://github.com/dyjakan/interpreter-bugs)
* [__riufuzz__: honggfuzz with AFL-like UI](https://github.com/riusksk/riufuzz)
- * [__h2fuzz__: fuzzing of Apache's HTTP/2 implementation](https://github.com/icing/h2fuzz)
+ * [__h2fuzz__: fuzzing Apache's HTTP/2 implementation](https://github.com/icing/h2fuzz)
* [__honggfuzz-dharma__: honggfuzz with dharma grammar fuzzer](https://github.com/Sbouber/honggfuzz-dharma)
* [__Owl__: a system for finding concurrency attacks](https://github.com/hku-systems/owl)
* [__honggfuzz-docker-apps__](https://github.com/skysider/honggfuzz_docker_apps)
* [__FFW - Fuzzing For Worms__](https://github.com/dobin/ffw)
+ * [__honggfuzz-rs__: fuzzing Rust with Honggfuzz](https://github.com/rust-fuzz/honggfuzz-rs)
+ * [__roughenough-fuzz__](https://github.com/int08h/roughenough-fuzz)
+ * [__Rust's fuzztest__](https://docs.rs/crate/fuzztest)
+ * [__Monkey__: a HTTP server](https://github.com/monkey/monkey/blob/master/FUZZ.md)
+ * [__Killerbeez API__](https://github.com/grimm-co/killerbeez-mutators)
+ * [__FuzzM__: a gray box model-based fuzzing framework](https://github.com/collins-research/FuzzM)
+ * [__FuzzOS__: by Mozilla Security](https://github.com/MozillaSecurity/fuzzos)
+ * [__Android__: by OHA](https://android.googlesource.com/platform/external/honggfuzz)
-**Examples**
+## Examples
The [examples](https://github.com/google/honggfuzz/tree/master/examples/)
directory contains code demonstrating (among others) how to use honggfuzz to find bugs in the
@@ -91,7 +121,7 @@ directory contains code demonstrating (among others) how to use honggfuzz to fin
library and in the [Apache](https://github.com/google/honggfuzz/tree/master/examples/apache-httpd)
HTTPD web server.
-**Other**
+## Other
* User mailing list: [honggfuzz@googlegroups.com](mailto:honggfuzz@googlegroups.com), sign up with [this link](https://groups.google.com/forum/#!forum/honggfuzz).
diff --git a/arch.h b/arch.h
index af4bd40650ccf78b45811199ae394841fb648905..39c5609a7ab120408a9f297c1918100cb7477e53 100644
--- a/arch.h
+++ b/arch.h
@@ -5,7 +5,7 @@
*
* Author: Robert Swiecki
*
- * Copyright 2010-2015 by Google Inc. All Rights Reserved.
+ * Copyright 2010-2018 by Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
diff --git a/cmdline.c b/cmdline.c
index 8f17e2a6873739f206e3074933d5a557ba0b3242..ebace3bedcc2c08704dc99c31020d778c19ee193 100644
--- a/cmdline.c
+++ b/cmdline.c
@@ -31,18 +31,21 @@
#include
#endif /* defined(_HF_ARCH_LINUX) */
#include
+#include
#include
#include
#include
+#include
#include
#include
#include
#include
-#include "libcommon/common.h"
-#include "libcommon/files.h"
-#include "libcommon/log.h"
-#include "libcommon/util.h"
+#include "display.h"
+#include "libhfcommon/common.h"
+#include "libhfcommon/files.h"
+#include "libhfcommon/log.h"
+#include "libhfcommon/util.h"
struct custom_option {
struct option opt;
@@ -56,7 +59,36 @@ static bool checkFor_FILE_PLACEHOLDER(const char* const* args) {
return false;
}
-static const char* cmdlineYesNo(bool yes) { return (yes ? "true" : "false"); }
+static bool cmdlineCheckBinaryType(honggfuzz_t* hfuzz) {
+ int fd;
+ off_t fileSz;
+ uint8_t* map = files_mapFile(hfuzz->exe.cmdline[0], &fileSz, &fd, /* isWriteable= */ false);
+ if (!map) {
+ /* It's not a critical error */
+ return true;
+ }
+ defer {
+ if (munmap(map, fileSz) == -1) {
+ PLOG_W("munmap(%p, %zu)", map, (size_t)fileSz);
+ }
+ close(fd);
+ };
+
+ if (memmem(map, fileSz, _HF_PERSISTENT_SIG, strlen(_HF_PERSISTENT_SIG))) {
+ LOG_I("Persistent signature found in '%s'. Enabling persistent fuzzing mode",
+ hfuzz->exe.cmdline[0]);
+ hfuzz->exe.persistent = true;
+ }
+ if (memmem(map, fileSz, _HF_NETDRIVER_SIG, strlen(_HF_NETDRIVER_SIG))) {
+ LOG_I("NetDriver signature found '%s'", hfuzz->exe.cmdline[0]);
+ hfuzz->exe.netDriver = true;
+ }
+ return true;
+}
+
+static const char* cmdlineYesNo(bool yes) {
+ return (yes ? "true" : "false");
+}
static void cmdlineHelp(const char* pname, struct custom_option* opts) {
LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname);
@@ -73,18 +105,17 @@ static void cmdlineHelp(const char* pname, struct custom_option* opts) {
}
LOG_HELP_BOLD("\nExamples:");
LOG_HELP(
- " Run the binary over a mutated file chosen from the directory. Disable fuzzing "
- "feedback (dry/static mode)");
+ " Run the binary over a mutated file chosen from the directory. Disable fuzzing feedback "
+ "(static mode):");
LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -x -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
LOG_HELP(" As above, provide input over STDIN:");
LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -x -s -- /usr/bin/djpeg");
- LOG_HELP(" Use compile-time instrumentation (libhfuzz/instrument.c):");
+ LOG_HELP(" Use compile-time instrumentation (-fsanitize-coverage=trace-pc-guard,...):");
LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
- LOG_HELP(" Use SANCOV instrumentation:");
- LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -C -- /usr/bin/djpeg " _HF_FILE_PLACEHOLDER);
- LOG_HELP(" Use persistent mode (libhfuzz/persistent.c) w/o instrumentation:");
+ LOG_HELP(" Use persistent mode w/o instrumentation:");
LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -P -x -- /usr/bin/djpeg_persistent_mode");
- LOG_HELP(" Use persistent mode (libhfuzz/persistent.c) and compile-time instrumentation:");
+ LOG_HELP(" Use persistent mode and compile-time (-fsanitize-coverage=trace-pc-guard,...) "
+ "instrumentation:");
LOG_HELP_BOLD(" " PROG_NAME " -f input_dir -P -- /usr/bin/djpeg_persistent_mode");
#if defined(_HF_ARCH_LINUX)
LOG_HELP(
@@ -105,6 +136,29 @@ static void cmdlineUsage(const char* pname, struct custom_option* opts) {
exit(0);
}
+bool cmdlineAddEnv(honggfuzz_t* hfuzz, char* env) {
+ size_t enveqlen = strlen(env);
+ const char* eqpos = strchr(env, '=');
+ if (eqpos) {
+ enveqlen = (uintptr_t)eqpos - (uintptr_t)env + 1;
+ }
+
+ for (size_t i = 0; i < ARRAYSIZE(hfuzz->exe.envs); i++) {
+ if (hfuzz->exe.envs[i] == NULL) {
+ LOG_D("Adding envar '%s'", env);
+ hfuzz->exe.envs[i] = env;
+ return true;
+ }
+ if (strncmp(hfuzz->exe.envs[i], env, enveqlen) == 0) {
+ LOG_W("Replacing envar '%s' with '%s'", hfuzz->exe.envs[i], env);
+ hfuzz->exe.envs[i] = env;
+ return true;
+ }
+ }
+ LOG_E("No more space for new envars (max.%zu)", ARRAYSIZE(hfuzz->exe.envs));
+ return false;
+}
+
rlim_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul) {
struct rlimit cur;
if (getrlimit(res, &cur) == -1) {
@@ -127,14 +181,19 @@ rlim_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul) {
}
static bool cmdlineVerify(honggfuzz_t* hfuzz) {
- if (!hfuzz->exe.fuzzStdin && !hfuzz->persistent &&
+ if (!cmdlineCheckBinaryType(hfuzz)) {
+ LOG_E("Couldn't test binary for signatures");
+ return false;
+ }
+
+ if (!hfuzz->exe.fuzzStdin && !hfuzz->exe.persistent &&
!checkFor_FILE_PLACEHOLDER(hfuzz->exe.cmdline)) {
LOG_E("You must specify '" _HF_FILE_PLACEHOLDER
- "' when the -s (stdin fuzzing) or --persistent options are not set");
+ "' if the -s (stdin fuzzing) or --persistent options are not set");
return false;
}
- if (hfuzz->exe.fuzzStdin && hfuzz->persistent) {
+ if (hfuzz->exe.fuzzStdin && hfuzz->exe.persistent) {
LOG_E(
"Stdin fuzzing (-s) and persistent fuzzing (-P) cannot be specified at the same time");
return false;
@@ -166,22 +225,13 @@ static bool cmdlineVerify(honggfuzz_t* hfuzz) {
return false;
}
- if (hfuzz->linux.pid > 0 || hfuzz->linux.pidFile) {
- LOG_I("PID=%d specified, lowering maximum number of concurrent threads to 1",
- hfuzz->linux.pid);
- hfuzz->threads.threadsMax = 1;
- }
-
- if (hfuzz->mutationsPerRun == 0U && hfuzz->useVerifier) {
+ if (hfuzz->mutate.mutationsPerRun == 0U && hfuzz->cfg.useVerifier) {
LOG_I("Verifier enabled with mutationsPerRun == 0, activating the dry run mode");
}
- /*
- * 'enableSanitizers' can be auto enabled when 'useSanCov', although it's probably
- * better to let user know about the features that each flag control.
- */
- if (hfuzz->useSanCov == true && hfuzz->enableSanitizers == false) {
- LOG_E("Sanitizer coverage cannot be used without enabling sanitizers '-S/--sanitizers'");
+ if (hfuzz->mutate.maxFileSz > _HF_INPUT_MAX_SIZE) {
+ LOG_E("Maximum file size '%zu' bigger than the maximum size '%zu'", hfuzz->mutate.maxFileSz,
+ (size_t)_HF_INPUT_MAX_SIZE);
return false;
}
@@ -189,7 +239,16 @@ static bool cmdlineVerify(honggfuzz_t* hfuzz) {
}
bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
- honggfuzz_t tmp = {
+ *hfuzz = (honggfuzz_t){
+ .threads =
+ {
+ .threadsFinished = 0,
+ .threadsMax =
+ (sysconf(_SC_NPROCESSORS_ONLN) <= 1) ? 1 : sysconf(_SC_NPROCESSORS_ONLN) / 2,
+ .threadsActiveCnt = 0,
+ .mainThread = pthread_self(),
+ .mainPid = getpid(),
+ },
.io =
{
.inputDir = NULL,
@@ -202,19 +261,24 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
.covDirAll = NULL,
.covDirNew = NULL,
.saveUnique = true,
+ .dynfileqCnt = 0U,
+ .dynfileq_mutex = PTHREAD_RWLOCK_INITIALIZER,
},
.exe =
{
+ .argc = 0,
.cmdline = NULL,
.nullifyStdio = true,
.fuzzStdin = false,
.externalCommand = NULL,
.postExternalCommand = NULL,
+ .persistent = false,
+ .netDriver = false,
.asLimit = 0U,
.rssLimit = 0U,
.dataLimit = 0U,
.clearEnv = false,
- .envs[0] = NULL,
+ .envs = {},
},
.timing =
{
@@ -222,50 +286,52 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
.runEndTime = 0,
.tmOut = 10,
.tmoutVTALRM = false,
+ .lastCovUpdate = time(NULL),
+ },
+ .mutate =
+ {
+ .mutationsMax = 0,
+ .dictionaryFile = NULL,
+ .dictionaryCnt = 0,
+ .mutationsPerRun = 6U,
+ .maxFileSz = 0UL,
},
- .cmdline_txt[0] = '\0',
- .useScreen = true,
- .useVerifier = false,
- .mutationsPerRun = 6U,
- .blacklistFile = NULL,
- .blacklistCnt = 0,
- .blacklist = NULL,
- .maxFileSz = 0UL,
- .mutationsMax = 0,
- .reportFile = NULL,
- .persistent = false,
- .skipFeedbackOnTimeout = false,
- .enableSanitizers = false,
+ .display =
+ {
+ .useScreen = true,
+ .lastDisplayMillis = util_timeNowMillis(),
+ .cmdline_txt[0] = '\0',
+ },
+ .cfg =
+ {
+ .useVerifier = false,
+ .exitUponCrash = false,
+ .report_mutex = PTHREAD_MUTEX_INITIALIZER,
+ .reportFile = NULL,
+ .dynFileIterExpire = 0,
#if defined(__ANDROID__)
- .monitorSIGABRT = false,
+ .monitorSIGABRT = false,
#else
- .monitorSIGABRT = true,
+ .monitorSIGABRT = true,
#endif
- .exitUponCrash = false,
-
- .threads =
+ .only_printable = false,
+ },
+ .sanitizer =
{
- .threadsFinished = 0,
- .threadsMax =
- (sysconf(_SC_NPROCESSORS_ONLN) <= 1) ? 1 : sysconf(_SC_NPROCESSORS_ONLN) / 2,
- .threadsActiveCnt = 0,
- .mainThread = pthread_self(),
- .mainPid = getpid(),
+ .enable = false,
+ },
+ .feedback =
+ {
+ .feedbackMap = NULL,
+ .feedback_mutex = PTHREAD_MUTEX_INITIALIZER,
+ .bbFd = -1,
+ .blacklistFile = NULL,
+ .blacklist = NULL,
+ .blacklistCnt = 0,
+ .skipFeedbackOnTimeout = false,
+ .dynFileMethod = _HF_DYNFILE_SOFT,
+ .state = _HF_STATE_UNSET,
},
-
- .dictionaryFile = NULL,
- .dictionaryCnt = 0,
- .dictqCurrent = NULL,
-
- .state = _HF_STATE_UNSET,
- .feedback = NULL,
- .bbFd = -1,
-
- .dynfileqCnt = 0U,
- .dynfileq_mutex = PTHREAD_RWLOCK_INITIALIZER,
-
- .feedback_mutex = PTHREAD_MUTEX_INITIALIZER,
-
.cnts =
{
.mutationsCnt = 0,
@@ -275,29 +341,12 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
.blCrashesCnt = 0,
.timeoutedCnt = 0,
},
-
- .dynFileMethod = _HF_DYNFILE_SOFT,
- .sanCovCnts =
- {
- .hitBBCnt = 0ULL,
- .totalBBCnt = 0ULL,
- .dsoCnt = 0ULL,
- .iDsoCnt = 0ULL,
- .newBBCnt = 0ULL,
- .crashesCnt = 0ULL,
- },
-
- .sanCov_mutex = PTHREAD_MUTEX_INITIALIZER,
- .sanOpts =
+ .socketFuzzer =
{
- .asanOpts = NULL,
- .msanOpts = NULL,
- .ubsanOpts = NULL,
+ .enabled = false,
+ .serverSocket = -1,
+ .clientSocket = -1,
},
- .useSanCov = false,
- .covMetadata = NULL,
-
- .report_mutex = PTHREAD_MUTEX_INITIALIZER,
/* Linux code */
.linux =
@@ -316,9 +365,6 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
.disableRandomization = true,
.ignoreAddr = NULL,
.numMajorFrames = 7,
- .pid = 0,
- .pidFile = NULL,
- .pidCmd[0] = '\0',
.symsBlFile = NULL,
.symsBlCnt = 0,
.symsBl = NULL,
@@ -329,29 +375,40 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
.kernelOnly = false,
.useClone = true,
},
+ /* NetBSD code */
+ .netbsd =
+ {
+ .ignoreAddr = NULL,
+ .numMajorFrames = 7,
+ .symsBlFile = NULL,
+ .symsBlCnt = 0,
+ .symsBl = NULL,
+ .symsWlFile = NULL,
+ .symsWlCnt = 0,
+ .symsWl = NULL,
+ },
};
- *hfuzz = tmp;
- TAILQ_INIT(&hfuzz->dynfileq);
- TAILQ_INIT(&hfuzz->dictq);
+ TAILQ_INIT(&hfuzz->io.dynfileq);
+ TAILQ_INIT(&hfuzz->mutate.dictq);
// clang-format off
struct custom_option custom_opts[] = {
{ { "help", no_argument, NULL, 'h' }, "Help plz.." },
{ { "input", required_argument, NULL, 'f' }, "Path to a directory containing initial file corpus" },
- { { "persistent", no_argument, NULL, 'P' }, "Enable persistent fuzzing (use hfuzz_cc/hfuzz-clang to compile code)" },
+ { { "persistent", no_argument, NULL, 'P' }, "Enable persistent fuzzing (use hfuzz_cc/hfuzz-clang to compile code). This will be auto-detected!!!" },
{ { "instrument", no_argument, NULL, 'z' }, "*DEFAULT-MODE-BY-DEFAULT* Enable compile-time instrumentation (use hfuzz_cc/hfuzz-clang to compile code)" },
- { { "noinst", no_argument, NULL, 'x' }, "Static mode (dry-mode), disable any instrumentation (hw/sw)" },
- { { "sancov", no_argument, NULL, 'C' }, "Enable sanitizer coverage feedback" },
+ { { "noinst", no_argument, NULL, 'x' }, "Static mode only, disable any instrumentation (hw/sw) feedback" },
{ { "keep_output", no_argument, NULL, 'Q' }, "Don't close children's stdin, stdout, stderr; can be noisy" },
- { { "timeout", required_argument, NULL, 't' }, "Timeout in seconds (default: '10')" },
+ { { "timeout", required_argument, NULL, 't' }, "Timeout in seconds (default: 10)" },
{ { "threads", required_argument, NULL, 'n' }, "Number of concurrent fuzzing threads (default: number of CPUs / 2)" },
{ { "stdin_input", no_argument, NULL, 's' }, "Provide fuzzing input on STDIN, instead of ___FILE___" },
- { { "mutations_per_run", required_argument, NULL, 'r' }, "Maximal number of mutations per one run (default: '6')" },
+ { { "mutations_per_run", required_argument, NULL, 'r' }, "Maximal number of mutations per one run (default: 6)" },
{ { "logfile", required_argument, NULL, 'l' }, "Log file" },
{ { "verbose", no_argument, NULL, 'v' }, "Disable ANSI console; use simple log output" },
{ { "verifier", no_argument, NULL, 'V' }, "Enable crashes verifier" },
- { { "debug_level", required_argument, NULL, 'd' }, "Debug level (0 - FATAL ... 4 - DEBUG), (default: '3' [INFO])" },
+ { { "debug", no_argument, NULL, 'd' }, "Show debug messages (level >= 4)" },
+ { { "quiet", no_argument, NULL, 'q' }, "Show only warnings and more serious messages (level <= 1)" },
{ { "extension", required_argument, NULL, 'e' }, "Input file extension (e.g. 'swf'), (default: 'fuzz')" },
{ { "workspace", required_argument, NULL, 'W' }, "Workspace directory to save crashes & runtime files (default: '.')" },
{ { "crashdir", required_argument, NULL, 0x600 }, "Directory where crashes are saved to (default: workspace directory)" },
@@ -361,28 +418,30 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
{ { "stackhash_bl", required_argument, NULL, 'B' }, "Stackhashes blacklist file (one entry per line)" },
{ { "mutate_cmd", required_argument, NULL, 'c' }, "External command producing fuzz files (instead of internal mutators)" },
{ { "pprocess_cmd", required_argument, NULL, 0x104 }, "External command postprocessing files produced by internal mutators" },
- { { "run_time", required_argument, NULL, 0x109 }, "Number of seconds this fuzzing session will last (default: '0' [no limit])" },
- { { "iterations", required_argument, NULL, 'N' }, "Number of fuzzing iterations (default: '0' [no limit])" },
- { { "rlimit_as", required_argument, NULL, 0x100 }, "Per process RLIMIT_AS in MiB (default: '0' [no limit])" },
- { { "rlimit_rss", required_argument, NULL, 0x101 }, "Per process RLIMIT_RSS in MiB (default: '0' [no limit])" },
- { { "rlimit_data", required_argument, NULL, 0x102 }, "Per process RLIMIT_DATA in MiB (default: '0' [no limit])" },
- { { "report", required_argument, NULL, 'R' }, "Write report to this file (default: '" _HF_REPORT_FILE "')" },
- { { "max_file_size", required_argument, NULL, 'F' }, "Maximal size of files processed by the fuzzer in bytes (default: '1048576')" },
+ { { "run_time", required_argument, NULL, 0x109 }, "Number of seconds this fuzzing session will last (default: 0 [no limit])" },
+ { { "iterations", required_argument, NULL, 'N' }, "Number of fuzzing iterations (default: 0 [no limit])" },
+ { { "rlimit_as", required_argument, NULL, 0x100 }, "Per process RLIMIT_AS in MiB (default: 0 [no limit])" },
+ { { "rlimit_rss", required_argument, NULL, 0x101 }, "Per process RLIMIT_RSS in MiB (default: 0 [no limit]). It will also set *SAN's soft_rss_limit_mb if used" },
+ { { "rlimit_data", required_argument, NULL, 0x102 }, "Per process RLIMIT_DATA in MiB (default: 0 [no limit])" },
+ { { "rlimit_core", required_argument, NULL, 0x103 }, "Per process RLIMIT_CORE in MiB (default: 0 [no cores are produced])" },
+ { { "report", required_argument, NULL, 'R' }, "Write report to this file (default: '/" _HF_REPORT_FILE "')" },
+ { { "max_file_size", required_argument, NULL, 'F' }, "Maximal size of files processed by the fuzzer in bytes (default: 1048576)" },
{ { "clear_env", no_argument, NULL, 0x108 }, "Clear all environment variables before executing the binary" },
{ { "env", required_argument, NULL, 'E' }, "Pass this environment variable, can be used multiple times" },
{ { "save_all", no_argument, NULL, 'u' }, "Save all test-cases (not only the unique ones) by appending the current time-stamp to the filenames" },
{ { "tmout_sigvtalrm", no_argument, NULL, 'T' }, "Use SIGVTALRM to kill timeouting processes (default: use SIGKILL)" },
{ { "sanitizers", no_argument, NULL, 'S' }, "Enable sanitizers settings (default: false)" },
- { { "monitor_sigabrt", required_argument, NULL, 0x105 }, "Monitor SIGABRT (default: 'false for Android - 'true for other platforms)" },
- { { "no_fb_timeout", required_argument, NULL, 0x106 }, "Skip feedback if the process has timeouted (default: 'false')" },
- { { "exit_upon_crash", no_argument, NULL, 0x107 }, "Exit upon seeing the first crash (default: 'false')" },
+ { { "monitor_sigabrt", required_argument, NULL, 0x105 }, "Monitor SIGABRT (default: false for Android, true for other platforms)" },
+ { { "no_fb_timeout", required_argument, NULL, 0x106 }, "Skip feedback if the process has timeouted (default: false)" },
+ { { "exit_upon_crash", no_argument, NULL, 0x107 }, "Exit upon seeing the first crash (default: false)" },
+ { { "socket_fuzzer", no_argument, NULL, 0x10B }, "Instrument external fuzzer via socket" },
+ { { "netdriver", no_argument, NULL, 0x10C }, "Use netdriver (libhfnetdriver/). In most cases it will be autodetected through a binary signature" },
+ { { "only_printable", no_argument, NULL, 'o' }, "Only generate printable inputs" },
#if defined(_HF_ARCH_LINUX)
{ { "linux_symbols_bl", required_argument, NULL, 0x504 }, "Symbols blacklist filter file (one entry per line)" },
{ { "linux_symbols_wl", required_argument, NULL, 0x505 }, "Symbols whitelist filter file (one entry per line)" },
- { { "linux_pid", required_argument, NULL, 'p' }, "Attach to a pid (and its thread group)" },
- { { "linux_file_pid", required_argument, NULL, 0x502 }, "Attach to pid (and its thread group) read from file" },
- { { "linux_addr_low_limit", required_argument, NULL, 0x500 }, "Address limit (from si.si_addr) below which crashes are not reported, (default: '0')" },
+ { { "linux_addr_low_limit", required_argument, NULL, 0x500 }, "Address limit (from si.si_addr) below which crashes are not reported, (default: 0)" },
{ { "linux_keep_aslr", no_argument, NULL, 0x501 }, "Don't disable ASLR randomization, might be useful with MSAN" },
{ { "linux_perf_ignore_above", required_argument, NULL, 0x503 }, "Ignore perf events which report IPs above this address" },
{ { "linux_perf_instr", no_argument, NULL, 0x510 }, "Use PERF_COUNT_HW_INSTRUCTIONS perf" },
@@ -394,6 +453,12 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
{ { "linux_ns_pid", no_argument, NULL, 0x0531 }, "Use Linux PID namespace isolation" },
{ { "linux_ns_ipc", no_argument, NULL, 0x0532 }, "Use Linux IPC namespace isolation" },
#endif // defined(_HF_ARCH_LINUX)
+
+#if defined(_HF_ARCH_NETBSD)
+ { { "netbsd_symbols_bl", required_argument, NULL, 0x504 }, "Symbols blacklist filter file (one entry per line)" },
+ { { "netbsd_symbols_wl", required_argument, NULL, 0x505 }, "Symbols whitelist filter file (one entry per line)" },
+ { { "netbsd_addr_low_limit", required_argument, NULL, 0x500 }, "Address limit (from si.si_addr) below which crashes are not reported, (default: 0)" },
+#endif // defined(_HF_ARCH_NETBSD)
{ { 0, 0, 0, 0 }, NULL },
};
// clang-format on
@@ -408,7 +473,7 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
int opt_index = 0;
for (;;) {
int c = getopt_long(
- argc, argv, "-?hQvVsuPxf:d:e:W:r:c:F:t:R:n:N:l:p:g:E:w:B:CzTS", opts, &opt_index);
+ argc, argv, "-?hQvVsuPxf:dqe:W:r:c:F:t:R:n:N:l:p:g:E:w:B:zTSo", opts, &opt_index);
if (c < 0) break;
switch (c) {
@@ -423,16 +488,16 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
}
break;
case 'x':
- hfuzz->dynFileMethod = _HF_DYNFILE_NONE;
+ hfuzz->feedback.dynFileMethod = _HF_DYNFILE_NONE;
break;
case 'Q':
hfuzz->exe.nullifyStdio = false;
break;
case 'v':
- hfuzz->useScreen = false;
+ hfuzz->display.useScreen = false;
break;
case 'V':
- hfuzz->useVerifier = true;
+ hfuzz->cfg.useVerifier = true;
break;
case 's':
hfuzz->exe.fuzzStdin = true;
@@ -444,7 +509,10 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
logfile = optarg;
break;
case 'd':
- ll = atoi(optarg);
+ ll = DEBUG;
+ break;
+ case 'q':
+ ll = WARNING;
break;
case 'e':
hfuzz->io.fileExtn = optarg;
@@ -462,28 +530,35 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
hfuzz->io.covDirNew = optarg;
break;
case 'r':
- hfuzz->mutationsPerRun = strtoul(optarg, NULL, 10);
+ hfuzz->mutate.mutationsPerRun = strtoul(optarg, NULL, 10);
break;
case 'c':
hfuzz->exe.externalCommand = optarg;
break;
- case 'C':
- hfuzz->useSanCov = true;
- break;
case 'S':
- hfuzz->enableSanitizers = true;
+ hfuzz->sanitizer.enable = true;
+ break;
+ case 0x10B:
+ hfuzz->socketFuzzer.enabled = true;
+ hfuzz->timing.tmOut = 0; // Disable process timeout checks
+ break;
+ case 0x10C:
+ hfuzz->exe.netDriver = true;
+ break;
+ case 'o':
+ hfuzz->cfg.only_printable = true;
break;
case 'z':
- hfuzz->dynFileMethod |= _HF_DYNFILE_SOFT;
+ hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_SOFT;
break;
case 'F':
- hfuzz->maxFileSz = strtoul(optarg, NULL, 0);
+ hfuzz->mutate.maxFileSz = strtoul(optarg, NULL, 0);
break;
case 't':
hfuzz->timing.tmOut = atol(optarg);
break;
case 'R':
- hfuzz->reportFile = optarg;
+ hfuzz->cfg.reportFile = optarg;
break;
case 'n':
hfuzz->threads.threadsMax = atol(optarg);
@@ -495,7 +570,7 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
}
} break;
case 'N':
- hfuzz->mutationsMax = atol(optarg);
+ hfuzz->mutate.mutationsMax = atol(optarg);
break;
case 0x100:
hfuzz->exe.asLimit = strtoull(optarg, NULL, 0);
@@ -506,58 +581,44 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
case 0x102:
hfuzz->exe.dataLimit = strtoull(optarg, NULL, 0);
break;
+ case 0x103:
+ hfuzz->exe.coreLimit = strtoull(optarg, NULL, 0);
+ break;
case 0x104:
hfuzz->exe.postExternalCommand = optarg;
break;
case 0x105:
if ((strcasecmp(optarg, "0") == 0) || (strcasecmp(optarg, "false") == 0)) {
- hfuzz->monitorSIGABRT = false;
+ hfuzz->cfg.monitorSIGABRT = false;
} else {
- hfuzz->monitorSIGABRT = true;
+ hfuzz->cfg.monitorSIGABRT = true;
}
break;
case 0x106:
- hfuzz->skipFeedbackOnTimeout = true;
+ hfuzz->feedback.skipFeedbackOnTimeout = true;
break;
case 0x107:
- hfuzz->exitUponCrash = true;
+ hfuzz->cfg.exitUponCrash = true;
break;
case 0x108:
hfuzz->exe.clearEnv = true;
break;
case 'P':
- hfuzz->persistent = true;
+ hfuzz->exe.persistent = true;
break;
case 'T':
hfuzz->timing.tmoutVTALRM = true;
break;
- case 'p':
- if (util_isANumber(optarg) == false) {
- LOG_E("-p '%s' is not a number", optarg);
- return false;
- }
- hfuzz->linux.pid = atoi(optarg);
- if (hfuzz->linux.pid < 1) {
- LOG_E("-p '%d' is invalid", hfuzz->linux.pid);
- return false;
- }
- break;
- case 0x502:
- hfuzz->linux.pidFile = optarg;
- break;
case 'E':
- for (size_t i = 0; i < ARRAYSIZE(hfuzz->exe.envs); i++) {
- if (hfuzz->exe.envs[i] == NULL) {
- hfuzz->exe.envs[i] = optarg;
- break;
- }
+ if (!cmdlineAddEnv(hfuzz, optarg)) {
+ return false;
}
break;
case 'w':
- hfuzz->dictionaryFile = optarg;
+ hfuzz->mutate.dictionaryFile = optarg;
break;
case 'B':
- hfuzz->blacklistFile = optarg;
+ hfuzz->feedback.blacklistFile = optarg;
break;
#if defined(_HF_ARCH_LINUX)
case 0x500:
@@ -576,16 +637,16 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
hfuzz->linux.symsWlFile = optarg;
break;
case 0x510:
- hfuzz->dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
+ hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_INSTR_COUNT;
break;
case 0x511:
- hfuzz->dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
+ hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_BRANCH_COUNT;
break;
case 0x513:
- hfuzz->dynFileMethod |= _HF_DYNFILE_BTS_EDGE;
+ hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_BTS_EDGE;
break;
case 0x514:
- hfuzz->dynFileMethod |= _HF_DYNFILE_IPT_BLOCK;
+ hfuzz->feedback.dynFileMethod |= _HF_DYNFILE_IPT_BLOCK;
break;
case 0x515:
hfuzz->linux.kernelOnly = true;
@@ -600,6 +661,17 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
hfuzz->linux.cloneFlags |= (CLONE_NEWUSER | CLONE_NEWIPC);
break;
#endif /* defined(_HF_ARCH_LINUX) */
+#if defined(_HF_ARCH_NETBSD)
+ case 0x500:
+ hfuzz->netbsd.ignoreAddr = (void*)strtoul(optarg, NULL, 0);
+ break;
+ case 0x504:
+ hfuzz->netbsd.symsBlFile = optarg;
+ break;
+ case 0x505:
+ hfuzz->netbsd.symsWlFile = optarg;
+ break;
+#endif /* defined(_HF_ARCH_NETBSD) */
default:
cmdlineUsage(argv[0], custom_opts);
return false;
@@ -607,48 +679,35 @@ bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz) {
}
}
- if (!logInitLogFile(logfile, ll)) {
- return false;
- }
+ logInitLogFile(logfile, -1, ll);
+
+ hfuzz->exe.argc = argc - optind;
hfuzz->exe.cmdline = (const char* const*)&argv[optind];
- if (hfuzz->exe.cmdline[0] == NULL) {
+ if (hfuzz->exe.argc <= 0) {
LOG_E("No fuzz command provided");
cmdlineUsage(argv[0], custom_opts);
return false;
}
+ if (!files_exists(hfuzz->exe.cmdline[0])) {
+ LOG_E("Your fuzzed binary '%s' doesn't seem to exist", hfuzz->exe.cmdline[0]);
+ return false;
+ }
if (!cmdlineVerify(hfuzz)) {
return false;
}
- LOG_I(
- "PID: %d, inputDir '%s', nullifyStdio: %s, fuzzStdin: %s, saveUnique: %s, "
- "mutationsPerRun: %u, "
- "externalCommand: '%s', runEndTime: %d tmOut: %ld, mutationsMax: %zu, "
- "threads.threadsMax: %zu, "
- "fileExtn: '%s', "
- "ASLimit: 0x%" PRIx64 "(MiB), RSSLimit: 0x%" PRIx64 ", DATALimit: 0x%" PRIx64
- ", fuzzExe: '%s', fuzzedPid: %d, monitorSIGABRT: '%s'",
- (int)getpid(), hfuzz->io.inputDir, cmdlineYesNo(hfuzz->exe.nullifyStdio),
- cmdlineYesNo(hfuzz->exe.fuzzStdin), cmdlineYesNo(hfuzz->io.saveUnique),
- hfuzz->mutationsPerRun,
- hfuzz->exe.externalCommand == NULL ? "NULL" : hfuzz->exe.externalCommand,
- (int)hfuzz->timing.runEndTime, hfuzz->timing.tmOut, hfuzz->mutationsMax,
- hfuzz->threads.threadsMax, hfuzz->io.fileExtn, hfuzz->exe.asLimit, hfuzz->exe.rssLimit,
- hfuzz->exe.dataLimit, hfuzz->exe.cmdline[0], hfuzz->linux.pid,
- cmdlineYesNo(hfuzz->monitorSIGABRT));
-
- snprintf(hfuzz->cmdline_txt, sizeof(hfuzz->cmdline_txt), "%s", hfuzz->exe.cmdline[0]);
- for (size_t i = 1; hfuzz->exe.cmdline[i]; i++) {
- util_ssnprintf(
- hfuzz->cmdline_txt, sizeof(hfuzz->cmdline_txt), " %s", hfuzz->exe.cmdline[i]);
- if (strlen(hfuzz->cmdline_txt) == (sizeof(hfuzz->cmdline_txt) - 1)) {
- hfuzz->cmdline_txt[sizeof(hfuzz->cmdline_txt) - 5] = ' ';
- hfuzz->cmdline_txt[sizeof(hfuzz->cmdline_txt) - 4] = '.';
- hfuzz->cmdline_txt[sizeof(hfuzz->cmdline_txt) - 3] = '.';
- hfuzz->cmdline_txt[sizeof(hfuzz->cmdline_txt) - 2] = '.';
- hfuzz->cmdline_txt[sizeof(hfuzz->cmdline_txt) - 1] = '\0';
- }
- }
+ display_createTargetStr(hfuzz);
+
+ sigemptyset(&hfuzz->exe.waitSigSet);
+ sigaddset(&hfuzz->exe.waitSigSet, SIGIO); /* Persistent socket data */
+ sigaddset(&hfuzz->exe.waitSigSet, SIGUSR1); /* Ping from the signal thread */
+
+ LOG_I("cmdline:'%s', bin:'%s' inputDir:'%s', fuzzStdin:%s, mutationsPerRun:%u, "
+ "externalCommand:'%s', timeout:%ld, mutationsMax:%zu, threadsMax:%zu",
+ hfuzz->display.cmdline_txt, hfuzz->exe.cmdline[0], hfuzz->io.inputDir,
+ cmdlineYesNo(hfuzz->exe.fuzzStdin), hfuzz->mutate.mutationsPerRun,
+ !hfuzz->exe.externalCommand ? "" : hfuzz->exe.externalCommand, (long)hfuzz->timing.tmOut,
+ hfuzz->mutate.mutationsMax, hfuzz->threads.threadsMax);
return true;
}
diff --git a/cmdline.h b/cmdline.h
index 2c998a2f8fd9ef60c1494bc1dcef73cb9e473191..60327f3f958e67ab2f21e87ea00987c59be099f5 100644
--- a/cmdline.h
+++ b/cmdline.h
@@ -26,10 +26,12 @@
#include
#include "honggfuzz.h"
-#include "libcommon/common.h"
+#include "libhfcommon/common.h"
rlim_t cmdlineParseRLimit(int res, const char* optarg, unsigned long mul);
+bool cmdlineAddEnv(honggfuzz_t* hfuzz, char* env);
+
bool cmdlineParse(int argc, char* argv[], honggfuzz_t* hfuzz);
#endif /* _HF_CMDLINE_H_ */
diff --git a/display.c b/display.c
index 48a0ebcd366c2890d66065ce420e1e2b11cf0871..c38f930130f5856cbbac30fe1869572a5fca03f6 100644
--- a/display.c
+++ b/display.c
@@ -5,7 +5,7 @@
*
* Author: Robert Swiecki
*
- * Copyright 2010-2015 by Google Inc. All Rights Reserved.
+ * Copyright 2010-2018 by Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
@@ -33,9 +33,9 @@
#include
#include
-#include "libcommon/common.h"
-#include "libcommon/log.h"
-#include "libcommon/util.h"
+#include "libhfcommon/common.h"
+#include "libhfcommon/log.h"
+#include "libhfcommon/util.h"
#define ESC_CLEAR_ALL "\033[2J"
#define ESC_CLEAR_LINE "\033[2K"
@@ -45,18 +45,17 @@
#define ESC_BOLD "\033[1m"
#define ESC_RED "\033[31m"
#define ESC_RESET "\033[0m"
-#define ESC_SCROLL(x, y) "\033[" #x ";" #y "r"
+#define ESC_SCROLL_REGION(x, y) "\033[" #x ";" #y "r"
#define ESC_SCROLL_DISABLE "\033[?7h"
-#define ESC_SCROLL_ENABLE "\033[r"
+#define ESC_SCROLL_RESET "\033[r"
+#define ESC_NAV_DOWN(x) "\033[" #x "B"
+#define ESC_NAV_HORIZ(x) "\033[" #x "G"
#define ESC_RESET_SETTINGS "\033[!p"
-#if defined(_HF_ARCH_LINUX)
-#define _HF_MONETARY_MOD "'"
-#else
-#define _HF_MONETARY_MOD ""
-#endif
+/* printf() nonmonetary separator. According to MacOSX's man it's supported there as well */
+#define _HF_NONMON_SEP "'"
-static void display_put(const char* fmt, ...) {
+__attribute__((format(printf, 1, 2))) static void display_put(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
vdprintf(logFd(), fmt, args);
@@ -65,22 +64,27 @@ static void display_put(const char* fmt, ...) {
static void display_printKMG(uint64_t val) {
if (val >= 1000000000UL) {
- display_put(" [%.2lfG]", (double)val / 1000000000.0);
+ display_put(" [%.02LfG]", (long double)val / 1000000000.0L);
} else if (val >= 1000000UL) {
- display_put(" [%.2lfM]", (double)val / 1000000.0);
+ display_put(" [%.02LfM]", (long double)val / 1000000.0L);
} else if (val >= 1000UL) {
- display_put(" [%.2lfk]", (double)val / 1000.0);
+ display_put(" [%.02Lfk]", (long double)val / 1000.0L);
}
}
-static unsigned getCpuUse(long num_cpu) {
+static unsigned getCpuUse(int numCpus) {
+ static uint64_t prevUserT = 0UL;
+ static uint64_t prevNiceT = 0UL;
+ static uint64_t prevSystemT = 0UL;
static uint64_t prevIdleT = 0UL;
FILE* f = fopen("/proc/stat", "re");
if (f == NULL) {
return 0;
}
- defer { fclose(f); };
+ defer {
+ fclose(f);
+ };
uint64_t userT, niceT, systemT, idleT;
if (fscanf(f, "cpu %" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &userT, &niceT, &systemT,
&idleT) != 4) {
@@ -88,40 +92,53 @@ static unsigned getCpuUse(long num_cpu) {
return 0;
}
- if (prevIdleT == 0UL) {
- prevIdleT = idleT;
+ uint64_t userCycles = (userT - prevUserT);
+ uint64_t niceCycles = (niceT - prevNiceT);
+ uint64_t systemCycles = (systemT - prevSystemT);
+ uint64_t idleCycles = (idleT - prevIdleT);
+
+ prevUserT = userT;
+ prevNiceT = niceT;
+ prevSystemT = systemT;
+ prevIdleT = idleT;
+
+ uint64_t allCycles = userCycles + niceCycles + systemCycles + idleCycles;
+ if (allCycles == 0) {
return 0;
}
- uint64_t cpuUse = (num_cpu * sysconf(_SC_CLK_TCK)) - (idleT - prevIdleT);
- prevIdleT = idleT;
- return cpuUse * 100 / sysconf(_SC_CLK_TCK);
+ return ((userCycles + niceCycles + systemCycles) * numCpus * 100) / (allCycles);
}
-static void display_displayLocked(honggfuzz_t* hfuzz) {
- static bool firstDisplay = true;
- if (firstDisplay) {
- display_put(ESC_CLEAR_ALL);
- firstDisplay = false;
+static void getDuration(time_t elapsed_second, char* buf, size_t bufSz) {
+ if (elapsed_second < 0) {
+ snprintf(buf, bufSz, "----");
+ return;
}
- unsigned long elapsed_second = (unsigned long)(time(NULL) - hfuzz->timing.timeStart);
unsigned int day, hour, min, second;
- char time_elapsed_str[64];
- if (elapsed_second < 24 * 3600) {
- hour = elapsed_second / 3600;
- min = (elapsed_second - 3600 * hour) / 60;
- second = elapsed_second - hour * 3600 - min * 60;
- snprintf(
- time_elapsed_str, sizeof(time_elapsed_str), "%u hrs %u min %u sec", hour, min, second);
+ day = elapsed_second / 24 / 3600;
+ elapsed_second = elapsed_second - day * 24 * 3600;
+ hour = elapsed_second / 3600;
+ min = (elapsed_second - 3600 * hour) / 60;
+ second = elapsed_second - hour * 3600 - min * 60;
+ snprintf(buf, bufSz, "%u days %02u hrs %02u mins %02u secs", day, hour, min, second);
+}
+
+static void display_displayLocked(honggfuzz_t* hfuzz) {
+ const time_t curr_sec = time(NULL);
+ const time_t elapsed_sec = curr_sec - hfuzz->timing.timeStart;
+ const int64_t curr_time_millis = util_timeNowMillis();
+ const int64_t elapsed_millis = curr_time_millis - hfuzz->display.lastDisplayMillis;
+ hfuzz->display.lastDisplayMillis = curr_time_millis;
+
+ char lastCovStr[64];
+ getDuration(curr_sec - ATOMIC_GET(hfuzz->timing.lastCovUpdate), lastCovStr, sizeof(lastCovStr));
+ char timeStr[64];
+ if (ATOMIC_GET(hfuzz->timing.runEndTime)) {
+ getDuration(ATOMIC_GET(hfuzz->timing.runEndTime) - curr_sec, timeStr, sizeof(timeStr));
} else {
- day = elapsed_second / 24 / 3600;
- elapsed_second = elapsed_second - day * 24 * 3600;
- hour = elapsed_second / 3600;
- min = (elapsed_second - 3600 * hour) / 60;
- second = elapsed_second - hour * 3600 - min * 60;
- snprintf(time_elapsed_str, sizeof(time_elapsed_str), "%u days %u hrs %u min %u sec", day,
- hour, min, second);
+ getDuration(elapsed_sec, timeStr, sizeof(timeStr));
}
size_t curr_exec_cnt = ATOMIC_GET(hfuzz->cnts.mutationsCnt);
@@ -131,160 +148,151 @@ static void display_displayLocked(honggfuzz_t* hfuzz) {
* Therefore at the end of fuzzing, the mutation counter might be higher
* than hfuzz->mutationsMax
*/
- if (hfuzz->mutationsMax > 0 && curr_exec_cnt > hfuzz->mutationsMax) {
- curr_exec_cnt = hfuzz->mutationsMax;
+ if (hfuzz->mutate.mutationsMax > 0 && curr_exec_cnt > hfuzz->mutate.mutationsMax) {
+ curr_exec_cnt = hfuzz->mutate.mutationsMax;
}
- float exeProgress = 0.0f;
- if (hfuzz->mutationsMax > 0) {
- exeProgress = ((float)curr_exec_cnt * 100 / hfuzz->mutationsMax);
+ int exeProgress = 0;
+ if (hfuzz->mutate.mutationsMax > 0) {
+ exeProgress = (curr_exec_cnt * 100) / hfuzz->mutate.mutationsMax;
}
static size_t prev_exec_cnt = 0UL;
- uintptr_t exec_per_sec = curr_exec_cnt - prev_exec_cnt;
+ size_t exec_per_millis =
+ elapsed_millis ? ((curr_exec_cnt - prev_exec_cnt) * 1000) / elapsed_millis : 0;
prev_exec_cnt = curr_exec_cnt;
- /* The lock should be acquired before any output is printed on the screen */
- MX_SCOPED_LOCK(logMutexGet());
-
display_put(ESC_NAV(13, 1) ESC_CLEAR_ABOVE ESC_NAV(1, 1));
- display_put("--------------------------- [ " ESC_BOLD "HONGGFUZZ" ESC_RESET " / " ESC_BOLD
- "v%s" ESC_RESET " ] ------------------------------\n",
- PROG_VERSION);
- display_put(" Iterations : " ESC_BOLD "%" _HF_MONETARY_MOD "zu" ESC_RESET, curr_exec_cnt);
+ display_put("------------------------[" ESC_BOLD "%31s " ESC_RESET "]----------------------\n",
+ timeStr);
+ display_put(" Iterations : " ESC_BOLD "%" _HF_NONMON_SEP "zu" ESC_RESET, curr_exec_cnt);
display_printKMG(curr_exec_cnt);
- if (hfuzz->mutationsMax) {
- display_put(" (out of: " ESC_BOLD "%" _HF_MONETARY_MOD "zu" ESC_RESET " [" ESC_BOLD
- "%.2f" ESC_RESET "%%])",
- hfuzz->mutationsMax, exeProgress);
+ if (hfuzz->mutate.mutationsMax) {
+ display_put(" (out of: " ESC_BOLD "%" _HF_NONMON_SEP "zu" ESC_RESET " [%d%%])",
+ hfuzz->mutate.mutationsMax, exeProgress);
}
- switch (ATOMIC_GET(hfuzz->state)) {
+ switch (ATOMIC_GET(hfuzz->feedback.state)) {
case _HF_STATE_STATIC:
- display_put("\n Phase : " ESC_BOLD "Main" ESC_RESET);
+ display_put("\n Mode : " ESC_BOLD "Static" ESC_RESET "\n");
break;
- case _HF_STATE_DYNAMIC_PRE:
- display_put("\n Phase : " ESC_BOLD "Dynamic Dry Run (1/2)" ESC_RESET);
+ case _HF_STATE_DYNAMIC_DRY_RUN:
+ display_put("\n Mode [1/2] : " ESC_BOLD "Feedback Driven Dry Run" ESC_RESET "\n");
break;
case _HF_STATE_DYNAMIC_MAIN:
- display_put("\n Phase : " ESC_BOLD "Dynamic Main (2/2)" ESC_RESET);
+ display_put("\n Mode [2/2] : " ESC_BOLD "Feedback Driven Mode" ESC_RESET "\n");
break;
default:
- display_put("\n Phase : " ESC_BOLD "Unknown" ESC_RESET);
+ display_put("\n Mode : " ESC_BOLD "Unknown" ESC_RESET "\n");
break;
}
-
- display_put("\n Run Time : " ESC_BOLD "%s" ESC_RESET, time_elapsed_str);
- if (hfuzz->timing.runEndTime > 0) {
- time_t time_left = hfuzz->timing.runEndTime - time(NULL);
- if (time_left < 0) {
- time_left = 0;
- }
- if (time_left > 3600) {
- char end_time_str[512];
- util_getLocalTime(
- "%F %H:%M:%S", end_time_str, sizeof(end_time_str), hfuzz->timing.runEndTime);
- display_put(", end time: " ESC_BOLD "%s" ESC_RESET, end_time_str);
- } else {
- display_put(", left: " ESC_BOLD "%d" ESC_RESET " sec.", time_left);
- }
- }
- display_put("\n Input Dir : [% " _HF_MONETARY_MOD "zu] '" ESC_BOLD "%s" ESC_RESET "'\n",
- ATOMIC_GET(hfuzz->io.fileCnt), hfuzz->io.inputDir);
-
- if (hfuzz->linux.pid > 0) {
- display_put(" Remote cmd : [" ESC_BOLD "%d" ESC_RESET "] '" ESC_BOLD "%s" ESC_RESET "'\n",
- hfuzz->linux.pid, hfuzz->linux.pidCmd);
- } else {
- display_put(" Fuzzed Cmd : '" ESC_BOLD "%s" ESC_RESET "'\n", hfuzz->cmdline_txt);
- }
+ display_put(" Target : " ESC_BOLD "%s" ESC_RESET "\n", hfuzz->display.cmdline_txt);
static long num_cpu = 0;
if (num_cpu == 0) {
num_cpu = sysconf(_SC_NPROCESSORS_ONLN);
}
+ if (num_cpu <= 0) {
+ num_cpu = 1;
+ }
unsigned cpuUse = getCpuUse(num_cpu);
display_put(" Threads : " ESC_BOLD "%zu" ESC_RESET ", CPUs: " ESC_BOLD "%ld" ESC_RESET
- ", CPU%: " ESC_BOLD "%u" ESC_RESET "%% (" ESC_BOLD "%u" ESC_RESET "%%/CPU)\n",
+ ", CPU%%: " ESC_BOLD "%u" ESC_RESET "%% [" ESC_BOLD "%lu" ESC_RESET "%%/CPU]\n",
hfuzz->threads.threadsMax, num_cpu, cpuUse, cpuUse / num_cpu);
- display_put(" Speed : " ESC_BOLD "% " _HF_MONETARY_MOD "zu" ESC_RESET
- "/sec"
- " (avg: " ESC_BOLD "%" _HF_MONETARY_MOD "zu" ESC_RESET ")\n",
- exec_per_sec, elapsed_second ? (curr_exec_cnt / elapsed_second) : 0);
+ size_t tot_exec_per_sec = elapsed_sec ? (curr_exec_cnt / elapsed_sec) : 0;
+ display_put(" Speed : " ESC_BOLD "%" _HF_NONMON_SEP "zu" ESC_RESET "/sec [avg: " ESC_BOLD
+ "%" _HF_NONMON_SEP "zu" ESC_RESET "]\n",
+ exec_per_millis, tot_exec_per_sec);
uint64_t crashesCnt = ATOMIC_GET(hfuzz->cnts.crashesCnt);
/* colored the crash count as red when exist crash */
- display_put(" Crashes : " ESC_BOLD
- "%s"
- "%zu" ESC_RESET " (unique: %s" ESC_BOLD "%zu" ESC_RESET ", blacklist: " ESC_BOLD
- "%zu" ESC_RESET ", verified: " ESC_BOLD "%zu" ESC_RESET ")\n",
+ display_put(" Crashes : " ESC_BOLD "%s"
+ "%zu" ESC_RESET " [unique: %s" ESC_BOLD "%zu" ESC_RESET ", blacklist: " ESC_BOLD
+ "%zu" ESC_RESET ", verified: " ESC_BOLD "%zu" ESC_RESET "]\n",
crashesCnt > 0 ? ESC_RED : "", hfuzz->cnts.crashesCnt, crashesCnt > 0 ? ESC_RED : "",
ATOMIC_GET(hfuzz->cnts.uniqueCrashesCnt), ATOMIC_GET(hfuzz->cnts.blCrashesCnt),
ATOMIC_GET(hfuzz->cnts.verifiedCrashesCnt));
- display_put(" Timeouts : " ESC_BOLD "%" _HF_MONETARY_MOD "zu" ESC_RESET
- " [%" _HF_MONETARY_MOD "zu sec.]\n",
- ATOMIC_GET(hfuzz->cnts.timeoutedCnt), hfuzz->timing.tmOut);
+ display_put(" Timeouts : " ESC_BOLD "%" _HF_NONMON_SEP "zu" ESC_RESET " [%lu sec]\n",
+ ATOMIC_GET(hfuzz->cnts.timeoutedCnt), (unsigned long)hfuzz->timing.tmOut);
/* Feedback data sources. Common headers. */
- display_put(" Corpus Size : " ESC_BOLD "%" _HF_MONETARY_MOD "zu" ESC_RESET
- ", max file size: " ESC_BOLD "%" _HF_MONETARY_MOD "zu" ESC_RESET "\n",
- hfuzz->dynfileqCnt, hfuzz->maxFileSz);
+ display_put(" Corpus Size : " ESC_BOLD "%" _HF_NONMON_SEP "zu" ESC_RESET ", max: " ESC_BOLD
+ "%" _HF_NONMON_SEP "zu" ESC_RESET " bytes, init: " ESC_BOLD "%" _HF_NONMON_SEP
+ "zu" ESC_RESET " files\n",
+ hfuzz->io.dynfileqCnt, hfuzz->mutate.maxFileSz, ATOMIC_GET(hfuzz->io.fileCnt));
+ display_put(" Cov Update : " ESC_BOLD "%s" ESC_RESET " ago\n" ESC_RESET, lastCovStr);
display_put(" Coverage :");
/* HW perf specific counters */
- if (hfuzz->dynFileMethod & _HF_DYNFILE_INSTR_COUNT) {
- display_put(" hwi: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
+ if (hfuzz->feedback.dynFileMethod == 0) {
+ display_put(" [none]");
+ }
+ if (hfuzz->feedback.dynFileMethod & _HF_DYNFILE_INSTR_COUNT) {
+ display_put(" hwi: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET,
ATOMIC_GET(hfuzz->linux.hwCnts.cpuInstrCnt));
}
- if (hfuzz->dynFileMethod & _HF_DYNFILE_BRANCH_COUNT) {
- display_put(" hwb: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
+ if (hfuzz->feedback.dynFileMethod & _HF_DYNFILE_BRANCH_COUNT) {
+ display_put(" hwb: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET,
ATOMIC_GET(hfuzz->linux.hwCnts.cpuBranchCnt));
}
- if (hfuzz->dynFileMethod & _HF_DYNFILE_BTS_EDGE) {
- display_put(" bts: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
+ if (hfuzz->feedback.dynFileMethod & _HF_DYNFILE_BTS_EDGE) {
+ display_put(" bts: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET,
ATOMIC_GET(hfuzz->linux.hwCnts.bbCnt));
}
- if (hfuzz->dynFileMethod & _HF_DYNFILE_IPT_BLOCK) {
- display_put(" ipt: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
+ if (hfuzz->feedback.dynFileMethod & _HF_DYNFILE_IPT_BLOCK) {
+ display_put(" ipt: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET,
ATOMIC_GET(hfuzz->linux.hwCnts.bbCnt));
}
- if (hfuzz->dynFileMethod & _HF_DYNFILE_SOFT) {
+ if (hfuzz->feedback.dynFileMethod & _HF_DYNFILE_SOFT) {
uint64_t softCntPc = ATOMIC_GET(hfuzz->linux.hwCnts.softCntPc);
uint64_t softCntEdge = ATOMIC_GET(hfuzz->linux.hwCnts.softCntEdge);
uint64_t softCntCmp = ATOMIC_GET(hfuzz->linux.hwCnts.softCntCmp);
- display_put(" edge: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET, softCntEdge);
- display_put(" pc: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET, softCntPc);
- display_put(" cmp: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET, softCntCmp);
+ display_put(" edge: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET, softCntEdge);
+ display_put(" pc: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET, softCntPc);
+ display_put(" cmp: " ESC_BOLD "%" _HF_NONMON_SEP PRIu64 ESC_RESET, softCntCmp);
}
- /* Sanitizer coverage specific counters */
- if (hfuzz->useSanCov) {
- uint64_t hitBB = ATOMIC_GET(hfuzz->sanCovCnts.hitBBCnt);
- uint64_t totalBB = ATOMIC_GET(hfuzz->sanCovCnts.totalBBCnt);
- float covPer = totalBB ? (((float)hitBB * 100) / totalBB) : 0.0;
- display_put(" #sancov_bb: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET
- " (cov: " ESC_BOLD "%.2f" ESC_RESET "%%)",
- hitBB, covPer);
- display_put(" #dso: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
- ATOMIC_GET(hfuzz->sanCovCnts.iDsoCnt));
- display_put(" #newbb: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
- ATOMIC_GET(hfuzz->sanCovCnts.newBBCnt));
- display_put(" #crashes: " ESC_BOLD "%" _HF_MONETARY_MOD PRIu64 ESC_RESET,
- ATOMIC_GET(hfuzz->sanCovCnts.crashesCnt));
- }
display_put("\n---------------------------------- [ " ESC_BOLD "LOGS" ESC_RESET
- " ] -----------------------------------\n");
- display_put(ESC_SCROLL(14, 999) ESC_NAV(999, 1));
+ " ] ------------------/ " ESC_BOLD "%s %s " ESC_RESET "/-",
+ PROG_NAME, PROG_VERSION);
+ display_put(ESC_SCROLL_REGION(13, ) ESC_NAV_HORIZ(1) ESC_NAV_DOWN(500));
+}
+
+void display_createTargetStr(honggfuzz_t* hfuzz) {
+ if (!hfuzz->exe.cmdline[0]) {
+ LOG_W("Your fuzzed binary is not specified");
+ snprintf(hfuzz->display.cmdline_txt, sizeof(hfuzz->display.cmdline_txt), "[EMPTY]");
+ return;
+ }
+
+ static char tmpstr[1024 * 128] = {0};
+ snprintf(tmpstr, sizeof(tmpstr), "%s", hfuzz->exe.cmdline[0]);
+ for (int i = 1; i < hfuzz->exe.argc; i++) {
+ util_ssnprintf(tmpstr, sizeof(tmpstr), " %s", hfuzz->exe.cmdline[i]);
+ }
+
+ size_t len = strlen(tmpstr);
+ if (len <= (sizeof(hfuzz->display.cmdline_txt) - 1)) {
+ snprintf(hfuzz->display.cmdline_txt, sizeof(hfuzz->display.cmdline_txt), "%s", tmpstr);
+ return;
+ }
+
+ snprintf(hfuzz->display.cmdline_txt, sizeof(hfuzz->display.cmdline_txt), "%.32s.....%s", tmpstr,
+ &tmpstr[len - 27]);
}
-extern void display_display(honggfuzz_t* hfuzz) {
+void display_display(honggfuzz_t* hfuzz) {
if (logIsTTY() == false) {
return;
}
+ MX_SCOPED_LOCK(logMutexGet());
display_displayLocked(hfuzz);
}
-extern void display_fini(void) { display_put(ESC_SCROLL_ENABLE ESC_NAV(999, 1)); }
+void display_fini(void) {
+ display_put(ESC_SCROLL_RESET ESC_NAV_DOWN(500));
+}
-extern void display_init(void) {
+void display_init(void) {
atexit(display_fini);
- display_put(ESC_NAV(999, 1));
+ display_put(ESC_CLEAR_ALL);
+ display_put(ESC_NAV_DOWN(500));
}
diff --git a/display.h b/display.h
index f57999edd7c697fe64da3c3183e57775ec42fd87..dc61422c55f19a03c20998fb7ce1d24334909a6e 100644
--- a/display.h
+++ b/display.h
@@ -5,7 +5,7 @@
*
* Author: Robert Swiecki
*
- * Copyright 2010-2015 by Google Inc. All Rights Reserved.
+ * Copyright 2010-2018 by Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
@@ -28,5 +28,6 @@
extern void display_display(honggfuzz_t* hfuzz);
extern void display_init(void);
+extern void display_createTargetStr(honggfuzz_t* hfuzz);
#endif
diff --git a/docs/AttachingToPid.md b/docs/AttachingToPid.md
deleted file mode 100644
index 484d67abd772a7be6da8991605e9d9a0a1ccfa13..0000000000000000000000000000000000000000
--- a/docs/AttachingToPid.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Introduction #
-
-This page described how to use honggfuzz in batch mode. The simplest example would be Apache Web Server, which cannot be restarted every time we want to send new input (for performance reasons).
-
-_Note: This currently works with Linux OS only_
-
-# What do we need? #
-
-We need to choose what we actually want to fuzz. In this example it'd be HTTP header parser of Apache WS. We need to create a fuzzing tool which will create those headers and then we'll use netcat (_/bin/nc_) to send it to Apache. I had created my own tool (_headfuzz_), it will create output which looks like:
-
-```
-GET (Orig-Uri) HTTP/1.0
-private: expires=application/x-zip-compressed
-Proxy-Authorization: HTTP/144444444444444444444444444.2
-Date: "application/x-gzip"
-
-ABC
-```
-
-In order to attach to a given PID we'll use the **-p** flag. Note that honggfuzz supports attaching to threads as well; in other words, it will attach to every thread in the same thread group (_ls /proc/pid/task_).
-
-# Start Apache WS #
-
-We need to run in debug mode, so it doesn't spawn child processes (-X flag)
-
-```
-# APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data apache2 -k start -X
-```
-
-# Run honggfuzz #
-
-We'll use _-s_ flag to send contents of the fuzz to the standard input of _/bin/nc_
-
-```
-# ./honggfuzz -c ./headfuzz -s -p "`pidof apache2`" -- /bin/nc -q2 -w2 127.0.0.1 80
-honggfuzz version 0.3 Robert Swiecki , Copyright 2010 by Google Inc. All Rights Reserved.
-[INFO] External PID specified, concurrency disabled
-[INFO] debugLevel: 3, inputFile '(null)', nullifyStdio: 0, fuzzStdin: 1, saveUnique: 0, flipRate: 0.001000, flipMode: 'B', externalCommand: './headfuzz', tmOut: 3, threadsMax: 1, fileExtn 'fuzz', ignoreAddr: (nil), memoryLimit: 0 (MiB), fuzzExe: '/bin/nc', fuzzedPid: 9378
-[INFO] No input file corpus specified, the external command './headfuzz' is responsible for creating the fuzz files
-[INFO] Successfully attached to pid/tid: 9378
-[INFO] Launched new process, pid: 9983, (1/1)
-....
-```
-
-If Apache crashes we will see:
-
-```
-[INFO] Ok, that's interesting, saved '.honggfuzz.10014.1310049998.834508.645006950.fuzz' as 'SIGSEGV.PC.0x7f45942f1c20.CODE.0.ADDR.0x288d.INSTR.cmp_rax,_0xfffff001.2011-07-07.16.46.38.9378.fuzz'
-[WARNING] Monitored process PID: 9378 finished
-```
-
-And we'll find the following file in the current directory
-
-```
-SIGSEGV.PC.0x7f45942f1c20.CODE.0.ADDR.0x288d.INSTR.cmp_rax,_0xfffff001.2011-07-07.16.46.38.9378.fuzz
-```
-
-Happy fuzzing!
diff --git a/docs/FeedbackDrivenFuzzing.md b/docs/FeedbackDrivenFuzzing.md
index f30fed686dd048af830ea45ffdb79db261fa704b..28298a412bbe2429690efb7a1e6d90f4680970c2 100644
--- a/docs/FeedbackDrivenFuzzing.md
+++ b/docs/FeedbackDrivenFuzzing.md
@@ -44,30 +44,6 @@ There are 2 phases of feedback-driven the fuzzing:
* Honggfuzz goes through each file in the initial corpus directory (-f). It adds files which hit new code coverage to the dynamic input corpus (as well as saving them on the disk, using *COVERAGE_DATA.PID.pid.RND.time.rnd* pattern
* Honggfuzz choses randomly files from the dynamic input corpus (in-memory), mutates them, and runs a new fuzzing round (round in persistent mode, exec in non-persistent mode). If the newly created file induces new code path (extends code coverage), it gets added to the dynamic input corpus
-# ASAN Code coverage (-C) #
-In order to make this mode work, one needs to compile the fuzzed tool (_xmllint_ here) with _-fsanitize=address -fsanitize-coverage=bb_
-
-```
-$ [honggfuzz_dir]/honggfuzz -C -f IN.corpus/ -- ./xmllint --format --nonet ___FILE___
-============================== STAT ==============================
-Iterations: 1419
-Start time: 2016-03-15 16:43:57 (16 seconds elapsed)
-Input file/dir: 'IN/'
-Fuzzed cmd: './xmllint --format --nonet ___FILE___'
-Fuzzing threads: 3
-Execs per second: 41 (avg: 88)
-Crashes: 0 (unique: 0, blacklist: 0, verified: 0)
-Timeouts: 0
-Number of dynamic files: 251
-Coverage (max):
- - total hit #bb: 8634 (coverage 11%)
- - total #dso: 1 (instrumented only)
- - discovered #bb: 1 (new from input seed)
- - crashes: 0
-============================== LOGS ==============================
-[2016-03-15T16:49:00+0100][I][2094] fuzz_sanCovFeedback():463 SanCov Update: file size (Cur): 2141, newBBs:9, counters (Cur,New): 8569/1,1666/1
-```
-
# Compile-time instrumentation with clang/gcc (default mode) #
Here you can use the following:
diff --git a/docs/USAGE.md b/docs/USAGE.md
index 3c6d354a8d7e0708a85cdf6f91fa9e47e1d348df..71c65ac1c44f14f2c083692d2e48a7b37fe47c4a 100644
--- a/docs/USAGE.md
+++ b/docs/USAGE.md
@@ -13,12 +13,11 @@ Honggfuzz is a security oriented, feedback-driven, evolutionary, easy-to-use fuz
* It's blazingly fast (specifically in the [persistent fuzzing mode](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md)). A simple _LLVMFuzzerTestOneInput_ function can be tested with __up to 1
mo iterations per second__ on a relatively modern CPU (e.g. i7-6600K)
* Has a nice track record of uncovered security bugs: e.g. the __only__ (to the date) __vulnerability in OpenSSL with the [critical](https://www.openssl.org/news/secadv/20160926.txt) score mark__ was discovered by honggfuzz
- * Uses low-level interfaces to monitor processes (e.g. _ptrace_ under Linux). As opposed to other fuzzers, it __will discover and report hidden signals__ (caught and potentially hidden by signal handlers)
+ * Uses low-level interfaces to monitor processes (e.g. _ptrace_ under Linux and NetBSD). As opposed to other fuzzers, it __will discover and report hidden signals__ (caught and potentially hidden by signal handlers)
* Easy-to-use, feed it a simple input corpus (__can even consist of a single, 1-byte file__) and it will work its way up expanding it utilizing feedback-based coverage metrics
* Supports several (more than any other coverage-based feedback-driven fuzzer) hardware-based (CPU: branch/instruction counting, __Intel BTS__, __Intel PT__) and software-based [feedback-driven fuzzing](https://github.com/google/honggfuzz/blob/master/docs/FeedbackDrivenFuzzing.md) methods known from other fuzzers (libfuzzer, afl)
- * Works (at least) under GNU/Linux, FreeBSD, Mac OS X, Windows/CygWin and [Android](https://github.com/google/honggfuzz/blob/master/docs/Android.md)
+ * Works (at least) under GNU/Linux, FreeBSD, NetBSD, Mac OS X, Windows/CygWin and [Android](https://github.com/google/honggfuzz/blob/master/docs/Android.md)
* Supports __persistent fuzzing mode__ (long-lived process calling a fuzzed API repeatedly) with libhfuzz/libhfuzz.a. More on that can be found [here](https://github.com/google/honggfuzz/blob/master/docs/PersistentFuzzing.md)
- * [Can fuzz remote/standalone long-lasting processes](https://github.com/google/honggfuzz/blob/master/docs/AttachingToPid.md) (e.g. network servers like __Apache's httpd__ and __ISC's bind__)
* It comes with the __[examples](https://github.com/google/honggfuzz/tree/master/examples) directory__, consisting of real world fuzz setups for widely-used software (e.g. Apache and OpenSSL)
# REQUIREMENTS #
@@ -39,6 +38,7 @@ It should work under the following operating systems:
|:-------|:-----------|:----------|
| **GNU/Linux** | Works | ptrace() API (x86, x86-64 disassembly support)|
| **FreeBSD** | Works | POSIX signal interface |
+| **NetBSD** | Works | ptrace() API (x86, x86-64 disassembly support)|
| **Mac OS X** | Works | POSIX signal interface/Mac OS X crash reports (x86-64/x86 disassembly support) |
| **Android** | Works | ptrace() API (x86, x86-64 disassembly support) |
| **MS Windows** | Works | POSIX signal interface via CygWin |
@@ -61,8 +61,6 @@ Options:
*DEFAULT-MODE-BY-DEFAULT* Enable compile-time instrumentation (use hfuzz_cc/hfuzz-clang to compile code)
--noinst|-x
Static mode (dry-mode), disable any instrumentation (hw/sw)
- --sancov|-C
- Enable sanitizer coverage feedback
--keep_output|-Q
Don't close children's stdin, stdout, stderr; can be noisy
--timeout|-t VALUE
@@ -155,6 +153,16 @@ Options:
Use Linux PID namespace isolation
--linux_ns_ipc
Use Linux IPC namespace isolation
+ --netbsd_symbols_bl VALUE
+ Symbols blacklist filter file (one entry per line)
+ --netbsd_symbols_wl VALUE
+ Symbols whitelist filter file (one entry per line)
+ --netbsd_pid|-p VALUE
+ Attach to a pid (and its thread group)
+ --netbsd_file_pid VALUE
+ Attach to pid (and its thread group) read from file
+ --netbsd_addr_low_limit VALUE
+ Address limit (from si.si_addr) below which crashes are not reported, (default: '0')
Examples:
Run the binary over a mutated file chosen from the directory. Disable fuzzing feedback (dry/static mode)
@@ -163,8 +171,6 @@ Examples:
honggfuzz -f input_dir -x -s -- /usr/bin/djpeg
Use compile-time instrumentation (libhfuzz/instrument.c):
honggfuzz -f input_dir -- /usr/bin/djpeg ___FILE___
- Use SANCOV instrumentation:
- honggfuzz -f input_dir -C -- /usr/bin/djpeg ___FILE___
Use persistent mode (libhfuzz/persistent.c) w/o instrumentation:
honggfuzz -f input_dir -P -x -- /usr/bin/djpeg_persistent_mode
Use persistent mode (libhfuzz/persistent.c) and compile-time instrumentation:
@@ -183,7 +189,7 @@ Examples:
| **Mode** | **Output file** |
|:---------|:----------------|
-| Linux | **SIGSEGV.PC.4ba1ae.STACK.13599d485.CODE.1.ADDR.0x10.INSTR.mov____0x10(%rbx),%rax.fuzz** |
+| Linux,NetBSD | **SIGSEGV.PC.4ba1ae.STACK.13599d485.CODE.1.ADDR.0x10.INSTR.mov____0x10(%rbx),%rax.fuzz** |
| POSIX signal interface | **SIGSEGV.22758.2010-07-01.17.24.41.tif** |
## Description ##
diff --git a/examples/apache b/examples/apache
new file mode 120000
index 0000000000000000000000000000000000000000..1697e84faef7beedfdbbaca02c1649d5e6ab0533
--- /dev/null
+++ b/examples/apache
@@ -0,0 +1 @@
+apache-httpd/
\ No newline at end of file
diff --git a/examples/apache-httpd/README.md b/examples/apache-httpd/README.md
index a690160914219f35ba4604182551257469ddcbe9..2710736eff8893b8ccd47adc561bfa1fe87fe8f4 100644
--- a/examples/apache-httpd/README.md
+++ b/examples/apache-httpd/README.md
@@ -2,44 +2,49 @@
**Requirements**
- * honggfuzz (1.0 or from the master branch)
+ * honggfuzz
* clang-4.0, or newer (5.0 works as well)
- * apache (e.g.: 2.4.25 or the master branch from git)
+ * apache (e.g. 2.4.29 or from githubs' master branch)
+ * apr, apr-utils, nghttp2
**Preparation**
-Note: The examples provided below use hardcoded paths (here to _/home/swiecki/_) and
+Note: The examples provided below use hardcoded paths (here to _/home/$USER/_) and
version strings of the libraries (e.g. apr-_1.5.2_). These will have to be modified, so they reflect your actual build environment.
1. Compile honggfuzz
2. Download and unpack the following packages: apr, apr-util, ngttp2, and Apache's httpd
3. Patch Apache's httpd
- ```
+
+```shell
$ cd httpd-master
$ patch -p1 < httpd-master.honggfuzz.patch
- ```
+```
4. Configure, compile and install Apache
- * edit compile_and_install.sh to contain valid versions/paths
- ```
-$ ./compile_and_install.sh
- ```
+ * edit ```compile_and_install.asan.sh``` so it contains valid versions/paths
+
+```shell
+$ ./compile_and_install.asan.sh
+```
-5. Copy the custom configuration files to ```/home/swiecki/fuzz/apache/apache2/conf/``` (i.e. to your apache dist directory)
+5. Copy custom configuration files (```httpd.conf.h1``` and ```httpd.conf.h2```) to ```/home/$USER/fuzz/apache/apache2/conf/``` (i.e. to your apache dist directory)
```
-$ cp httpd.conf.h1 httpd.conf.h2 /home/swiecki/fuzz/apache/apache2/conf/
+$ cp httpd.conf.h1 httpd.conf.h2 /home/$USER/fuzz/apache/apache2/conf/
```
+6. Edit ```httpd.conf.h1``` and ```httpd.conf.h2```, so they contain valid configuration paths
+
**Fuzzing**
* HTTP/1
```
-$ honggfuzz/honggfuzz -P -f corpus_http1 -w ./httpd.wordlist -- ./apache2/bin/httpd -DFOREGROUND -f /home/swiecki/fuzz/apache/apache2/conf/httpd.conf.h1
+$ honggfuzz/honggfuzz -f corpus_http1 -w ./httpd.wordlist -- ./apache2/bin/httpd -DFOREGROUND -f /home/$USER/fuzz/apache/apache2/conf/httpd.conf.h1
```
* HTTP/2
```
-$ honggfuzz/honggfuzz -P -f corpus_http2 -w ./httpd.wordlist -- ./apache2/bin/httpd -DFOREGROUND -f /home/swiecki/fuzz/apache/apache2/conf/httpd.conf.h2
+$ honggfuzz/honggfuzz -f corpus_http2 -w ./httpd.wordlist -- ./apache2/bin/httpd -DFOREGROUND -f /home/$USER/fuzz/apache/apache2/conf/httpd.conf.h2
```
diff --git a/examples/apache-httpd/corpus_http1/005cedc70f1d44786a12b73e098f4497.000000cc.honggfuzz.cov b/examples/apache-httpd/corpus_http1/005cedc70f1d44786a12b73e098f4497.000000cc.honggfuzz.cov
deleted file mode 100644
index 9bba25a767dfd27eeffe625ba3682fe73909ddd8..0000000000000000000000000000000000000000
--- a/examples/apache-httpd/corpus_http1/005cedc70f1d44786a12b73e098f4497.000000cc.honggfuzz.cov
+++ /dev/null
@@ -1,3 +0,0 @@
-GET /dir/?P=2;91
-CUފ!,@eءs'{l8SDHP&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Content-MD5:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&O&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrhtml HTTP/1.1
-Useq-Agent: Wgrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr(>&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&UPDATE&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&j&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Content-MD5:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&O&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Content-MD5:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&O&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.&&&&&&&&&&&&&&&&&&&&%&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrhtml HTTP/1.1
-Useq-Agent: Wget/.15 Vlimux.gou)
-Acbvpt: */)
-Host: 127.0.0.1:8080
-Content-Length:p-A,ire
-
- s'8 'O :Ecvo՟`p3qGԾ&5eۺ#М$dKDrKԷU\e~[:N^HֲQȇ:h1G=A(Z>D<7~aqd@`[nⳐSL˸-B76By47P;]V~f;8OVX[.Z,ێ D-'M=t0jr.WL)?O`B\Z^4R*ܑKJM 4|yP)] O&@a3Xb+aSHHޠ9GZs]
!~E(-t4kNH&Prc]j&=),R뿑,b